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










share|improve this question
























  • 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















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










share|improve this question
























  • 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













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










share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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


















  • 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
















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

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















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






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














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





















































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







這個網誌中的熱門文章

Xamarin.form Move up view when keyboard appear

Post-Redirect-Get with Spring WebFlux and Thymeleaf

Anylogic : not able to use stopDelay()