diff options
author | Sravan Kumar Lakkimsetti | 2020-07-31 08:20:38 +0000 |
---|---|---|
committer | Sravan Kumar Lakkimsetti | 2020-08-06 06:43:46 +0000 |
commit | fffec414ab0eddec1965c39ad6ea55d7074d7580 (patch) | |
tree | 2a474b57905606738da5d4ba8764b45d7a6a81ce | |
parent | 1f1e2d3eea7e54f65d420be7a6134afd57c047c9 (diff) | |
download | eclipse.jdt.core-fffec414ab0eddec1965c39ad6ea55d7074d7580.tar.gz eclipse.jdt.core-fffec414ab0eddec1965c39ad6ea55d7074d7580.tar.xz eclipse.jdt.core-fffec414ab0eddec1965c39ad6ea55d7074d7580.zip |
Bug 563628 - NullPointerException in
org.eclipse.jdt.internal.compiler.tool.EclipseFileManager.getLocationForModule
In this specific case the module is different from project folder and
the java files are passed to to the compiler without modulesourcepath.
In this case we ger a null when we try to find output location for a
module.
The solution is to create modules in the standard CLASS_OUTPUT folder.
Change-Id: I09da1602ce5559fdd7678c491fc992d6f0661c91
Signed-off-by: Sravan Kumar Lakkimsetti <sravankumarl@in.ibm.com>
2 files changed, 129 insertions, 2 deletions
diff --git a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolTests.java b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolTests.java index 2b33f67f05..43cf3d4870 100644 --- a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolTests.java +++ b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolTests.java @@ -860,6 +860,127 @@ static final String[] FAKE_ZERO_ARG_OPTIONS = new String[] { assertTrue("delete failed", inputFile.delete()); } + public void testCompilerOneModuleWithEclipseCompiler() { + String tmpFolder = System.getProperty("java.io.tmpdir") + "/src/java"; + File tempDir= new File(tmpFolder + "/bar"); + tempDir.mkdirs(); + File inputFile1 = new File(tmpFolder, "module-info.java"); + BufferedWriter writer = null; + try { + writer = new BufferedWriter(new FileWriter(inputFile1)); + writer.write( + "module bar {\n" + + " exports bar;\n" + + "}\n"); + writer.flush(); + writer.close(); + } catch (IOException e) { + // ignore + } finally { + if (writer != null) { + try { + writer.close(); + } catch (IOException e) { + // ignore + } + } + } + File inputFile2 = new File(tmpFolder + "/bar", "Library.java"); + writer = null; + try { + writer = new BufferedWriter(new FileWriter(inputFile2)); + writer.write( + "package bar;\n" + + "public class Library { /**/ }\n"); + writer.flush(); + writer.close(); + } catch (IOException e) { + // ignore + } finally { + if (writer != null) { + try { + writer.close(); + } catch (IOException e) { + // ignore + } + } + } + StandardJavaFileManager manager = compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset()); + + ForwardingJavaFileManager<StandardJavaFileManager> forwardingJavaFileManager = new ForwardingJavaFileManager<StandardJavaFileManager>(manager) { + @Override + public FileObject getFileForInput(Location location, String packageName, String relativeName) + throws IOException { + if (DEBUG) { + System.out.println("Create file for input : " + packageName + " " + relativeName + " in location " + location); + } + return super.getFileForInput(location, packageName, relativeName); + } + @Override + public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) + throws IOException { + if (DEBUG) { + System.out.println("Create java file for input : " + className + " in location " + location); + } + return super.getJavaFileForInput(location, className, kind); + } + @Override + public JavaFileObject getJavaFileForOutput(Location location, + String className, + Kind kind, + FileObject sibling) throws IOException { + + if (DEBUG) { + System.out.println("Create .class file for " + className + " in location " + location + " with sibling " + sibling.toUri()); + } + JavaFileObject javaFileForOutput = super.getJavaFileForOutput(location, className, kind, sibling); + if (DEBUG) { + System.out.println(javaFileForOutput.toUri()); + } + return javaFileForOutput; + } + }; + // create new list containing input file + List<File> files = new ArrayList<File>(); + files.add(inputFile1); + files.add(inputFile2); + Iterable<? extends JavaFileObject> units = manager.getJavaFileObjectsFromFiles(files); + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + + List<String> options = new ArrayList<String>(); + options.add("-d"); + options.add(tmpFolder + "/target/classes"); + CompilationTask task = compiler.getTask(printWriter, forwardingJavaFileManager, null, options, null, units); + // check the classpath location + assertTrue("Has no location CLASS_OUPUT", forwardingJavaFileManager.hasLocation(StandardLocation.CLASS_OUTPUT)); + Boolean result = task.call(); + printWriter.flush(); + printWriter.close(); + if (!result.booleanValue()) { + System.err.println("Compilation failed: " + stringWriter.getBuffer().toString()); + assertTrue("Compilation failed ", false); + } + ClassFileReader reader = null; + try { + reader = ClassFileReader.read(new File(tmpFolder + "/target/classes", "module-info.class"), true); + } catch (ClassFormatException e) { + assertTrue("Should not happen", false); + } catch (IOException e) { + assertTrue("Should not happen", false); + } + try { + reader = ClassFileReader.read(new File(tmpFolder + "/target/classes", "bar/Library.class"), true); + } catch (ClassFormatException e) { + assertTrue("Should not happen", false); + } catch (IOException e) { + assertTrue("Should not happen", false); + } + // check that the .class file exist for module-info.class and library.class + assertTrue("delete failed", inputFile1.delete()); + assertTrue("delete failed", inputFile2.delete()); + } + // Test that JavaFileManager#inferBinaryName returns null for invalid file public void testInferBinaryName() { String tmpFolder = System.getProperty("java.io.tmpdir"); diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java index 78e3a90048..5f8b713711 100644 --- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java +++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java @@ -1424,8 +1424,14 @@ public class EclipseFileManager implements StandardJavaFileManager { Location result = this.locationHandler.getLocation(location, moduleName); if (result == null && location == StandardLocation.CLASS_OUTPUT) { LocationWrapper wrapper = this.locationHandler.getLocation(StandardLocation.MODULE_SOURCE_PATH, moduleName); - deriveOutputLocationForModules(moduleName, wrapper.paths); - result = getLocationForModule(location, moduleName); + // There are cases where we don't have module source path in that case we need to create + // classes in default location + if (wrapper == null) { + result = location; + } else { + deriveOutputLocationForModules(moduleName, wrapper.paths); + result = getLocationForModule(location, moduleName); + } } else if (result == null && location == StandardLocation.SOURCE_OUTPUT) { LocationWrapper wrapper = this.locationHandler.getLocation(StandardLocation.MODULE_SOURCE_PATH, moduleName); deriveSourceOutputLocationForModules(moduleName, wrapper.paths); |