Defining a class while a Java application is running
Asked Answered
M

11

17

In Java, is it possible to create a class definition on the fly while an application is running, and then create an object of that class?

For example, a running application would read in a text file that contains a list of class members to include in the new class. The application would then define a class definition based on the list of members, and then insantiate it.

Monro answered 23/4, 2009 at 13:52 Comment(6)
This is how SkyNet gets started.Iodide
If SkyNet were written in Java, it would require far too much memory to ever be a threat.Pocketful
SkyNet would just build itself a larger cluster to run on. The fact that it's written in Java would make sense since SkyNet and Java both will end up being the end of humanity.Iodide
I always figured SkyNet to be written in Perl. Then all it'd have to do to evolve is output random punctuation and pipe it to the Perl interpreter.Pocketful
Just out of curiosity, what are you trying to solve using this method? Or is the question academic?Refrangible
@nemo: Mostly out of curiosity. I am writing a Java program that will output a Java class definition, I probably won't need to create an object of the class on the fly, but thought it would be cool to do so...Monro
G
11

Yes its possible to do so in theory your class file is byte code which is at the end a byte array! you can then use the method defineClass(String, byte[], int, int) to get a Class instance that can be used to instantiate objects via reflection.

In practice you can use something like CGLib or javaassist.

You can also use the long way of generating the java code in a file, invoking the compiler, then loading the file.

Gena answered 23/4, 2009 at 13:56 Comment(0)
D
2

You can dynamically generate classes using ASM

Dubai answered 23/4, 2009 at 13:59 Comment(0)
E
1

You can do this by writing the code for your new class out to a file, then invoking the Java compiler on that file and using a classloader to dynamically load that class into your running application. Apache Tomcat does this for its JSP pages; it takes the code, makes some changes to it, wraps it in a try/catch block in the middle of a class, which it then writes to the filesystem, compiles it, and uses a classloader to get and sue it to serve requests.

En answered 23/4, 2009 at 13:54 Comment(0)
M
1

Sure it is possible. See for example this article.

Memoirs answered 23/4, 2009 at 13:57 Comment(0)
T
1

ASM is the lowest level bytecode library for Java, I suppose. That makes it very hard but also very powerful. I recommend reading ASM's documentation (PDF) to really understand how bytecode generation in Java works. That documentation also explains how to load the bytecode in the class loader (another hard topic to do right).

After that you may use one of the higher level libraries, if it makes your life easier, and understand what they do. For many cases, such as generating proxies, the CGLIB is useful and simple to use. For more power, many have mentioned Javassist (I haven't used it - CGLIB and ASM have been good for me).

Torchier answered 23/4, 2009 at 14:22 Comment(0)
C
1

Perhaps the simplest solution (in terms of not requiring extra libraries) would be to use the Java compiler API that comes with Java 6. You just just be able to generate the .java, compile and then perform a Class.forName().

Casanova answered 23/4, 2009 at 15:3 Comment(0)
G
0

Perhaps a little overkill, the Apache BCEL (Byte Code Engineering Library) can be used to create class files during runtime.

Although I haven't tried it myself, conceivably, one could then create a class, load it, and instantiate it during runtime.

Guacin answered 23/4, 2009 at 14:0 Comment(0)
F
0

Yes, that is possible.

You can create classes with Javassist at runtime by defining the body of the class and making javassist compile your new class.

Javassist has a custom compiler that creates bytecode based on the definition of your class. It has some particular ways to handle things, but it's very easy and intuitive to use this library.

Javassist is used on JBoss, and I think that is a good reference :)

The same can be achieved with BCEL, however it's much harder (but in this way you have more control over what is being generated).

Foliation answered 23/4, 2009 at 14:0 Comment(0)
T
0

You could probably do something like that with JRuby, or JPython or Groovy if you must.

If you're feeling particularly masochistic you could look at BCEL.

Thacher answered 23/4, 2009 at 14:3 Comment(0)
C
0

If you want Java and metaprogramming, use Groovy.

Coil answered 23/4, 2009 at 14:9 Comment(1)
Hi Stefan, so Groovy can help to compile at runtime a Java class on the fly and instantiate it ? Do you have any pointer about how to do this ?Silverpoint
T
0

There was a recent question here regarding in-memory compilation which should give you some hints on what to do after you've managed to generate the source code.

Twotime answered 23/4, 2009 at 16:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.