Compile java file at runtime
up vote
0
down vote
favorite
I'm trying to compile a java file at runtime. If I run my code in Eclipse there is no problem, I can compile the external java file and instantiate the object of that class.
The problem occur when I generate the jar of my application (using the spring boot plugin). If I run my application using java -jar
the runtime compilation task fails with the error: error: package 'com.myLib' does not exist
I've extracted the jar and I can find com.myLib
in BOOT-INF/lib/mylib.jar
I think that it is just a problem of setting the right class path before compile at runtime my external java file
This is my external java file to be compiled at runtime:
package com.mypackage;
import com.myLib.myclass;
public class filter implements MyInterface {
@Override
public void print(myclass obj) {
System.out.println(obj);
}
}
This is the code used to compile at runtime:
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
final StandardJavaFileManager fileManager = compiler.getStandardFileManager(errorListener, Locale.ENGLISH,
Charset.defaultCharset());
StringBuilder sb = new StringBuilder();
for (URL url : ((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURLs()) {
sb.append(url.getPath()).append(File.pathSeparator);
}
final classPath = sb.toString();
final List<String> optionList = new ArrayList<>();
optionList.addAll(Arrays.asList("-classpath", classPath));
optionList.add("-Xlint:unchecked");
optionList.add("-Xlint:none");
optionList.addAll(Arrays.asList("-d", "outputFolder"));
final JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, errorListener, optionList, null,
files);
task.call();
EDIT
I think that the problem is how the jar of my application is created. If I use the 'com.github.johnrengelman.shadow' plugin there is no problem. But if I use spring-boot and I generate the jar using bootJar
task, I have a runtime exception during the execution of my application. If I extract both jars I see that spring-boot put the jars (of the libraries) into the jar of my application, instead 'shadow' put the .class (of the libraries) into the jar of my application.
I've created 2 gradle projects:
- https://github.com/fabry00/test-compile
https://github.com/fabry00/test-compile-boot (with spring boot)
Both run in Eclpise without problem. The first one runs also in command line (./gradlew shadowJar) the second one does not run in command line (./gradlew bootJar
and then run it 'java -jar')
The logic of the project is to read external xmls (filters directory) and create java classes at runtime mixing the content of the xmls and the content of the file skeleton/skeleton.java
Once you run the application, you can see the generated .java and .class files in the compiled folder
java spring spring-boot dynamic-compilation
|
show 2 more comments
up vote
0
down vote
favorite
I'm trying to compile a java file at runtime. If I run my code in Eclipse there is no problem, I can compile the external java file and instantiate the object of that class.
The problem occur when I generate the jar of my application (using the spring boot plugin). If I run my application using java -jar
the runtime compilation task fails with the error: error: package 'com.myLib' does not exist
I've extracted the jar and I can find com.myLib
in BOOT-INF/lib/mylib.jar
I think that it is just a problem of setting the right class path before compile at runtime my external java file
This is my external java file to be compiled at runtime:
package com.mypackage;
import com.myLib.myclass;
public class filter implements MyInterface {
@Override
public void print(myclass obj) {
System.out.println(obj);
}
}
This is the code used to compile at runtime:
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
final StandardJavaFileManager fileManager = compiler.getStandardFileManager(errorListener, Locale.ENGLISH,
Charset.defaultCharset());
StringBuilder sb = new StringBuilder();
for (URL url : ((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURLs()) {
sb.append(url.getPath()).append(File.pathSeparator);
}
final classPath = sb.toString();
final List<String> optionList = new ArrayList<>();
optionList.addAll(Arrays.asList("-classpath", classPath));
optionList.add("-Xlint:unchecked");
optionList.add("-Xlint:none");
optionList.addAll(Arrays.asList("-d", "outputFolder"));
final JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, errorListener, optionList, null,
files);
task.call();
EDIT
I think that the problem is how the jar of my application is created. If I use the 'com.github.johnrengelman.shadow' plugin there is no problem. But if I use spring-boot and I generate the jar using bootJar
task, I have a runtime exception during the execution of my application. If I extract both jars I see that spring-boot put the jars (of the libraries) into the jar of my application, instead 'shadow' put the .class (of the libraries) into the jar of my application.
I've created 2 gradle projects:
- https://github.com/fabry00/test-compile
https://github.com/fabry00/test-compile-boot (with spring boot)
Both run in Eclpise without problem. The first one runs also in command line (./gradlew shadowJar) the second one does not run in command line (./gradlew bootJar
and then run it 'java -jar')
The logic of the project is to read external xmls (filters directory) and create java classes at runtime mixing the content of the xmls and the content of the file skeleton/skeleton.java
Once you run the application, you can see the generated .java and .class files in the compiled folder
java spring spring-boot dynamic-compilation
All what remains for you is loading the class at runtime, check this
– Mohamed EL AYADI
Nov 7 at 10:08
You foundcom.myLib
(btw, please avoid using uppercase letters in package names) in jar, but did you actually put it on the compilation task classpath?
– M. Prokhorov
Nov 7 at 10:23
@MohamedELAYADI which class I have to load at runtime? I have the exception when I execute thetask.call()
at this point the .class of my external java file is not created yet
– Fabry
Nov 7 at 10:26
@M.Prokhorov yes you are right, I just replaced the real name with myLib (in production is all lowercase). It shouldn't already be the the classPath that I retrieve withThread.currentThread().getContextClassLoader()).getURLs()
if not how can I do it?
– Fabry
Nov 7 at 10:28
If it's not in the classpath, you'll have to add it, of course.
– M. Prokhorov
Nov 7 at 10:29
|
show 2 more comments
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm trying to compile a java file at runtime. If I run my code in Eclipse there is no problem, I can compile the external java file and instantiate the object of that class.
The problem occur when I generate the jar of my application (using the spring boot plugin). If I run my application using java -jar
the runtime compilation task fails with the error: error: package 'com.myLib' does not exist
I've extracted the jar and I can find com.myLib
in BOOT-INF/lib/mylib.jar
I think that it is just a problem of setting the right class path before compile at runtime my external java file
This is my external java file to be compiled at runtime:
package com.mypackage;
import com.myLib.myclass;
public class filter implements MyInterface {
@Override
public void print(myclass obj) {
System.out.println(obj);
}
}
This is the code used to compile at runtime:
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
final StandardJavaFileManager fileManager = compiler.getStandardFileManager(errorListener, Locale.ENGLISH,
Charset.defaultCharset());
StringBuilder sb = new StringBuilder();
for (URL url : ((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURLs()) {
sb.append(url.getPath()).append(File.pathSeparator);
}
final classPath = sb.toString();
final List<String> optionList = new ArrayList<>();
optionList.addAll(Arrays.asList("-classpath", classPath));
optionList.add("-Xlint:unchecked");
optionList.add("-Xlint:none");
optionList.addAll(Arrays.asList("-d", "outputFolder"));
final JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, errorListener, optionList, null,
files);
task.call();
EDIT
I think that the problem is how the jar of my application is created. If I use the 'com.github.johnrengelman.shadow' plugin there is no problem. But if I use spring-boot and I generate the jar using bootJar
task, I have a runtime exception during the execution of my application. If I extract both jars I see that spring-boot put the jars (of the libraries) into the jar of my application, instead 'shadow' put the .class (of the libraries) into the jar of my application.
I've created 2 gradle projects:
- https://github.com/fabry00/test-compile
https://github.com/fabry00/test-compile-boot (with spring boot)
Both run in Eclpise without problem. The first one runs also in command line (./gradlew shadowJar) the second one does not run in command line (./gradlew bootJar
and then run it 'java -jar')
The logic of the project is to read external xmls (filters directory) and create java classes at runtime mixing the content of the xmls and the content of the file skeleton/skeleton.java
Once you run the application, you can see the generated .java and .class files in the compiled folder
java spring spring-boot dynamic-compilation
I'm trying to compile a java file at runtime. If I run my code in Eclipse there is no problem, I can compile the external java file and instantiate the object of that class.
The problem occur when I generate the jar of my application (using the spring boot plugin). If I run my application using java -jar
the runtime compilation task fails with the error: error: package 'com.myLib' does not exist
I've extracted the jar and I can find com.myLib
in BOOT-INF/lib/mylib.jar
I think that it is just a problem of setting the right class path before compile at runtime my external java file
This is my external java file to be compiled at runtime:
package com.mypackage;
import com.myLib.myclass;
public class filter implements MyInterface {
@Override
public void print(myclass obj) {
System.out.println(obj);
}
}
This is the code used to compile at runtime:
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
final StandardJavaFileManager fileManager = compiler.getStandardFileManager(errorListener, Locale.ENGLISH,
Charset.defaultCharset());
StringBuilder sb = new StringBuilder();
for (URL url : ((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURLs()) {
sb.append(url.getPath()).append(File.pathSeparator);
}
final classPath = sb.toString();
final List<String> optionList = new ArrayList<>();
optionList.addAll(Arrays.asList("-classpath", classPath));
optionList.add("-Xlint:unchecked");
optionList.add("-Xlint:none");
optionList.addAll(Arrays.asList("-d", "outputFolder"));
final JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, errorListener, optionList, null,
files);
task.call();
EDIT
I think that the problem is how the jar of my application is created. If I use the 'com.github.johnrengelman.shadow' plugin there is no problem. But if I use spring-boot and I generate the jar using bootJar
task, I have a runtime exception during the execution of my application. If I extract both jars I see that spring-boot put the jars (of the libraries) into the jar of my application, instead 'shadow' put the .class (of the libraries) into the jar of my application.
I've created 2 gradle projects:
- https://github.com/fabry00/test-compile
https://github.com/fabry00/test-compile-boot (with spring boot)
Both run in Eclpise without problem. The first one runs also in command line (./gradlew shadowJar) the second one does not run in command line (./gradlew bootJar
and then run it 'java -jar')
The logic of the project is to read external xmls (filters directory) and create java classes at runtime mixing the content of the xmls and the content of the file skeleton/skeleton.java
Once you run the application, you can see the generated .java and .class files in the compiled folder
java spring spring-boot dynamic-compilation
java spring spring-boot dynamic-compilation
edited Nov 7 at 11:42
asked Nov 7 at 10:00
Fabry
188113
188113
All what remains for you is loading the class at runtime, check this
– Mohamed EL AYADI
Nov 7 at 10:08
You foundcom.myLib
(btw, please avoid using uppercase letters in package names) in jar, but did you actually put it on the compilation task classpath?
– M. Prokhorov
Nov 7 at 10:23
@MohamedELAYADI which class I have to load at runtime? I have the exception when I execute thetask.call()
at this point the .class of my external java file is not created yet
– Fabry
Nov 7 at 10:26
@M.Prokhorov yes you are right, I just replaced the real name with myLib (in production is all lowercase). It shouldn't already be the the classPath that I retrieve withThread.currentThread().getContextClassLoader()).getURLs()
if not how can I do it?
– Fabry
Nov 7 at 10:28
If it's not in the classpath, you'll have to add it, of course.
– M. Prokhorov
Nov 7 at 10:29
|
show 2 more comments
All what remains for you is loading the class at runtime, check this
– Mohamed EL AYADI
Nov 7 at 10:08
You foundcom.myLib
(btw, please avoid using uppercase letters in package names) in jar, but did you actually put it on the compilation task classpath?
– M. Prokhorov
Nov 7 at 10:23
@MohamedELAYADI which class I have to load at runtime? I have the exception when I execute thetask.call()
at this point the .class of my external java file is not created yet
– Fabry
Nov 7 at 10:26
@M.Prokhorov yes you are right, I just replaced the real name with myLib (in production is all lowercase). It shouldn't already be the the classPath that I retrieve withThread.currentThread().getContextClassLoader()).getURLs()
if not how can I do it?
– Fabry
Nov 7 at 10:28
If it's not in the classpath, you'll have to add it, of course.
– M. Prokhorov
Nov 7 at 10:29
All what remains for you is loading the class at runtime, check this
– Mohamed EL AYADI
Nov 7 at 10:08
All what remains for you is loading the class at runtime, check this
– Mohamed EL AYADI
Nov 7 at 10:08
You found
com.myLib
(btw, please avoid using uppercase letters in package names) in jar, but did you actually put it on the compilation task classpath?– M. Prokhorov
Nov 7 at 10:23
You found
com.myLib
(btw, please avoid using uppercase letters in package names) in jar, but did you actually put it on the compilation task classpath?– M. Prokhorov
Nov 7 at 10:23
@MohamedELAYADI which class I have to load at runtime? I have the exception when I execute the
task.call()
at this point the .class of my external java file is not created yet– Fabry
Nov 7 at 10:26
@MohamedELAYADI which class I have to load at runtime? I have the exception when I execute the
task.call()
at this point the .class of my external java file is not created yet– Fabry
Nov 7 at 10:26
@M.Prokhorov yes you are right, I just replaced the real name with myLib (in production is all lowercase). It shouldn't already be the the classPath that I retrieve with
Thread.currentThread().getContextClassLoader()).getURLs()
if not how can I do it?– Fabry
Nov 7 at 10:28
@M.Prokhorov yes you are right, I just replaced the real name with myLib (in production is all lowercase). It shouldn't already be the the classPath that I retrieve with
Thread.currentThread().getContextClassLoader()).getURLs()
if not how can I do it?– Fabry
Nov 7 at 10:28
If it's not in the classpath, you'll have to add it, of course.
– M. Prokhorov
Nov 7 at 10:29
If it's not in the classpath, you'll have to add it, of course.
– M. Prokhorov
Nov 7 at 10:29
|
show 2 more comments
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53187175%2fcompile-java-file-at-runtime%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
All what remains for you is loading the class at runtime, check this
– Mohamed EL AYADI
Nov 7 at 10:08
You found
com.myLib
(btw, please avoid using uppercase letters in package names) in jar, but did you actually put it on the compilation task classpath?– M. Prokhorov
Nov 7 at 10:23
@MohamedELAYADI which class I have to load at runtime? I have the exception when I execute the
task.call()
at this point the .class of my external java file is not created yet– Fabry
Nov 7 at 10:26
@M.Prokhorov yes you are right, I just replaced the real name with myLib (in production is all lowercase). It shouldn't already be the the classPath that I retrieve with
Thread.currentThread().getContextClassLoader()).getURLs()
if not how can I do it?– Fabry
Nov 7 at 10:28
If it's not in the classpath, you'll have to add it, of course.
– M. Prokhorov
Nov 7 at 10:29