Defining a class while a Java application is running

≯℡__Kan透↙ 提交于 2019-12-17 23:37:30

问题


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.


回答1:


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.




回答2:


You can dynamically generate classes using ASM




回答3:


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.




回答4:


Sure it is possible. See for example this article.




回答5:


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().




回答6:


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.




回答7:


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).




回答8:


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.




回答9:


If you want Java and metaprogramming, use Groovy.




回答10:


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).




回答11:


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.



来源:https://stackoverflow.com/questions/781805/defining-a-class-while-a-java-application-is-running

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!