0

Compiling Java source code from within java is a task that is aided by the Java Compiler Tools within the javafx.tools package. However there is something I can't seem to find any information about.

The question I ask is if it's possible to compile the java files against the JVM being used to compile it. I am writing code that runs on software that makes use of several jar libraries, some of them quite large, and I intend to dynamically compile individual java files and load the resulting class files to operate almost like a scripting language. In order for the compiled java files to access classes and variables within the software, it needs to have all the same libraries added to its classpath upon building, or I'll face compilation errors.

I've searched around for information on whether this is impossible or not, and can't find it, I get completely irrelevant results.

If it is impossible I could link all needed libraries (over 30 of them), I would just prefer not to. If it is impossible to compile against the current environment, then what would you consider the easiest way to dynamically get a list of all libraries being loaded in the JVM are?

Edit: In response to Jim, I understand that java files are compiled into class files and that class files are the ones loaded. I understand that libraries need to be accessible to the compiler, etc. What I'm stating is the fact that I have over 30 libraries totaling over 380 MB, and I have a couple hundred individual java source files in a folder that extend a class defined within the main program to be used as a module, If I have to link all several hundred of them with 380 MB of files for compiling, that's a lot of time taken. I could compile them all together to fix most of the problem, but the main issue is that the list of files to run are added in the -classpath argument of the command line, and this can change at any time, so I can not hard code this. That's why the second part of the question exists, how would I get the classpath being used to run the current program so that I can then pass it into the compiler.

D3_JMultiply
  • 1,022
  • 2
  • 12
  • 22
  • The statement _"compile the java files against the JVM being used "_ doesn't make sense. You compile a java file to produce a class file, and that class file can then be loaded into a JVM. As to external libraries, they must be available to the compiler in order to resolve references, and they must be available to the class loader to link at runtime. Assuming the external libraries are already in the JVM's classpath, you just need to make sure they are also available to the compiler when you invoke it. – Jim Garrison Aug 04 '16 at 22:41
  • I don't think you properly read my question Jim. First off "Compi;e against" is a completely valid statement, you may want to look it up, you'll see it's a quite commonly used phrase meaning to link a resource to the compilation process. To "compile against a library"" means the exact same thing in this case as "add a library to the compiler classpath". I'm asking if it's possible to instead of having to link 30+ libraries each for over 300 individual java files, if it's possible to use the already loaded and running environment. – D3_JMultiply Aug 04 '16 at 22:48
  • "makes use of several jar libraries, some of them quite large" - you can create small jars containing only the api to those large libs and compile against those. To get list of "loaded libraries" you can call `System. getProperty("java.class.path")` - maybe it's sufficient in your case. – mabn Aug 04 '16 at 23:40
  • That will work just fine, wasn't aware of that specific property, strange that that didn't show up when I searched "how to get the java classpath". – D3_JMultiply Aug 05 '16 at 00:30
  • 1
    If you're going to downvote, at least comment why. – D3_JMultiply Aug 05 '16 at 02:46
  • When you use the Compiler API, you specify the ClassLoader you want to use. This ClassLoader then provides all the classes you might need to compile your code. I can't remember the details but I wrote a library for in memory compilation of Java code about 5 years ago. https://github.com/OpenHFT/Java-Runtime-Compiler – Peter Lawrey Aug 05 '16 at 09:52
  • @PeterLawrey I just tried your code there, and I get errors. I made a simple base class which has a method that returns a String. I made my Test.java file extend that class and return a different string. When it tries to compile it just says it can't find the base class I made, meaning no, it's not finding the classes needed to compile. I made sure I even passed in the base class's class loader, still no effect. Is there something specific I need to do to make that work, you made it sound like it out of the box already did exactly this. – D3_JMultiply Aug 05 '16 at 22:05
  • @PeterLawrey figured it out, works like a charm. If you wish to make an answer I can accept it, although i will say it's probably best to remove the nullable and notnull stuff, because it makes your code error on many IDEs that aren't IntelliJ – D3_JMultiply Aug 06 '16 at 06:27

1 Answers1

0

When you use the Compiler API, you specify the ClassLoader you want to use. This ClassLoader then provides all the classes you might need to compile your code. I can't remember the details but I wrote a library for in memory compilation of Java code about 5 years ago. https://github.com/OpenHFT/Java-Runtime-Compiler

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130