3

Is it possible to generate subclasses at runtime or while an application is running? If so, how is this achieved and what precautions should be taken to prevent a rogue object wreaking havoc inside an application?

Edit: Title modified from "Class generation on the fly".

tshepang
  • 12,111
  • 21
  • 91
  • 136
James P.
  • 19,313
  • 27
  • 97
  • 155
  • 1
    *rogue object wreaking havoc* That's a phrase I have never read before.. cool – OscarRyz Apr 08 '10 at 20:09
  • 1
    http://www.javaranch.com/journal/200711/Journal200711.jsp#a4 crating classes at runtime, might help – Justin Gregoire Apr 08 '10 at 20:09
  • Curious at why you might need to do this? There might be a much simpler solution to whatever problem you are trying to solve – matt b Apr 08 '10 at 20:15
  • @matt b: It's for a sort of DMS I'd like to create. Rather than have a fixed set of rules saying how documents are organized, I'd like to allow users to customize these rules according to their needs. This would save having to adapt the application or parameterizing everything. – James P. Apr 08 '10 at 20:29
  • @Oscar Reyes: The phrase was probably inspired by a comicbook I read a while ago :smile:. – James P. Apr 08 '10 at 20:33
  • @James P You could consider adding an scripting language such as Jython or JRuby for those dynamic rules. That's an alternative. – OscarRyz Apr 08 '10 at 20:40
  • Using scripting language could be a possibility. An approach like this has been used on a program called metatrader which makes it possible to create custom indicators. – James P. Apr 13 '10 at 10:32

4 Answers4

3

Take a look at Reflection API.

Create Dynamic class "on the fly"

Read this one too:

Java Reflection: Create an implementing class - Jon Skeet answered it! :)

Community
  • 1
  • 1
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
1

Yes. Have a look at what you can do with the compiler in Javassist.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
1

Yes, it is possible

Take a look at the package "javax.tools"

You could compile and load a class at runtime.

    String rogue = "package abc; "+
                 "public class RogueObjectWreakingHavoc extends SomeImportantClass {"+
                 " { System.exit(-1) }"+
                 "}"
    File sourceFile = new File("RogueObjectWreakingHavoc.java");
    FileWriter fileWriter = new FileWriter(sourceFile);
    fileWriter.write(rogue);
    fileWriter.close();

    List<File> files = new ArrayList<File>();
    files.add(sourceFile);

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,
                                                                          null,
                                                                          null);

    compiler.getTask(null, 
                     fileManager,
                     null,
                     null,
                     null,
                     fileManager.getJavaFileObjectsFromFiles(files))
    .call();
    fileManager.close();

   // load using URLClassLoader...

To avoid it you most consider declare your classes as final if they are not indented to be subclasses, and make copies when needed ( instead of taking arguments just they way they are )

More information ( about how to use Java effectively ) on the book "Effective Java" by Joshua Bloch

OscarRyz
  • 196,001
  • 113
  • 385
  • 569
0

For other developpers seeking to add the possibility of extending their software, another approach for plugin behaviour is the forName() method of Class (used for example by JDBC) and Dynamic Class Loading.

http://mindprod.com/jgloss/classforname.html

James P.
  • 19,313
  • 27
  • 97
  • 155