23

I don't know if this is even possible. Anyway, here is my problem: I want to create a Class having a database table schema, for example suppose that I have a table like

id - unsigned int 
username - varchar(128)
password - varchar(128)

and let's assume I can query this data from my db. What I want to do is to dynamically create (and, of course, instantiate) a Java class that should look like this:

public class User{
    private unsigned int id;
    private String username;
    private String password;
}

(actually an ActiveRecord for my table)

Can you help me starting this? Tnks

0

8 Answers 8

18

What would you do with a dynamically created and instantiated class that none of your other code knows about?

For a stically typed language like Java, it makes little sense to have such classes. On the other hand, most OR Mappers like Hibernate come with tools that allow you to statically generate classes from a database schema.

Sign up to request clarification or add additional context in comments.

7 Comments

One use case would be generating a class that implements an interface which your static code knows about. I'm researching this topic because we have an application that runs against mixed database schema, so columns may or may not exist.
@Snekse: dynamically implementing interfaces is quite easy, using java.lang.reflect.Proxy
I was just trying to answer the question of what you might do with such a dynamically generated class. We're about to attempt something similar, but I think we're going to investigate Groovy before going down the .reflect.Proxy path or the like.
another case would be to generate a class annotated with something, for instance to use with an ApplicationContext as an additional configuration class
You could do a lot with dynamically generated classes, you code would know about it through inheritance. Arguably you could probably do anything that you could think of through more traditional means, but they would require a lot more future-proofing. I'm thinking in-game scripting / game modding here.
|
18

Technically, you can, via a bytecode manipulation library - CGLIB, javassist, asm, bcel and the likes.

However, this is not the Java "philosophy". Java is statically-typed, so you'd better create the classes before runtime.

Take a look at hibernate / eclipseLink for Java ORM - a way of mapping tables to objects.

Comments

6

I think what you want is the facility provided by java.lang.reflect.Proxy and related classes.

4 Comments

That requires an interface to exist, so quite useless in this scenario.
Well, I agree that that's true, but the question isn't exactly rock-solid.
I think you confused the JDK proxy mechanism with bytecode manipulation libs like asm or cglib
Not necessarily wrong; Think about it. What is the point of having a real method if it does not exist in any interface? How would you ever use it in any way that gets you any benefit of the fact that it's a real statically typed method?
4

This is a good article to start with, but are you sure you need to actually create a new class? Maybe you could just use a Map?

1 Comment

Using CodeModel to narrow to a Class that I haven't created yet was problematic, this article trivially solves my problem, via Javassist: ClassPool.getDefault().makeClass(clazzString).toClass();
1

Like @Bozho states, Java is a statically typed language for which generating classes at runtime can only lead to mayhem.

In our world, it is far more convenient to generate classes at build time, that's to say during compilation. Typycally, using Hibernate reverse engineering, you can build your Java classes from your DB schema at build time, and deploy those classes in your application, which give you authentical Java code to read, with the guarantee that your code will be bound to your DB schema

Comments

1

The Article about the "new" Compiler API and the java doc for JavaCompiler show a way on how to compile java source from String objects. (I don't know if we can compile to output streams and load the class files in memory yet...)

You can load the class files later on with a URLClassLoader and create instances (reclection/invocation API)

Comments

0

You could generate Java source text and use javax.tools package to compile it and a class loader to load it. Googling yields some examples how it can be done, but I never tried anything like that, so I don't know what problems you may encounter. Clearly, Java wasn't designed for such things.

Comments

0

Old question and if it is possible, you should avoid to generate class during runtime, but sometimes you have to do that. So you can use Javassist and here is example...

I created a small example here: http://hrabosch.com/2018/04/08/generate-class-during-runtime-with-javassist/

But here is main point:

public static Class generateClass(String className, String methodName, String methodBody)
  throws CannotCompileException {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass(className);
StringBuffer method = new StringBuffer();
method.append("public void ")
      .append(methodName)
      .append("() {")
      .append(methodBody)
      .append(";}");
cc.addMethod(CtMethod.make(method.toString(), cc));
return cc.toClass();
}

So what I did... Via Javassist I made a class in ClassPool. Also I added a method inside this class and via reflection I invoked it.

Hope it helps.

Just keep on mind whatever you want to use in generated class, there are NOT imports, so you have to use fully-qualified names.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.