Search code examples
javacompiler-constructionjvm.class-filejava-compiler-api

Where compiled code will be stored if not in class file


Recently I came across a query while reading THE STRUCTURE OF THE JAVA VIRTUAL MACHINE

On page no-5 ch. 2,

Compiled code to be executed by the Java Virtual Machine is represented using a hardware- and operating system-independent binary format, typically (but not necessarily) stored in a file, known as the class file format.

That bracket But not necessarily is the reason.

Question is,

In which case compiled code will not be stored in class file ? and if it will not be stored in class file, then where and how ?

Edit : Please note that question is not about ClassLoader.


Solution

  • You seem more interest in how to generate a java class file in memory so here goes:

    public class CompileSourceInMemory {
        public static void main(String args[]) throws IOException {
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            DiagnosticCollector<JavaFileObject> diagnostics = new    DiagnosticCollector<JavaFileObject>();
    
            StringWriter writer = new StringWriter();
            PrintWriter out = new PrintWriter(writer);
            out.println("public class HelloWorld {");
            out.println("  public static void main(String args[]) {");
            out.println("    System.out.println(\"This is in another java file\");");    
            out.println("  }");
            out.println("}");
            out.close();
            JavaFileObject file = new JavaSourceFromString("HelloWorld", writer.toString());
    
            Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
            CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits);
    
            boolean success = task.call();
    
            if (success) {
                try {
                    Class.forName("HelloWorld").getDeclaredMethod("main", new Class[] { String[].class }).invoke(null, new Object[] { null });
                } catch (ClassNotFoundException e) {
                    System.err.println("Class not found: " + e);
                } catch (NoSuchMethodException e) {
                    System.err.println("No such method: " + e);
                } catch (IllegalAccessException e) {
                    System.err.println("Illegal access: " + e);
                } catch (InvocationTargetException e) {
                    System.err.println("Invocation target: " + e);
                }
            }
        }
    }
    
    class JavaSourceFromString extends SimpleJavaFileObject {
        final String code;
    
        JavaSourceFromString(String name, String code) {
            super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),Kind.SOURCE);
            this.code = code;
        }
    
        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return code;
        }
    }
    

    Source: In memory compilation

    This generates a class in memory without any external representation of the java source or compiled class.