Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions src/main/java/run/myCode/compiler/InMemoryJavaFileObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ public InMemoryJavaFileObject(String fileName, String contents) {
// Using a non-file scheme is important because ECJ will otherwise try
// to open the path returned by getName() from the filesystem which
// causes "File ... is missing" errors when compiling in memory.
super(URI.create("mem:///" + fileName), Kind.SOURCE);
// Use the "string" URI scheme which the Eclipse compiler treats as an
// in-memory source and therefore does not attempt to resolve on the
// filesystem. Any other scheme will cause ECJ to verify the file on
// disk and emit a "File ... is missing" error.
super(URI.create("string:///" + fileName), Kind.SOURCE);

// Save the file's contents
this.contents = contents;
Expand All @@ -57,15 +61,6 @@ public InputStream openInputStream() throws IOException {
return new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8));
}

@Override
public String getName() {
String path = toUri().getPath();
if (path.startsWith("/")) {
return path.substring(1);
}
return path;
}

@Override
public String toString() {
String s = this.getName() + ":\n";
Expand Down
17 changes: 10 additions & 7 deletions src/main/java/run/myCode/compiler/JavaCodeCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;

import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
import javax.tools.ToolProvider;

public class JavaCodeCompiler {

Expand Down Expand Up @@ -56,7 +56,10 @@ public static FromMemoryClassLoader compile(Iterable<? extends JavaFileObject> f

final FromMemoryClassLoader classLoader = new FromMemoryClassLoader(urlcl);
// get system compiler:
final JavaCompiler compiler = new EclipseCompiler();
// Use the standard Java compiler provided by the JDK. This avoids ECJ
// attempting to resolve in-memory sources on disk which resulted in
// "File ... is missing" errors during tests.
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

// create a diagnostic listener for compilation diagnostic message processing on
// compilation WARNING/ERROR
Expand All @@ -76,11 +79,11 @@ public static FromMemoryClassLoader compile(Iterable<? extends JavaFileObject> f
options = new ArrayList<>();
}

// Build the classpath from the current folder and the system classpath
StringBuilder classpathBuilder =
new StringBuilder("."
+ System.getProperty("path.separator")
+ System.getProperty("java.class.path"));
// Build the classpath from the current folder and the system classpath
StringBuilder classpathBuilder =
new StringBuilder("." +
System.getProperty("path.separator") +
System.getProperty("java.class.path"));

// Add any included jar files from the lib folder to the classpath (wildcard isn't working)
try {
Expand Down
102 changes: 56 additions & 46 deletions src/main/java/zss/compiler/InMemoryJavaFileObject.java
Original file line number Diff line number Diff line change
@@ -1,46 +1,56 @@
package zss.compiler;

import java.io.IOException;
import java.net.URI;

import javax.tools.SimpleJavaFileObject;

import javax.tools.JavaFileObject.Kind;

/**
* java File Object represents an in-memory java source file so there is no need
* to put the source file on hard disk
*/
@SuppressWarnings("unused")
public class InMemoryJavaFileObject extends SimpleJavaFileObject {

private String contents = null;

/**
* Create a Java file object in memory with a name and text contents.
*
* @param fileName the name of the file, with extension
* @param contents the contents of the file as a single string object
* @throws Exception
*/
public InMemoryJavaFileObject(String fileName, String contents) {
// Create a file object with a classname instead of a filename by
// removing the file's extension and convert the . separators into slashes
super(URI.create("file:///" + fileName), Kind.SOURCE);

// Save the file's contents
this.contents = contents;
}

@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return contents;
}

public String toString() {
String s = this.getName() + ":\n";
s += this.contents;

return s;
}
}
package zss.compiler;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;

import javax.tools.SimpleJavaFileObject;

import javax.tools.JavaFileObject.Kind;

/**
* java File Object represents an in-memory java source file so there is no need
* to put the source file on hard disk
*/
@SuppressWarnings("unused")
public class InMemoryJavaFileObject extends SimpleJavaFileObject {

private String contents = null;

/**
* Create a Java file object in memory with a name and text contents.
*
* @param fileName the name of the file, with extension
* @param contents the contents of the file as a single string object
*/
public InMemoryJavaFileObject(String fileName, String contents) {
// Use the "string" URI scheme so the compiler treats this source as an
// in-memory file and does not attempt to resolve it on disk. Using the
// "file" scheme caused ECJ to look for a physical file and fail with
// "File ... is missing" errors.
super(URI.create("string:///" + fileName), Kind.SOURCE);

// Save the file's contents
this.contents = contents;
}

@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return contents;
}

@Override
public InputStream openInputStream() throws IOException {
return new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8));
}

@Override
public String toString() {
String s = this.getName() + ":\n";
s += this.contents;

return s;
}
}
27 changes: 15 additions & 12 deletions src/main/java/zss/compiler/MemoryCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;

import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
import javax.tools.ToolProvider;

/**
* An instance of the Eclipse Compiler for Java that compiles memory files into
* memory byte code
*/
public class MemoryCompiler {
/**
* Compiles in-memory source files into byte code using the standard JDK
* compiler. This avoids relying on the Eclipse compiler which attempted to
* resolve sources on disk.
*/
public class MemoryCompiler {
/**
* Compile Java source files into memory
*
Expand All @@ -36,8 +37,10 @@ public static FromMemoryClassLoader compile(Iterable<? extends JavaFileObject> f
// classloader
final FromMemoryClassLoader classLoader = new FromMemoryClassLoader(urlcl);

// get system compiler:
final JavaCompiler compiler = new EclipseCompiler();
// Use the standard JDK compiler to avoid ECJ attempting to read
// temporary files from disk which caused "File ... is missing"
// errors when compiling in memory.
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

// create a diagnostic listener for compilation diagnostic message processing on
// compilation WARNING/ERROR
Expand All @@ -48,10 +51,10 @@ public static FromMemoryClassLoader compile(Iterable<? extends JavaFileObject> f

// specify options for compiler
List<String> options = new ArrayList<>();
options.addAll(
Arrays.asList("-classpath", MemoryCompiler.class.getProtectionDomain().getCodeSource().getLocation()
+ ":" + System.getProperty("java.class.path")));
options.addAll(Arrays.asList("-1.8", "-nowarn"));
options.addAll(
Arrays.asList("-classpath", MemoryCompiler.class.getProtectionDomain().getCodeSource().getLocation()
+ ":" + System.getProperty("java.class.path")));
options.addAll(Arrays.asList("--release", "8", "-nowarn"));

Writer out = new PrintWriter(System.out);
JavaCompiler.CompilationTask task = compiler.getTask(out, fileManager, diag, options, null, files);
Expand Down