mardi 30 juin 2015

ClassNotFoundException with dynamically generated and compiled source code [duplicate]

This question is an exact duplicate of:

The following code works correctly but in some cases when Class.forName method accesses the file it throws ClassNotFoundException because the file is not completely written, I solve the problem in those cases by increasing the sleep time.

But I want a way that forces the thread sleeps until file becomes completely written in stead of the static sleep(5000) ?

public void run(String className, String code) {
    String pkgname = "pkg" + (int) (Math.random() * 10000);
    String sb = "";
    sb += "package " + pkgname + ";\n";
    sb += code;

    File javaFile = new File(serverPath + pkgname + "/" + className + ".java");
    if (javaFile.getParentFile()
            .exists() || javaFile.getParentFile().mkdirs()) {
                try {
                FileWriter writer = new FileWriter(javaFile);
                writer.write(sb);
                writer.flush();
                writer.close();
                try {
                    Thread.sleep(5000);// here is the problem 
                } catch (InterruptedException ex) {
                    Logger.getLogger(InlineCompiler.class.getName()).log(Level.SEVERE, null, ex);
                }
                JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
                int compilationResult = compiler.run(null, null, null, javaFile.getPath());
                try {
                    String[] params = new String[0];
                    Method method = Class.forName(pkgname + "." + className).getMethod("main", String[].class);
                    method.invoke(null, (Object) params);

                } catch (NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException | IllegalAccessException ex) {
                    Logger.getLogger(InlineCompiler.class.getName()).log(Level.SEVERE, null, ex);

                }

            } catch (IOException | ClassNotFoundException exp) {
                Logger.getLogger(InlineCompiler.class.getName()).log(Level.SEVERE, null, exp);

            }
}}

Again: my problem is not the logic of the code or of Compiling and executing the file dynamically but it is only related to the sleeping time.

Exception when I decreased sleep to 2000

    Jun 27, 2015 3:06:28 AM compile.InlineCompiler run
SEVERE: null
java.lang.ClassNotFoundException: pkg5958.test
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:259)
    at compile.InlineCompiler.run(InlineCompiler.java:49)

Aucun commentaire:

Enregistrer un commentaire