| /******************************************************************************* |
| * Copyright (c) 2016, 2019 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.core.tests.model; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.Arrays; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.Map; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceDescription; |
| import org.eclipse.core.resources.IncrementalProjectBuilder; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jdt.core.IAccessRule; |
| import org.eclipse.jdt.core.IClasspathAttribute; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaModelMarker; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IModuleDescription; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.IProblemRequestor; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.WorkingCopyOwner; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.CompilationUnit; |
| import org.eclipse.jdt.core.tests.util.Util; |
| import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
| import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; |
| import org.eclipse.jdt.internal.core.ClasspathAttribute; |
| import org.eclipse.jdt.internal.core.ClasspathEntry; |
| import org.eclipse.jdt.internal.core.builder.ClasspathJrt; |
| import org.eclipse.jdt.internal.core.util.Messages; |
| |
| import junit.framework.Test; |
| |
| public class ModuleBuilderTests extends ModifyingResourceTests { |
| public ModuleBuilderTests(String name) { |
| super(name); |
| } |
| |
| static { |
| // TESTS_NAMES = new String[] { "testReleaseOption8" }; |
| } |
| private String sourceWorkspacePath = null; |
| protected ProblemRequestor problemRequestor; |
| public static Test suite() { |
| if (!isJRE9) { |
| // almost empty suite, since we need JRE9+ |
| Suite suite = new Suite(ModuleBuilderTests.class.getName()); |
| suite.addTest(new ModuleBuilderTests("thisSuiteRunsOnJRE9plus")); |
| return suite; |
| } |
| return buildModelTestSuite(ModuleBuilderTests.class, BYTECODE_DECLARATION_ORDER); |
| } |
| public void thisSuiteRunsOnJRE9plus() {} |
| |
| public String getSourceWorkspacePath() { |
| return this.sourceWorkspacePath == null ? super.getSourceWorkspacePath() : this.sourceWorkspacePath; |
| } |
| public void setUp() throws Exception { |
| super.setUp(); |
| this.problemRequestor = new ProblemRequestor(); |
| this.wcOwner = new WorkingCopyOwner() { |
| public IProblemRequestor getProblemRequestor(ICompilationUnit unit) { |
| return ModuleBuilderTests.this.problemRequestor; |
| } |
| }; |
| } |
| public void setUpSuite() throws Exception { |
| super.setUpSuite(); |
| this.currentProject = createJava9Project("P1"); |
| this.createFile("P1/src/module-info.java", ""); |
| this.createFolder("P1/src/com/greetings"); |
| this.createFile("P1/src/com/greetings/Main.java", ""); |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| } |
| |
| public void tearDownSuite() throws Exception { |
| super.tearDownSuite(); |
| deleteProject("P1"); |
| } |
| |
| // Test that the java.base found as a module package fragment root in the project |
| public void test001() throws CoreException { |
| try { |
| IJavaProject project = createJava9Project("Test01", new String[]{"src"}); |
| this.createFile("Test01/src/module-info.java", ""); |
| this.createFolder("Test01/src/com/greetings"); |
| this.createFile("Test01/src/com/greetings/Main.java", ""); |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IPackageFragmentRoot[] roots = project.getPackageFragmentRoots(); |
| IPackageFragmentRoot base = null; |
| for (IPackageFragmentRoot iRoot : roots) { |
| IModuleDescription moduleDescription = iRoot.getModuleDescription(); |
| if (moduleDescription != null && moduleDescription.getElementName().equals("java.base")) { |
| base = iRoot; |
| break; |
| } |
| } |
| assertNotNull("Java.base module should not null", base); |
| assertMarkers("Unexpected markers", "", project); |
| } finally { |
| deleteProject("Test01"); |
| } |
| } |
| // Test the project compiles without errors with a simple module-info.java |
| public void test002() throws CoreException { |
| try { |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| " requires java.base;\n" + |
| "}"); |
| waitForManualRefresh(); |
| this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertMarkers("Unexpected markers", "", this.currentProject); |
| } finally { |
| } |
| } |
| // Test that types from java.base module are seen by the compiler |
| // even without an explicit 'requires java.base' declaration. |
| public void test003() throws CoreException { |
| try { |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| "}"); |
| this.editFile("P1/src/com/greetings/Main.java", |
| "package com.greetings;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " }\n" + |
| "}"); |
| waitForManualRefresh(); |
| this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = this.currentProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| } |
| } |
| // Test that a type that is present in the JDK, but not observable to the source module, |
| // is reported as a compilation error. |
| public void test004() throws CoreException { |
| try { |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| " requires java.base;\n" + |
| "}"); |
| this.editFile("P1/src/com/greetings/Main.java", |
| "package com.greetings;\n" + |
| "import java.sql.Connection;\n" + |
| "public class Main {\n" + |
| " public Connection con = null;\n" + |
| "}"); |
| waitForManualRefresh(); |
| this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = this.currentProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type java.sql.Connection is not accessible\n" + |
| "Connection cannot be resolved to a type", markers); |
| } finally { |
| } |
| } |
| // Test that a type that is outside java.base module is available to the compiler |
| // when the module is specified as 'requires'. |
| public void test005() throws CoreException { |
| try { |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| " requires java.base;\n" + |
| " requires java.sql;\n" + |
| "}"); |
| waitForManualRefresh(); |
| this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = this.currentProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| // just an API leak warning: |
| "The type Connection from module java.sql may not be accessible to clients due to missing \'requires transitive\'", |
| markers); |
| } finally { |
| } |
| } |
| // Test that a module that doesn't exist but specified as requires in module-info |
| // doesn't affect rest of the compilation. |
| public void _test006() throws CoreException { |
| try { |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| " requires java.base;\n" + |
| " requires java.sql;\n" + |
| " requires java.idontexist;\n" + |
| "}"); |
| this.editFile("P1/src/com/greetings/Main.java", |
| "package com.greetings;\n" + |
| "public class Main {\n" + |
| "}"); |
| waitForManualRefresh(); |
| this.currentProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = this.currentProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| } |
| } |
| private IJavaProject setupP2() throws CoreException { |
| IJavaProject project = createJava9Project("P2"); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry projectEntry = JavaCore.newProjectEntry(new Path("/P1"), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| true); |
| IClasspathEntry[] old = project.getRawClasspath(); |
| IClasspathEntry[] newPath = new IClasspathEntry[old.length +1]; |
| System.arraycopy(old, 0, newPath, 0, old.length); |
| newPath[old.length] = projectEntry; |
| project.setRawClasspath(newPath, null); |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| " requires java.base;\n" + |
| "}"); |
| this.editFile("P1/src/com/greetings/Main.java", |
| "package com.greetings;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " }\n" + |
| "}"); |
| this.createFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires M1;\n" + |
| "}"); |
| this.createFolder("P2/src/org/astro"); |
| this.createFile("P2/src/org/astro/Test.java", |
| "package org.astro;\n" + |
| "import com.greetings.Main;\n" + |
| "public class Test {\n" + |
| " public static void main(String[] args) {\n" + |
| " Main.main(args);\n" + |
| " }\n" + |
| "}"); |
| return project; |
| } |
| /* |
| * Two Java projects, each with one module. P2 has P1 in its build path but |
| * module M2 has no 'requires' M1. Should report unresolved type, import etc. |
| * |
| */ |
| public void test007() throws Exception { |
| try { |
| IJavaProject project = setupP2(); |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| "}"); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " //requires M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| project.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type com.greetings.Main is not accessible\n" + |
| "Main cannot be resolved", |
| markers); |
| } finally { |
| deleteProject("P2"); |
| } |
| } |
| /* |
| * Two Java project, each with one module. P2 has P1 in its build path and |
| * module M2 'requires' M1. Should report unresolved type, import etc. But M1 |
| * does not export the package that is used by M2. Test that M2 does not see |
| * the types in unexported packages. |
| * |
| */ |
| public void test008() throws Exception { |
| try { |
| IJavaProject project = setupP2(); |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " //exports com.greetings;\n" + |
| "}"); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| project.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type com.greetings.Main is not accessible\n" + |
| "Main cannot be resolved", |
| markers); |
| } finally { |
| deleteProject("P2"); |
| } |
| } |
| /* |
| * Two Java projects, each with one module. P2 has P1 in its build path. |
| * Module M2 has "requires M1" in module-info and all packages used by M2 |
| * are exported by M1. No errors expected. |
| */ |
| public void test009() throws Exception { |
| try { |
| IJavaProject project = setupP2(); |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| "}"); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| project.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "", markers); |
| } finally { |
| deleteProject("P2"); |
| } |
| } |
| /* |
| * Two Java projects, each with a module. Project P2 depends on P1. |
| * Module M1 exports a package to a specific module, which is not M2. |
| * Usage of types from M1 in M2 should be reported. |
| */ |
| public void _test010() throws Exception { |
| try { |
| IJavaProject project = setupP2(); |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings to org.main;\n" + |
| "}"); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| project.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The import com.greetings.Main cannot be resolved\n" + |
| "Main cannot be resolved", |
| markers); |
| } finally { |
| deleteProject("P2"); |
| } |
| } |
| private IJavaProject setupP3() throws CoreException { |
| IJavaProject project = createJava9Project("P3"); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry projectEntry = JavaCore.newProjectEntry(new Path("/P2"), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| true); |
| IClasspathEntry[] old = project.getRawClasspath(); |
| IClasspathEntry[] newPath = new IClasspathEntry[old.length +1]; |
| System.arraycopy(old, 0, newPath, 0, old.length); |
| newPath[old.length] = projectEntry; |
| project.setRawClasspath(newPath, null); |
| this.createFile("P3/src/module-info.java", |
| "module M3 {\n" + |
| " exports org.main;\n" + |
| " requires M2;\n" + |
| "}"); |
| this.createFolder("P3/src/org/main"); |
| this.createFile("P3/src/org/main/TestMain.java", |
| "package org.main;\n" + |
| "import com.greetings.*;\n" + |
| "public class TestMain {\n" + |
| " public static void main(String[] args) {\n" + |
| " Main.main(args);\n" + |
| " }\n" + |
| "}"); |
| return project; |
| } |
| /* |
| * Three Java projects, each with one module. Project P3 depends on P2, which depends on P1. |
| * Module M1 exports a package (to all), M2 requires M1 and M3 requires M2. Usage of types from |
| * M1 in M3 should be reported as errors. |
| */ |
| public void test011() throws Exception { |
| try { |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| "}"); |
| IJavaProject p2 = setupP2(); |
| IJavaProject p3 = setupP3(); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The package com.greetings is not accessible\n" + |
| "Main cannot be resolved", |
| markers); |
| } finally { |
| deleteProject("P2"); |
| deleteProject("P3"); |
| } |
| } |
| /* |
| * Three Java projects, each with one module. Project P3 depends on P2, which depends on P1. |
| * Module M1 exports a package only to M2, M2 requires M1 and M3 requires M2. Usage of types from |
| * M1 in M3 should not be allowed. |
| */ |
| public void test012() throws Exception { |
| try { |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings to M2;\n" + |
| "}"); |
| IJavaProject p2 = setupP2(); |
| IJavaProject p3 = setupP3(); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The package com.greetings is not accessible\n" + |
| "Main cannot be resolved", |
| markers); |
| } finally { |
| deleteProject("P2"); |
| deleteProject("P3"); |
| } |
| } |
| /* |
| * Three Java projects, each with one module. Project P3 depends on P2, which depends on P1. |
| * Module M1 exports a package (to all), M2 requires 'transitive' M1 and M3 requires M2. Usage of types from |
| * M1 in M3 should be allowed. |
| */ |
| public void test013() throws Exception { |
| try { |
| IJavaProject p2 = setupP2(); |
| IJavaProject p3 = setupP3(); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires transitive M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("P2"); |
| deleteProject("P3"); |
| } |
| } |
| /* |
| * Three Java projects, each with one module. Project P3 depends on P2, which depends on P1. |
| * Module M1 exports a package only to M2, M2 requires 'public' M1 and M3 requires M2. Usage of types from |
| * M1 in M3 should be allowed. And no errors reported on M2. |
| */ |
| public void test014() throws Exception { |
| try { |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings to M2;\n" + |
| "}"); |
| IJavaProject p2 = setupP2(); |
| IJavaProject p3 = setupP3(); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires transitive M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("P2"); |
| deleteProject("P3"); |
| } |
| } |
| public void test015() throws CoreException, IOException { |
| try { |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings to M2;\n" + |
| "}"); |
| IJavaProject p2 = setupP2(); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires transitive M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IFolder folder = getFolder("P1/src"); |
| assertNotNull("Should be a module", this.currentProject.getModuleDescription()); |
| folder = getFolder("P2/src"); |
| folder = getFolder("P1/bin"); |
| IPath jarPath = p2.getResource().getLocation().append("m0.jar"); |
| org.eclipse.jdt.core.tests.util.Util.zip(new File(folder.getLocation().toOSString()), jarPath.toOSString()); |
| IClasspathEntry[] old = p2.getRawClasspath(); |
| for (int i = 0; i < old.length; i++) { |
| if (old[i].isExported()) { |
| old[i] = JavaCore.newLibraryEntry(new Path("/P2/m0.jar"), null, null); |
| break; |
| } |
| } |
| p2.setRawClasspath(old, null); |
| p2.getProject().refreshLocal(IResource.DEPTH_INFINITE, null); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNotNull("Should be a module", p2.getModuleDescription()); |
| } finally { |
| deleteProject("P2"); |
| deleteProject("P3"); |
| } |
| } |
| /* |
| * Change the module-info and wait for autobuild to |
| * report expected errors. |
| */ |
| public void test016() throws CoreException, IOException { |
| try { |
| IJavaProject p2 = setupP2(); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires java.base;\n" + |
| " requires transitive M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| "}"); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); |
| markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type com.greetings.Main is not accessible\n" + |
| "Main cannot be resolved", markers); |
| } finally { |
| deleteProject("P2"); |
| } |
| } |
| /* |
| * Change the module-info of a required module and wait for autobuild to |
| * report expected errors. |
| */ |
| public void test017() throws CoreException, IOException { |
| try { |
| IJavaProject p2 = setupP2(); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires java.base;\n" + |
| " requires transitive M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " requires java.base;\n" + |
| "}"); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); |
| markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type com.greetings.Main is not accessible\n" + |
| "Main cannot be resolved", markers); |
| } finally { |
| deleteProject("P2"); |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| " requires java.base;\n" + |
| "}"); |
| } |
| } |
| /* |
| * Change the module-info of a required module and wait for autobuild to |
| * report expected errors. |
| */ |
| public void test018() throws CoreException, IOException { |
| try { |
| String wkspEncoding = System.getProperty("file.encoding"); |
| final String encoding = "UTF-8".equals(wkspEncoding) ? "Cp1252" : "UTF-8"; |
| IJavaProject p2 = setupP2(); |
| this.editFile("P2/src/module-info.java", |
| "module M2 {\n" + |
| " exports org.astro;\n" + |
| " requires java.base;\n" + |
| " requires transitive M1;\n" + |
| "}"); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| IFile bin = getFile("P1/bin/com/greetings/Main.class"); |
| long old = bin.getLocalTimeStamp(); |
| IFile file = getFile("P1/src/module-info.java"); |
| file.setCharset(encoding, null); |
| waitForManualRefresh(); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); |
| markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "", markers); |
| long latest = getFile("P1/bin/com/greetings/Main.class").getLocalTimeStamp(); |
| assertTrue("Should not have been recompiled", old == latest); |
| } finally { |
| deleteProject("P2"); |
| } |
| } |
| /* |
| * Test that adding or removing java.base does not result in |
| * re-compilation of module. |
| */ |
| public void _test019() throws CoreException, IOException { |
| try { |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| " requires java.base;\n" + |
| "}"); |
| waitForManualRefresh(); |
| this.currentProject.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = this.currentProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| IFile bin = getFile("P1/bin/com/greetings/Main.class"); |
| long old = bin.getLocalTimeStamp(); |
| waitForManualRefresh(); |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| "}"); |
| this.currentProject.getProject().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); |
| long latest = getFile("P1/bin/com/greetings/Main.class").getLocalTimeStamp(); |
| assertTrue("Should not have been recompiled", old == latest); |
| } finally { |
| deleteProject("P2"); |
| this.editFile("P1/src/module-info.java", |
| "module M1 {\n" + |
| " exports com.greetings;\n" + |
| " requires java.base;\n" + |
| "}"); |
| } |
| } |
| public void testConvertToModule() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| try { |
| IJavaProject project = setUpJavaProject("ConvertToModule"); |
| Map<String, String> options = new HashMap<>(); |
| // Make sure the new options map doesn't reset. |
| options.put(CompilerOptions.OPTION_Compliance, "9"); |
| options.put(CompilerOptions.OPTION_Source, "9"); |
| options.put(CompilerOptions.OPTION_TargetPlatform, "9"); |
| options.put(CompilerOptions.OPTION_Release, "enabled"); |
| project.setOptions(options); |
| project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IPackageFragmentRoot[] roots = project.getPackageFragmentRoots(); |
| IPackageFragmentRoot theRoot = null; |
| for (IPackageFragmentRoot root : roots) { |
| if (root.getElementName().equals("jdt.test")) { |
| theRoot = root; |
| break; |
| } |
| } |
| assertNotNull("should not be null", theRoot); |
| String[] modules = JavaCore.getReferencedModules(project); |
| if (isJRE12) |
| assertStringsEqual("incorrect result", new String[]{"java.desktop", "java.rmi", "java.sql"}, modules); |
| else if (isJRE11) |
| assertStringsEqual("incorrect result", new String[]{"java.datatransfer", "java.desktop", "java.net.http", "java.rmi", "java.sql"}, modules); |
| else if (isJRE10) |
| assertStringsEqual("incorrect result", new String[]{"java.datatransfer", "java.desktop", "java.rmi", "java.sql"}, modules); |
| else // 9 |
| assertStringsEqual("incorrect result", new String[]{"java.desktop", "java.rmi", "java.sql"}, modules); |
| } finally { |
| this.deleteProject("ConvertToModule"); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| public void test_services_abstractImpl() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public abstract class MyWorld implements World { }\n" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Invalid service implementation, the type com.greetings.MyWorld is abstract", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_invalidImpl() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "public class MyWorld { }\n" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Type mismatch: cannot convert from MyWorld to World", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_NoDefaultConstructor() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public MyWorld(String name) { }\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "The service implementation com.greetings.MyWorld must define a public static provider method or a no-arg constructor", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_DefaultConstructorNotVisible() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " MyWorld() { }\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "The no-arg constructor of service implementation com.greetings.MyWorld is not public", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_DuplicateEntries() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyWorld;\n" + |
| " provides org.astro.World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Duplicate service entry: org.astro.World", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_NestedClass() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyWorld.Nested;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld {\n" + |
| " public static class Nested implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_NonStatic_NestedClass() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyWorld.Nested;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld {\n" + |
| " public class Nested implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Invalid service implementation, the type com.greetings.MyWorld.Nested is an inner class", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_ImplDefinedInAnotherModule() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "src/org/astro/AstroWorld.java", |
| "package org.astro;\n" + |
| "public class AstroWorld implements World{\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " provides org.astro.World with org.astro.AstroWorld;\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Service implementation org.astro.AstroWorld is not defined in the module with the provides directive", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_ProviderMethod() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyImpl;\n" + |
| "}", |
| "src/com/greetings/MyImpl.java", |
| "package com.greetings;\n" + |
| "public class MyImpl {\n" + |
| " public static MyWorld provider() {\n" + |
| " return new MyWorld(\"Name\");\n" + |
| " }\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public MyWorld(String name) { }\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_ProviderMethod_ReturnTypeFromAnotherModule() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", sources, true); |
| sources = new String[] { |
| "src/module-info.java", |
| "module other.mod {\n" + |
| " requires org.astro;\n" + |
| " exports org.impl;\n" + |
| "}", |
| "src/org/impl/MyWorld.java", |
| "package org.impl;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| setupModuleProject("other.mod", sources, true); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " requires transitive other.mod;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyImpl;\n" + |
| "}", |
| "src/com/greetings/MyImpl.java", |
| "package com.greetings;\n" + |
| "import org.impl.MyWorld;\n" + |
| "public class MyImpl {\n" + |
| " public static MyWorld provider() {\n" + |
| " return new MyWorld();\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p3 = setupModuleProject("com.greetings", src, true); |
| p3.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("other.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_ProviderMethod_ReturnTypeInvisible() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", sources, true); |
| sources = new String[] { |
| "src/module-info.java", |
| "module other.mod {\n" + |
| " requires org.astro;\n" + |
| "}", |
| "src/org/impl/MyWorld.java", |
| "package org.impl;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| setupModuleProject("other.mod", sources, true); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " requires other.mod;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyImpl;\n" + |
| "}", |
| "src/com/greetings/MyImpl.java", |
| "package com.greetings;\n" + |
| "import org.impl.MyWorld;\n" + |
| "public class MyImpl {\n" + |
| " public static MyWorld provider() {\n" + |
| " return new MyWorld();\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p3 = setupModuleProject("com.greetings", src, true); |
| p3.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().getFile(new Path("src/module-info.java")).findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "MyWorld cannot be resolved to a type", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("other.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_ProviderMethod_InvalidReturnType() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyImpl;\n" + |
| "}", |
| "src/com/greetings/MyImpl.java", |
| "package com.greetings;\n" + |
| "public class MyImpl {\n" + |
| " public static MyWorld provider() {\n" + |
| " return new MyWorld(\"Name\");\n" + |
| " }\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "public class MyWorld {\n" + |
| " public MyWorld(String name) { }\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "Type mismatch: cannot convert from MyWorld to World", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_DuplicateImplEntries() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyWorld, com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Duplicate service entry: com.greetings.MyWorld", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_InvalidIntfType() throws CoreException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " exports com.greetings;\n" + |
| " provides com.greetings.MyEnum with com.greetings.MyEnum;\n" + |
| "}", |
| "src/com/greetings/MyEnum.java", |
| "package com.greetings;\n" + |
| "public enum MyEnum {}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "Invalid service interface com.greetings.MyEnum, must be a class, interface or annotation type\n" + |
| "Invalid service implementation com.greetings.MyEnum, must be a public class or interface type", markers); |
| } finally { |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_InvalidImplType() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyEnum;\n" + |
| "}", |
| "src/com/greetings/MyEnum.java", |
| "package com.greetings;\n" + |
| "public enum MyEnum implements org.astro.World {}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Invalid service implementation com.greetings.MyEnum, must be a public class or interface type", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_services_nonPublicImpl() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides org.astro.World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "The type com.greetings.MyWorld is not visible", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_Exports_Error() throws CoreException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " exports com.greetings;\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "The package com.greetings does not exist or is empty", markers); |
| } finally { |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_DuplicateExports() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Duplicate exports entry: org.astro", markers); |
| } finally { |
| deleteProject("org.astro"); |
| } |
| } |
| public void test_TargetedExports_Duplicates() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro to com.greetings, com.greetings;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath()); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Duplicate module name: com.greetings", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // Types from source module should be resolved in target module |
| // when package is exported specifically to the target module |
| public void test_TargetedExports() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro to com.greetings;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // Types in one module should not be visible in target module when |
| // source module exports packages to a specific module which is not |
| // the same as the target module |
| public void test_TargetedExports_Error() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module some.mod { }", |
| }; |
| setupModuleProject("some.mod", sources); |
| sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro to some.mod;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type org.astro.World is not accessible\n" + |
| "World cannot be resolved to a type", |
| markers); |
| } finally { |
| deleteProject("some.mod"); |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // It is permitted for the to clause of an exports or opens statement to |
| // specify a module which is not observable |
| public void test_TargetedExports_Unresolved() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro to some.mod;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| } |
| } |
| // Target module of an exports statement should be resolved without having an explicit |
| // dependency to the project that defines the module |
| public void test_TargetedExports_Resolution() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module some.mod {\n" + |
| "}" |
| }; |
| setupModuleProject("some.mod", sources); |
| sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro to some.mod;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("some.mod"); |
| } |
| } |
| // Make sure modules in the workspace are resolved via the module source path container |
| // without needing to add a dependency to the project explicitly |
| public void test_ModuleSourcePathContainer() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", sources); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // Make sure module path container picks up changes to module-info |
| public void _test_ModuleSourcePath_update() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module some.mod {\n" + |
| "}" |
| }; |
| setupModuleProject("some.mod", sources); |
| sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", sources); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| this.editFile("com.greetings/src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " requires some.mod;\n" + |
| " exports com.greetings;\n" + |
| "}"); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("some.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // Implicit module dependencies via the 'requires transitive' directive should be |
| // resolved via the module path container |
| public void test_ModuleSourcePath_implicitdeps() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module some.mod {\n" + |
| " requires transitive org.astro;\n" + |
| "}" |
| }; |
| setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires some.mod;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("some.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // Changes to implicit dependencies should be reflected // FIXME: container JavaCore.MODULE_PATH_CONTAINER_ID is unreliable |
| public void _test_ModuleSourcePath_implicitdeps2() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module some.mod {\n" + |
| " requires transitive org.astro;\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires some.mod;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| this.editFile("some.mod/src/module-info.java", |
| "module some.mod {\n" + |
| " requires org.astro;\n" + |
| "}"); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type org.astro.World is not accessible\n" + |
| "World cannot be resolved to a type", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("some.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // Changes to implicit dependencies should be reflected |
| //TODO enable once we know how to update project cache |
| public void _test_ModuleSourcePath_implicitdeps3() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module some.mod {\n" + |
| " requires org.astro;\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires some.mod;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| this.editFile("some.mod/src/module-info.java", |
| "module some.mod {\n" + |
| " requires transitive org.astro;\n" + |
| "}"); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("some.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_Cycle_In_Module_Dependency() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module some.mod {\n" + |
| " requires org.astro;\n" + |
| "}" |
| }; |
| setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires some.mod;\n" + |
| " exports com.greetings;\n" + |
| "}" |
| }; |
| |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| editFile("org.astro/src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| " requires com.greetings;\n" + |
| "}"); |
| waitForAutoBuild(); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertTrue("Should detect cycle", p2.hasClasspathCycle(null)); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("some.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_Cycle_In_Implicit_Module_Dependency() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module some.mod {\n" + |
| " requires transitive org.astro;\n" + |
| "}" |
| }; |
| setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires some.mod;\n" + |
| " exports com.greetings;\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| editFile("org.astro/src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| " requires transitive com.greetings;\n" + |
| "}"); |
| waitForAutoBuild(); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertTrue("Should detect cycle", p2.hasClasspathCycle(null)); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("some.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_bug506479() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| IJavaProject p1 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| IWorkspaceDescription desc = p1.getProject().getWorkspace().getDescription(); |
| desc.setAutoBuilding(false); |
| p1.getProject().getWorkspace().setDescription(desc); |
| this.deleteFile("org.astro/src/module-info.java"); |
| this.createFile( |
| "org.astro/src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}"); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| } finally { |
| deleteProject("org.astro"); |
| } |
| } |
| public void test_Multiple_SourceFolders() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "othersrc/org/astro/OtherWorld.java", |
| "package org.astro;\n" + |
| "import org.astro.World;\n" + |
| "public interface OtherWorld {\n" + |
| " default public String name() {\n" + |
| " return \" Other World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", new String[]{"src", "othersrc"}, sources, null); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}", |
| "othersrc/com/greetings/AnotherWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.OtherWorld;\n" + |
| "public class AnotherWorld implements OtherWorld {\n" + |
| " public String name() {\n" + |
| " return \" Another World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| IJavaProject p2 = setupModuleProject("com.greetings", new String[]{"src", "othersrc"}, src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_Multiple_SourceFolders_WithModuleInfo() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "othersrc/org/astro/OtherWorld.java", |
| "package org.astro;\n" + |
| "import org.astro.World;\n" + |
| "public interface OtherWorld {\n" + |
| " default public String name() {\n" + |
| " return \" Other World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", new String[]{"src", "othersrc"}, sources, null); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}", |
| "othersrc/module-info.java", |
| "module com.greetings1 {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "othersrc/com/greetings/AnotherWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.OtherWorld;\n" + |
| "public class AnotherWorld implements OtherWorld {\n" + |
| " public String name() {\n" + |
| " return \" Another World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| IJavaProject p2 = setupModuleProject("com.greetings", new String[]{"src", "othersrc"}, src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ZERO); |
| assertEquals(1, markers.length); |
| String msg = markers[0].getAttribute(IMarker.MESSAGE, ""); |
| String expected = Messages.bind(Messages.classpath_duplicateEntryPath, TypeConstants.MODULE_INFO_FILE_NAME_STRING, p2.getElementName()); |
| assertTrue("Unexpected result", msg.indexOf(expected) != -1); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_Multiple_SourceFolders_addModuleInfo() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "othersrc/org/astro/OtherWorld.java", |
| "package org.astro;\n" + |
| "import org.astro.World;\n" + |
| "public interface OtherWorld {\n" + |
| " default public String name() {\n" + |
| " return \" Other World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", new String[]{"src", "othersrc"}, sources, null); |
| this.createFile("org.astro/othersrc/module-info.java", |
| "module org.astro1 {\n" + |
| " exports org.astro;\n" + |
| "}"); |
| waitForAutoBuild(); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ZERO); |
| assertEquals(1, markers.length); |
| String msg = markers[0].getAttribute(IMarker.MESSAGE, ""); |
| String expected = Messages.bind(Messages.classpath_duplicateEntryPath, TypeConstants.MODULE_INFO_FILE_NAME_STRING, p1.getElementName()); |
| assertTrue("Unexpected result", msg.indexOf(expected) != -1); |
| } finally { |
| deleteProject("org.astro"); |
| } |
| } |
| public void test_Multiple_SourceFolders_removeModuleInfo() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "othersrc/module-info.java", |
| "module org.astro1 {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "othersrc/org/astro/OtherWorld.java", |
| "package org.astro;\n" + |
| "import org.astro.World;\n" + |
| "public interface OtherWorld {\n" + |
| " default public String name() {\n" + |
| " return \" Other World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", new String[]{"src", "othersrc"}, sources, null); |
| waitForAutoBuild(); |
| this.deleteFile("org.astro/othersrc/module-info.java"); |
| waitForAutoBuild(); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ZERO); |
| assertEquals(0, markers.length); |
| } finally { |
| deleteProject("org.astro"); |
| } |
| } |
| public void test_services_multipleImpl() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "import org.astro.World;\n" + |
| "import com.greetings.*;\n" + |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides World with MyWorld, AnotherWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}", |
| "src/com/greetings/AnotherWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class AnotherWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" Another World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_imports_in_moduleinfo() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "import org.astro.World;\n" + |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| |
| public void test_Opens_Nonexistent_Package() throws CoreException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " opens com.greetings;\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_Opens_Alien_Package() throws CoreException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module org.astro {}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}\n" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", src); |
| src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " opens org.astro;\n" + |
| "}", |
| "src/test/Test.java", |
| "package test;\n" + |
| "public class Test {\n" + |
| " org.astro.World w = null;\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute(IClasspathAttribute.MODULE, "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type org.astro.World is not accessible\n" + |
| "The package org.astro does not exist or is empty", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_DuplicateOpens() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " opens org.astro;\n" + |
| " opens org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Duplicate opens entry: org.astro", markers); |
| } finally { |
| deleteProject("org.astro"); |
| } |
| } |
| public void test_TargetedOpens_Duplicates() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " opens org.astro to com.greetings, com.greetings;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath()); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Duplicate module name: com.greetings", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // It is permitted for the to clause of an exports or opens statement to |
| // specify a module which is not observable |
| public void test_TargetedOpens_Unresolved() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " opens org.astro to some.mod;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| } |
| } |
| // It is a compile-time error if an opens statement appears in the declaration of an open module. |
| public void test_OpensStatment_in_OpenModule() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "open module org.astro {\n" + |
| " opens org.astro to some.mod;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "opens statement is not allowed, as module org.astro is declared open", markers); |
| } finally { |
| deleteProject("org.astro"); |
| } |
| } |
| public void test_uses_DuplicateEntries() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| " uses org.astro.World;\n" + |
| " uses org.astro.World;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Duplicate uses entry: org.astro.World", markers); |
| } finally { |
| deleteProject("org.astro"); |
| } |
| } |
| public void test_uses_InvalidIntfType() throws CoreException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " exports com.greetings;\n" + |
| " uses com.greetings.MyEnum;\n" + |
| "}", |
| "src/com/greetings/MyEnum.java", |
| "package com.greetings;\n" + |
| "public enum MyEnum {}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "Invalid service interface com.greetings.MyEnum, must be a class, interface or annotation type", markers); |
| } finally { |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_ReconcilerModuleLookup1() throws CoreException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires java.sql;\n" + |
| "}"}; |
| setupModuleProject("com.greetings", src); |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = src[1].toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/com.greetings/src/module-info.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_ReconcilerModuleLookup2() throws CoreException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires java.sq;\n" + |
| "}"}; |
| setupModuleProject("com.greetings", src); |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = src[1].toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/com.greetings/src/module-info.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /com.greetings/src/module-info.java (at line 2)\n" + |
| " requires java.sq;\n" + |
| " ^^^^^^^\n" + |
| "java.sq cannot be resolved to a module\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject("com.greetings"); |
| } |
| } |
| public void testSystemLibAsJMod() throws CoreException { |
| try { |
| IJavaProject project = createJava9Project("Test01", new String[]{"src"}); |
| IClasspathEntry[] rawClasspath = project.getRawClasspath(); |
| for (int i = 0; i < rawClasspath.length; i++) { |
| IPath path = rawClasspath[i].getPath(); |
| if (path.lastSegment().equals("jrt-fs.jar")) { |
| path = path.removeLastSegments(2).append("jmods").append("java.base.jmod"); |
| IClasspathEntry newEntry = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(), new Path("java.base")); |
| rawClasspath[i] = newEntry; |
| } |
| } |
| project.setRawClasspath(rawClasspath, null); |
| this.createFile("Test01/src/module-info.java", ""); |
| this.createFolder("Test01/src/com/greetings"); |
| this.createFile("Test01/src/com/greetings/Main.java", ""); |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IPackageFragmentRoot[] roots = project.getPackageFragmentRoots(); |
| IPackageFragmentRoot base = null; |
| for (IPackageFragmentRoot iRoot : roots) { |
| IModuleDescription moduleDescription = iRoot.getModuleDescription(); |
| if (moduleDescription != null) { |
| base = iRoot; |
| break; |
| } |
| } |
| assertNotNull("Java.base module should not null", base); |
| assertMarkers("Unexpected markers", "", project); |
| } finally { |
| deleteProject("Test01"); |
| } |
| } |
| public void testSystemLibAsJMod_2() throws CoreException { |
| try { |
| IJavaProject project = createJava9Project("Test01", new String[]{"src"}); |
| IClasspathEntry[] rawClasspath = project.getRawClasspath(); |
| IClasspathEntry[] newClasspath = new IClasspathEntry[rawClasspath.length + 1]; |
| IClasspathEntry desktop = null; |
| for (int i = 0; i < rawClasspath.length; i++) { |
| IPath path = rawClasspath[i].getPath(); |
| if (path.lastSegment().equals("jrt-fs.jar")) { |
| path = path.removeLastSegments(2).append("jmods").append("java.base.jmod"); |
| IClasspathAttribute[] attributes = { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| IClasspathEntry newEntry = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(), |
| new Path("java.base"), null, attributes, rawClasspath[i].isExported()); |
| newClasspath[i] = newEntry; |
| path = path.removeLastSegments(2).append("jmods").append("java.desktop.jmod"); |
| desktop = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(), |
| new Path("java.desktop"), null, attributes, rawClasspath[i].isExported()); |
| } else { |
| newClasspath[i] = rawClasspath[i]; |
| } |
| } |
| newClasspath[rawClasspath.length] = desktop; |
| project.setRawClasspath(newClasspath, null); |
| this.createFile("Test01/src/module-info.java", |
| "module org.eclipse {\n" + |
| " requires java.desktop;\n" + |
| " requires java.base;\n" + |
| "}"); |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); |
| assertMarkers("unexpected markers", "", markers); |
| |
| // Check the reconciler |
| ICompilationUnit cu = getCompilationUnit("/Test01/src/module-info.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| markers = project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); |
| editFile("Test01/src/module-info.java", |
| "//Just touching \n" + |
| "module org.eclipse {\n" + |
| " requires java.desktop;\n" + |
| " requires java.base;\n" + |
| "}"); |
| project.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| markers = project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); |
| assertMarkers("unexpected markers", "", markers); |
| } finally { |
| deleteProject("Test01"); |
| } |
| } |
| public void testBug510617() throws CoreException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module Test {\n" + |
| " exports p;\n" + |
| " requires java.sql;\n" + |
| " provides java.sql.Driver with p.C;\n" + |
| "}", |
| "src/p/C.java", |
| "package p;\n" + |
| "import java.lang.SecurityManager;\n" + |
| "import java.sql.Connection;\n" + |
| "import java.sql.Driver;\n" + |
| "import java.sql.DriverPropertyInfo;\n" + |
| "import java.sql.SQLException;\n" + |
| "import java.sql.SQLFeatureNotSupportedException;\n" + |
| "import java.util.Properties;\n" + |
| "import java.util.logging.Logger;\n" + |
| "public class C implements Driver {\n" + |
| " SecurityManager s;\n" + |
| " @Override\n" + |
| " public boolean acceptsURL(String arg0) throws SQLException {\n" + |
| " return false;\n" + |
| " }\n" + |
| " @Override\n" + |
| " public Connection connect(String arg0, Properties arg1) throws SQLException {\n" + |
| " return null;\n" + |
| " }\n" + |
| " @Override\n" + |
| " public int getMajorVersion() {\n" + |
| " return 0;\n" + |
| " }\n" + |
| " @Override\n" + |
| " public int getMinorVersion() {\n" + |
| " return 0;\n" + |
| " }\n" + |
| " @Override\n" + |
| " public Logger getParentLogger() throws SQLFeatureNotSupportedException {\n" + |
| " return null;\n" + |
| " }\n" + |
| " @Override\n" + |
| " public DriverPropertyInfo[] getPropertyInfo(String arg0, Properties arg1) throws SQLException {\n" + |
| " return null;\n" + |
| " }\n" + |
| " @Override\n" + |
| " public boolean jdbcCompliant() {\n" + |
| " return false;\n" + |
| " } \n" + |
| "}" |
| }; |
| setupModuleProject("Test", src); |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = src[1].toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit("/Test/src/module-info.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject("Test"); |
| } |
| } |
| public void test_annotations_in_moduleinfo() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "src/org/astro/Foo.java", |
| "package org.astro;\n" + |
| "public @interface Foo {}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "import org.astro.Foo;\n" + |
| "import org.astro.World;\n" + |
| "@Foo\n" + |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_unresolved_annotations() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "src/org/astro/Foo.java", |
| "package org.astro;\n" + |
| "public @interface Foo {}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "import org.astro.Foo;\n" + |
| "import org.astro.World;\n" + |
| "@Foo @Bar\n" + |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Bar cannot be resolved to a type", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_illegal_modifiers() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "src/org/astro/Foo.java", |
| "package org.astro;\n" + |
| "public @interface Foo {}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "import org.astro.Foo;\n" + |
| "import org.astro.World;\n" + |
| "@Foo\n" + |
| "private static module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Illegal modifier for module com.greetings; only open is permitted", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_annotations_with_target() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "src/org/astro/Foo.java", |
| "package org.astro;\n" + |
| "import java.lang.annotation.ElementType;\n" + |
| "import java.lang.annotation.Target;\n" + |
| "@Target(ElementType.MODULE)\n" + |
| "public @interface Foo {}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "import org.astro.Foo;\n" + |
| "import org.astro.World;\n" + |
| "@Foo\n" + |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void test_annotations_with_wrong_target() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "src/org/astro/Foo.java", |
| "package org.astro;\n" + |
| "import java.lang.annotation.ElementType;\n" + |
| "import java.lang.annotation.Target;\n" + |
| "@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE})\n" + |
| "public @interface Foo {}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "import org.astro.Foo;\n" + |
| "import org.astro.World;\n" + |
| "@Foo\n" + |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| " provides World with com.greetings.MyWorld;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "The annotation @Foo is disallowed for this location", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void testBug518334() throws CoreException, IOException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " requires java.sql;\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| waitForAutoBuild(); |
| // set options |
| Map<String, String> options = new HashMap<>(); |
| options.put(CompilerOptions.OPTION_Compliance, "1.8"); |
| options.put(CompilerOptions.OPTION_Source, "1.8"); |
| options.put(CompilerOptions.OPTION_TargetPlatform, "1.8"); |
| p1.setOptions(options); |
| // waitForAutoBuild(); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertTrue("Module declaration incorrectly accepted below 9", markers.length > 0); |
| } finally { |
| deleteProject("org.astro"); |
| } |
| } |
| public void testBug518334a() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath()); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| waitForAutoBuild(); |
| // set options |
| Map<String, String> options = new HashMap<>(); |
| options.put(CompilerOptions.OPTION_Compliance, "1.8"); |
| options.put(CompilerOptions.OPTION_Source, "1.8"); |
| options.put(CompilerOptions.OPTION_TargetPlatform, "1.8"); |
| p1.setOptions(options); |
| |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "org.astro cannot be resolved to a module", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| |
| public void test_api_leak_1() throws CoreException { |
| try { |
| String[] sources1 = { |
| "src/module-info.java", |
| "module mod.one { \n" + |
| " exports pm;\n" + |
| "}", |
| "src/impl/Other.java", |
| "package impl;\n" + |
| "public class Other {\n" + |
| "}\n", |
| "src/pm/C1.java", |
| "package pm;\n" + |
| "import impl.Other;\n" + |
| "public class C1 extends Other {\n" + |
| " public void m1(Other o) {}\n" + |
| "}\n" |
| }; |
| IJavaProject p1 = setupModuleProject("mod.one", sources1); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| String[] sources2 = { |
| "src/module-info.java", |
| "module mod.two { \n" + |
| " requires mod.one;\n" + |
| "}", |
| "src/impl/Other.java", |
| "package impl;\n" + |
| "public class Other {\n" + |
| "}\n", |
| "src/po/Client.java", |
| "package po;\n" + |
| "import pm.C1;\n" + |
| "public class Client {\n" + |
| " void test1(C1 one) {\n" + |
| " one.m1(one);\n" + |
| " }\n" + |
| "}\n" |
| }; |
| IJavaProject p2 = setupModuleProject("mod.two", sources2, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("mod.one"); |
| deleteProject("mod.two"); |
| } |
| } |
| |
| /** |
| * Same-named classes should not conflict, since one is not accessible. |
| * Still a sub class of the inaccessible class can be accessed and used for a method argument. |
| */ |
| public void test_api_leak_2() throws CoreException { |
| try { |
| String[] sources1 = { |
| "src/module-info.java", |
| "module mod.one { \n" + |
| " exports pm;\n" + |
| "}", |
| "src/impl/SomeImpl.java", |
| "package impl;\n" + |
| "public class SomeImpl {\n" + |
| "}\n", |
| "src/pm/C1.java", |
| "package pm;\n" + |
| "import impl.SomeImpl;\n" + |
| "public class C1 {\n" + |
| " public void m1(SomeImpl o) {}\n" + |
| "}\n", |
| "src/pm/Other.java", |
| "package pm;\n" + |
| "import impl.SomeImpl;\n" + |
| "public class Other extends SomeImpl {\n" + |
| "}\n" |
| }; |
| IJavaProject p1 = setupModuleProject("mod.one", sources1); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| String[] sources2 = { |
| "src/module-info.java", |
| "module mod.two { \n" + |
| " requires mod.one;\n" + |
| "}", |
| "src/impl/SomeImpl.java", |
| "package impl;\n" + |
| "public class SomeImpl {\n" + // pseudo-conflict to same named, but inaccessible class from mod.one |
| "}\n", |
| "src/po/Client.java", |
| "package po;\n" + |
| "import pm.C1;\n" + |
| "import pm.Other;\n" + |
| "import impl.SomeImpl;\n" + |
| "public class Client {\n" + |
| " void test1(C1 one) {\n" + |
| " SomeImpl impl = new SomeImpl();\n" + // our own version |
| " one.m1(impl);\n" + // incompatible to what's required |
| " one.m1(new Other());\n" + // OK |
| " }\n" + |
| "}\n", |
| }; |
| String expectedError = "The method m1(impl.SomeImpl) in the type C1 is not applicable for the arguments (impl.SomeImpl)"; |
| IJavaProject p2 = setupModuleProject("mod.two", sources2, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", expectedError, markers); |
| |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", expectedError, markers); |
| } finally { |
| deleteProject("mod.one"); |
| deleteProject("mod.two"); |
| } |
| } |
| |
| public void testNonPublic1() throws CoreException { |
| try { |
| String[] sources1 = { |
| "src/module-info.java", |
| "module mod.one { \n" + |
| " exports pm;\n" + |
| "}", |
| "src/pm/C1.java", |
| "package pm;\n" + |
| "class C1 {\n" + |
| " public void test() {}\n" + |
| "}\n" |
| }; |
| IJavaProject p1 = setupModuleProject("mod.one", sources1); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| String[] sources2 = { |
| "src/module-info.java", |
| "module mod.two { \n" + |
| " requires mod.one;\n" + |
| "}", |
| "src/pm/sub/C2.java", |
| "package pm.sub;\n" + |
| "class C2 {\n" + |
| " public void foo() {}\n" + |
| "}\n", |
| "src/po/Client.java", |
| "package po;\n" + |
| "import pm.*;\n" + // package is exported but type C1 is not public |
| "public class Client {\n" + |
| " void test1(C1 one) {\n" + |
| " one.test();\n" + |
| " }\n" + |
| "}\n" |
| }; |
| |
| IJavaProject p2 = setupModuleProject("mod.two", sources2, new IClasspathEntry[] { dep }); |
| this.workingCopies = new ICompilationUnit[3]; |
| this.workingCopies[0] = getCompilationUnit("/mod.two/src/module-info.java").getWorkingCopy(this.wcOwner, null); |
| this.workingCopies[1] = getCompilationUnit("/mod.two/src/pm/sub/C2.java").getWorkingCopy(this.wcOwner, null); |
| this.problemRequestor.initialize(sources2[5].toCharArray()); |
| this.workingCopies[2] = getCompilationUnit("/mod.two/src/po/Client.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /mod.two/src/po/Client.java (at line 4)\n" + |
| " void test1(C1 one) {\n" + |
| " ^^\n" + |
| "The type C1 is not visible\n" + |
| "----------\n" + |
| "2. ERROR in /mod.two/src/po/Client.java (at line 5)\n" + |
| " one.test();\n" + |
| " ^^^\n" + |
| "The type C1 is not visible\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| String expectedError = "The type C1 is not visible\n" + |
| "The type C1 is not visible"; |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", expectedError, markers); |
| |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", expectedError, markers); |
| } finally { |
| deleteProject("mod.one"); |
| deleteProject("mod.two"); |
| } |
| } |
| // test that two packages with the same name result in conflict if they are both |
| // accessible to a module |
| public void test_conflicting_packages() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module some.mod {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/Test.java", |
| "package org.astro;\n" + |
| "public class Test { }" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires some.mod;\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| // reported against both 'requires' directives & against the import: |
| "The package org.astro is accessible from more than one module: org.astro, some.mod\n" + |
| "The package org.astro is accessible from more than one module: org.astro, some.mod\n" + |
| "The package org.astro is accessible from more than one module: org.astro, some.mod\n" + |
| "World cannot be resolved to a type", |
| markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("some.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| |
| // test that the compilation of a class using same package defined in the java.util module |
| // works if a special option is given |
| public void test_no_conflicting_packages_for_debugger_global() throws CoreException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| try { |
| Hashtable<String, String> newOptions=new Hashtable<>(javaCoreOptions); |
| newOptions.put(CompilerOptions.OPTION_JdtDebugCompileMode, JavaCore.ENABLED); |
| JavaCore.setOptions(newOptions); |
| String[] sources = new String[] { |
| "src/java/util/Map___.java", |
| "package java.util;\n" + |
| "abstract class Map___ implements java.util.Map {\n" + |
| " Map___() {\n" + |
| " super();\n" + |
| " }\n" + |
| " Object[] ___run() throws Throwable {\n" + |
| " return entrySet().toArray();\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| IJavaProject p1= setupModuleProject("debugger_project", sources, new IClasspathEntry[]{dep}); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| |
| assertNull("Option should not be stored", JavaCore.getOption(CompilerOptions.OPTION_JdtDebugCompileMode)); |
| } finally { |
| deleteProject("debugger_project"); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| |
| // test that the special OPTION_JdtDebugCompileMode cannot be persisted on a project |
| public void test_no_conflicting_packages_for_debugger_project() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/java/util/Map___.java", |
| "package java.util;\n" + |
| "abstract class Map___ implements java.util.Map {\n" + |
| " Map___() {\n" + |
| " super();\n" + |
| " }\n" + |
| " Object[] ___run() throws Throwable {\n" + |
| " return entrySet().toArray();\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| IJavaProject p1= setupModuleProject("debugger_project", sources, new IClasspathEntry[]{dep}); |
| p1.setOption(CompilerOptions.OPTION_JdtDebugCompileMode, JavaCore.ENABLED); |
| assertNull("Option should not be stored", p1.getOption(CompilerOptions.OPTION_JdtDebugCompileMode, false)); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The package java.util conflicts with a package accessible from another module: java.base\n" + |
| "The package java.util is accessible from more than one module: <unnamed>, java.base\n" + |
| "The method entrySet() is undefined for the type Map___", |
| markers); |
| } finally { |
| deleteProject("debugger_project"); |
| } |
| } |
| |
| // test that a package declared in a module conflicts with an accessible package |
| // of the same name declared in another required module |
| public void test_conflicting_packages_declaredvsaccessible() throws CoreException { |
| try { |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/org/astro/Test.java", |
| "package org.astro;\n" + |
| "public class Test {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "public class MyWorld implements org.astro.World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The package org.astro conflicts with a package accessible from another module: org.astro\n" + |
| "The package org.astro is accessible from more than one module: com.greetings, org.astro", |
| markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // accessible package bundle.org contains type astro |
| // accessible package bundle.org.astro contains type World |
| // Type bundle.org.astro.World should not be resolved, because type |
| // bundle.org.astro trumps package bundle.org.astro |
| public void test_conflict_packagevstype() throws CoreException { |
| try { |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports bundle.org.astro;\n" + |
| "}", |
| "src/bundle/org/astro/World.java", |
| "package bundle.org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module other.mod {\n" + |
| " exports bundle.org;\n" + |
| "}", |
| "src/bundle/org/astro.java", |
| "package bundle.org;\n" + |
| "public class astro {}" |
| }; |
| setupModuleProject("other.mod", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " requires other.mod;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "public class MyWorld implements bundle.org.astro.World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "bundle.org.astro.World cannot be resolved to a type", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("other.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // package bundle.org contains type astro, but the package is not accessible |
| // accessible package bundle.org.astro contains type World |
| // type bundle.org.astro.World should be resolved because type bundle.org.astro |
| // cannot be seen |
| // TODO - to be confirmed with spec |
| public void test_noconflict_concealedtype_accessiblepackage() throws CoreException { |
| try { |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports bundle.org.astro;\n" + |
| "}", |
| "src/bundle/org/astro/World.java", |
| "package bundle.org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module other.mod {\n" + |
| "}", |
| "src/bundle/org/astro.java", |
| "package bundle.org;\n" + |
| "public class astro {}" |
| }; |
| setupModuleProject("other.mod", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " requires other.mod;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "public class MyWorld implements bundle.org.astro.World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("other.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // test that two packages of the same name exported by two named modules result in |
| // a conflict in the context of a non-modular project |
| public void test_conflicting_packages_unnamed() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module some.mod {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/Test.java", |
| "package org.astro;\n" + |
| "public class Test { }" |
| }; |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| IJavaProject p1 = setupModuleProject("some.mod", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p3 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep1, dep2 }); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The package org.astro is accessible from more than one module: org.astro, some.mod\n" + |
| "World cannot be resolved to a type", |
| markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("some.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // test that a package declared in a non-modular project conflicts with a package with the same name |
| // exported by a named module on it's build path |
| public void test_conflict_unnamed_declaredvsexported() throws CoreException { |
| try { |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/org/astro/Test.java", |
| "package org.astro;\n" + |
| "public class Test {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "public class MyWorld implements org.astro.World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep1 }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The package org.astro conflicts with a package accessible from another module: org.astro\n" + |
| "The package org.astro is accessible from more than one module: <unnamed>, org.astro", |
| markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // test that a type in an accessible package trumps an accessible package with the same name |
| // in the context of a non-modular project |
| public void test_conflict_packagevstype_unnamed() throws CoreException { |
| try { |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports bundle.org.astro;\n" + |
| "}", |
| "src/bundle/org/astro/World.java", |
| "package bundle.org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module other.mod {\n" + |
| " exports bundle.org;\n" + |
| "}", |
| "src/bundle/org/astro.java", |
| "package bundle.org;\n" + |
| "public class astro {}" |
| }; |
| IJavaProject p2 = setupModuleProject("other.mod", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "public class MyWorld implements bundle.org.astro.World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p3 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep1, dep2 }); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "bundle.org.astro.World cannot be resolved to a type", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("other.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // test that a conflicting package does not cause an error when resolving a sub package name |
| // when the sub package is accessible in the context of a non-modular project |
| public void test_noconflict_subpkg_unnamed() throws CoreException { |
| try { |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports bundle.org.astro;\n" + |
| "}", |
| "src/bundle/org/astro/World.java", |
| "package bundle.org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module other.mod {\n" + |
| " exports bundle.org;\n" + |
| "}", |
| "src/bundle/org/astro.java", |
| "package bundle.org;\n" + |
| "public class astro {}" |
| }; |
| IJavaProject p2 = setupModuleProject("other.mod", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/bundle/org/Test.java", |
| "package bundle.org;\n" + |
| "public class Test {}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "public class MyWorld implements bundle.org.astro.World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p3 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep1, dep2 }); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The package bundle.org conflicts with a package accessible from another module: other.mod\n" + |
| "The package bundle.org is accessible from more than one module: <unnamed>, other.mod", |
| markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("other.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| // test that a type in a non-accessible package does not conflict with an accessible package |
| // in the context of a non-modular project |
| public void test_noconflict_concealedtype_accessiblepackage_unnamed() throws CoreException { |
| try { |
| IClasspathEntry dep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports bundle.org.astro;\n" + |
| "}", |
| "src/bundle/org/astro/World.java", |
| "package bundle.org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", sources, new IClasspathEntry[]{dep}); |
| sources = new String[] { |
| "src/module-info.java", |
| "module other.mod {\n" + |
| "}", |
| "src/bundle/org/astro.java", |
| "package bundle.org;\n" + |
| "public class astro {}" |
| }; |
| IJavaProject p2 = setupModuleProject("other.mod", sources, new IClasspathEntry[]{dep}); |
| String[] src = new String[] { |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "public class MyWorld implements bundle.org.astro.World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p3 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep1, dep2 }); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("other.mod"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void testBug512053() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| this.sourceWorkspacePath = super.getSourceWorkspacePath() + java.io.File.separator + "bug512053"; |
| try { |
| setUpJavaProject("bundle.test.a.callable", "9"); |
| setUpJavaProject("bundle.test.a", "9"); |
| setUpJavaProject("bundle.test.b", "9"); |
| setUpJavaProject("jpms.test.a", "9"); |
| setUpJavaProject("jpms.test.b", "9"); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| //assertNoErrors(p2); |
| } finally { |
| this.deleteProject("bundle.test.a.callable"); |
| this.deleteProject("bundle.test.a"); |
| this.deleteProject("bundle.test.b"); |
| this.deleteProject("jpms.test.a"); |
| this.deleteProject("jpms.test.b"); |
| this.sourceWorkspacePath = null; |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| // basic test for automatic modules - external jars |
| public void testBug518280() throws CoreException, IOException { |
| try { |
| String libPath = "externalLib/test.jar"; |
| Util.createJar( |
| new String[] { |
| "test/src/org/astro/World.java", //$NON-NLS-1$ |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| }, |
| null, |
| new HashMap<>(), |
| null, |
| getExternalResourcePath(libPath)); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires test;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null, ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteExternalResource("externalLib"); |
| this.deleteProject("com.greetings"); |
| } |
| } |
| // basic test for automatic modules - workspace jars |
| public void testBug518282() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| try { |
| setUpJavaProject("test_automodules", "9"); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| this.deleteProject("test_automodules"); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| // Only the project using a jar as an automatic module should be able to |
| // resolve one as such |
| public void testBug518282a() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| try { |
| IJavaProject p1 = setUpJavaProject("test_automodules", "9"); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires junit; // This should not be resolved\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/Test.java", |
| "package com.greetings;\n" + |
| "public class Test {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "false"); |
| IClasspathEntry dep = JavaCore.newLibraryEntry(p1.getProject().findMember("lib/junit.jar").getFullPath(), null, null, |
| ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "junit cannot be resolved to a module", markers); |
| } finally { |
| this.deleteProject("test_automodules"); |
| this.deleteProject("com.greetings"); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| // A modular jar on the module path of a project should behave as a regular module and not |
| // as an automatic module |
| public void testBug518282b() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| String libPath = "externalLib/test.jar"; |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/Test.java", |
| "package com.greetings;\n" + |
| "public class Test {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("test", src); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| File rootDir = new File(p1.getProject().findMember("bin").getLocation().toString()); |
| Util.zip(rootDir, getExternalResourcePath(libPath)); |
| src = new String[] { |
| "src/module-info.java", |
| "module test_automodules {\n" + |
| " requires com.greetings;\n" + |
| "}", |
| "src/test/Main.java", |
| "package test;\n" + |
| "import com.greetings.Test;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " System.out.println(new Test().name());\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null, |
| ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p2 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| this.deleteProject("test"); |
| this.deleteProject("test_automodules"); |
| deleteExternalResource(libPath); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| // A modular jar on the class path of a module project - shouldn't be |
| // treated as a module and shouldn't be readable |
| public void testBug518282c() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| String libPath = "externalLib/test.jar"; |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module test {\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/Test.java", |
| "package com.greetings;\n" + |
| "public class Test {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("test", src); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| File rootDir = new File(p1.getProject().findMember("bin").getLocation().toString()); |
| Util.zip(rootDir, getExternalResourcePath(libPath)); |
| src = new String[] { |
| "src/module-info.java", |
| "module test_automodules {\n" + |
| " requires test;\n" + |
| "}", |
| "src/test/Main.java", |
| "package test;\n" + |
| "import com.greetings.Test;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " System.out.println(new Test().name());\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "false"); |
| IClasspathEntry dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null, |
| ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p2 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertTrue("Compilation succeeds unexpectedly", markers.length > 0); |
| } finally { |
| this.deleteProject("test"); |
| this.deleteProject("test_automodules"); |
| deleteExternalResource(libPath); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| // An automatic module grants implied readability to all other automatic modules |
| public void testBug518282d() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| String libPath = "externalLib/test.jar"; |
| try { |
| String[] src = new String[] { |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", src); |
| src = new String[] { |
| "src/org/greetings/Test.java", |
| "package org.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class Test implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath()); |
| IJavaProject p2 = setupModuleProject("test", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| File rootDir = new File(p2.getProject().findMember("bin").getLocation().toString()); |
| Util.zip(rootDir, getExternalResourcePath(libPath)); |
| src = new String[] { |
| "src/module-info.java", |
| "module test_automodules {\n" + |
| " requires test;\n" + |
| "}", |
| "src/test/Main.java", |
| "package test;\n" + |
| "import org.greetings.Test;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " org.astro.World world = new Test();\n" + |
| " System.out.println(world.name());\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null, |
| ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IClasspathEntry dep2 = JavaCore.newLibraryEntry(p1.getProject().findMember("bin").getFullPath(), null, null, |
| ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p3 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep, dep2}); |
| p3.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| this.deleteProject("test"); |
| this.deleteProject("test_automodules"); |
| this.deleteProject("org.astro"); |
| deleteExternalResource(libPath); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| // Automatic module should not allow access to other explicit modules without |
| // requires |
| public void testBug518282e() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| String libPath = "externalLib/test.jar"; |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", src); |
| src = new String[] { |
| "src/com/greetings/Test.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class Test implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath()); |
| IJavaProject p2 = setupModuleProject("test", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| File rootDir = new File(p2.getProject().findMember("bin").getLocation().toString()); |
| Util.zip(rootDir, getExternalResourcePath(libPath)); |
| src = new String[] { |
| "src/module-info.java", |
| "module test_automodules {\n" + |
| " requires test;\n" + |
| "}", |
| "src/test/Main.java", |
| "package test;\n" + |
| "import com.greetings.Test;\n" + |
| "import org.astro.*;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " World world = new Test();\n" + |
| " System.out.println(world.name());\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null, |
| ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p1.getPath(), null, true, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p3 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep, dep2}); |
| p3.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The package org.astro is not accessible\n" + |
| "World cannot be resolved to a type", markers); |
| } finally { |
| this.deleteProject("test"); |
| this.deleteProject("test_automodules"); |
| this.deleteProject("org.astro"); |
| deleteExternalResource(libPath); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| // An automatic module shouldn't allow access to classpath |
| public void testBug518282f() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| String libPath = "externalLib/test.jar"; |
| try { |
| String[] src = new String[] { |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", src); |
| src = new String[] { |
| "src/com/greetings/Test.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class Test implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath()); |
| IJavaProject p2 = setupModuleProject("test", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| File rootDir = new File(p2.getProject().findMember("bin").getLocation().toString()); |
| Util.zip(rootDir, getExternalResourcePath(libPath)); |
| src = new String[] { |
| "src/module-info.java", |
| "module test_automodules {\n" + |
| " requires test;\n" + |
| "}", |
| "src/test/Main.java", |
| "package test;\n" + |
| "import com.greetings.Test;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " org.astro.World world = new Test();\n" + |
| " System.out.println(world.name());\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null, |
| ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| modAttr = new ClasspathAttribute("module", "false"); |
| IClasspathEntry dep2 = JavaCore.newLibraryEntry(p1.getProject().findMember("bin").getFullPath(), null, null, |
| ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p3 = setupModuleProject("test_automodules", src, new IClasspathEntry[] {dep, dep2}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "The project was not built since its build path is incomplete. Cannot find the class file for org.astro.World. Fix the build path then try building this project\n" + |
| "The type org.astro.World cannot be resolved. It is indirectly referenced from required .class files", |
| markers); |
| } finally { |
| this.deleteProject("test"); |
| this.deleteProject("test_automodules"); |
| this.deleteProject("org.astro"); |
| deleteExternalResource(libPath); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| |
| public void testUnnamedModule_bug519674() throws CoreException { |
| try { |
| IJavaProject p1 = createJava9Project("Project1"); |
| createFolder("/Project1/src/pack1"); |
| createFile("/Project1/src/pack1/Class1.java", |
| "package pack1;\n" + |
| "public class Class1 {}\n"); |
| |
| IJavaProject p2 = createJava9Project("Project2"); |
| { |
| IClasspathEntry[] old = p2.getRawClasspath(); |
| IClasspathEntry[] newPath = new IClasspathEntry[old.length + 1]; |
| System.arraycopy(old, 0, newPath, 0, old.length); |
| newPath[old.length] = JavaCore.newProjectEntry(p1.getPath()); |
| p2.setRawClasspath(newPath, null); |
| } |
| createFolder("/Project2/src/pack2"); |
| createFile("/Project2/src/pack2/Class2.java", |
| "package pack2;\n" + |
| "import pack1.Class1;\n" + |
| "public class Class2 extends Class1 {}\n"); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| this.deleteProject("Project1"); |
| this.deleteProject("Project2"); |
| } |
| |
| } |
| public void testBug520246() throws CoreException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module test_automodules {\n" + |
| " requires java.sql;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "import some.pack.Type;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", src); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "The import some cannot be resolved", markers); |
| } finally { |
| this.deleteProject("org.astro"); |
| } |
| |
| } |
| public void testBug520147() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/bundle/org/SomeClass.java", |
| "package bundle.org;\n" + |
| "public class SomeClass {}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", src); |
| src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports bundle.org;\n" + |
| "}", |
| "src/bundle/org/SomeWorld.java", |
| "package bundle.org;\n" + |
| "import org.astro.World;\n" + |
| "public class SomeWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" Some World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| src = new String[] { |
| "src/module-info.java", |
| "module test {\n" + |
| " exports test;\n" + |
| " requires org.astro;\n" + |
| " requires com.greetings;\n" + |
| "}", |
| "src/test/Main.java", |
| "package test;\n" + |
| "import bundle.org.SomeWorld;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " org.astro.World world = new SomeWorld();\n" + |
| " System.out.println(world.name());\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false); |
| IJavaProject p3 = setupModuleProject("test", src, new IClasspathEntry[] {dep, dep2}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| this.deleteProject("test"); |
| this.deleteProject("com.greetings"); |
| this.deleteProject("org.astro"); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| public void testBug520147a() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/bundle/org/SomeClass.java", |
| "package bundle.org;\n" + |
| "public class SomeClass {}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", src); |
| src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports bundle.org;\n" + |
| "}", |
| "src/bundle/org/SomeWorld.java", |
| "package bundle.org;\n" + |
| "import org.astro.World;\n" + |
| "public class SomeWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" Some World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| src = new String[] { |
| "src/module-info.java", |
| "module test {\n" + |
| " exports test;\n" + |
| " requires com.greetings;\n" + |
| "}", |
| "src/test/Main.java", |
| "package test;\n" + |
| "import bundle.org.SomeWorld;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " org.astro.World world = new SomeWorld();\n" + |
| " System.out.println(world.name());\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false); |
| IJavaProject p3 = setupModuleProject("test", src, new IClasspathEntry[] {dep, dep2}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "The type org.astro.World is not accessible", markers); |
| } finally { |
| this.deleteProject("test"); |
| this.deleteProject("com.greetings"); |
| this.deleteProject("org.astro"); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| public void testBug520147b() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| " exports bundle.org to com.greetings;\n" + |
| "}", |
| "src/bundle/org/SomeClass.java", |
| "package bundle.org;\n" + |
| "public class SomeClass {}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", src); |
| src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " exports bundle.org;\n" + |
| "}", |
| "src/bundle/org/SomeWorld.java", |
| "package bundle.org;\n" + |
| "import org.astro.World;\n" + |
| "public class SomeWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" Some World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("markers on com.greetings", |
| "The package bundle.org conflicts with a package accessible from another module: org.astro", |
| markers); |
| |
| src = new String[] { |
| "src/module-info.java", |
| "module test {\n" + |
| " exports test;\n" + |
| " requires org.astro;\n" + |
| " requires com.greetings;\n" + |
| "}", |
| "src/test/Main.java", |
| "package test;\n" + |
| "import bundle.org.SomeWorld;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " org.astro.World world = new SomeWorld();\n" + |
| " System.out.println(world.name());\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false); |
| IJavaProject p3 = setupModuleProject("test", src, new IClasspathEntry[] {dep, dep2}); |
| p3.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| this.deleteProject("test"); |
| this.deleteProject("com.greetings"); |
| this.deleteProject("org.astro"); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| public void testSourceFolders_Bug519673() throws CoreException { |
| try { |
| // Setup project PSources1: |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module PSources1 {\n" + |
| " //exports p.q;\n" + |
| "}", |
| "src2/p/q/SomeClass.java", |
| "package p.q;\n" + |
| "public class SomeClass {}", |
| }; |
| IJavaProject p1 = setupModuleProject("PSources1", new String[] { "src", "src2" }, src, new IClasspathEntry[0]); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| // Edit PSources1/src/module-info.java: |
| String infoSrc = |
| "module PSources1 {\n" + |
| " exports p.q;\n" + |
| "}"; |
| String infoPath = "/PSources1/src/module-info.java"; |
| editFile(infoPath, infoSrc); |
| this.workingCopies = new ICompilationUnit[1]; |
| char[] sourceChars = src[1].toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| this.workingCopies[0] = getCompilationUnit(infoPath).getWorkingCopy(this.wcOwner, null); |
| // was: ERROR: The package pkg does not exist or is empty |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| // Setup project PClient2: |
| String[] src2 = new String[] { |
| "src/module-info.java", |
| "module PClient2 {\n" + |
| " requires PSources1;\n" + |
| "}", |
| "src/x/Client.java", |
| "package x;\n" + |
| "public class Client {\n" + |
| " p.q.SomeClass f;\n" + |
| "\n}", |
| }; |
| setupModuleProject("PClient2", src2); |
| getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| |
| // Edit PClient2/src/module-info.java: |
| // was NPE in ModuleBinding.canAccess() |
| char[] info2Chars = src2[2].toCharArray(); |
| this.problemRequestor.initialize(info2Chars); |
| this.workingCopies[0] = getCompilationUnit("PClient2/src/module-info.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| // Failed attempt to trigger NPE in ModuleBinding.isPackageExportedTo() by editing Client.java |
| char[] source2Chars = src2[3].toCharArray(); |
| this.problemRequestor.initialize(source2Chars); |
| this.workingCopies[0] = getCompilationUnit("PClient2/src/x/Client.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject("PSources1"); |
| deleteProject("PClient2"); |
| } |
| } |
| public void testPrivateMethod_Bug515985() throws CoreException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module mod.one { \n" + |
| " exports pm;\n" + |
| "}", |
| "src/impl/Other.java", |
| "package impl;\n" + |
| "public class Other {\n" + |
| " public void privateMethod() {}" + |
| "}\n", |
| "src/pm/C1.java", |
| "package pm;\n" + |
| "import impl.Other;\n" + |
| "public class C1 extends Other {\n" + |
| "}\n" |
| }; |
| IJavaProject p1 = setupModuleProject("mod.one", src); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| String[] src2 = new String[] { |
| "src/module-info.java", |
| "module mod.two { \n" + |
| " requires mod.one;\n" + |
| "}", |
| "src/po/Client.java", |
| "package po;\n" + |
| "import pm.C1;\n" + |
| "public class Client {\n" + |
| " void test1(C1 one) {\n" + |
| " one.privateMethod(); // ecj: The method privateMethod() is undefined for the type C1\n" + |
| " }\n" + |
| "}\n" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false); |
| IJavaProject p2 = setupModuleProject("mod.two", src2, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("mod.one"); |
| deleteProject("mod.two"); |
| } |
| } |
| public void testAddExports() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module morg.astro {\n" + |
| // " exports org.astro to com.greetings;\n" + // this export will be added via add-exports |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("morg.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathAttribute addExports = new ClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "morg.astro/org.astro=com.greetings"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr, addExports}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires morg.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("morg.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void testAddExports2() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module morg.astro {\n" + |
| // " exports org.astro to com.greetings;\n" + // this export will be added via add-exports |
| // " exports org.eclipse to com.greetings;\n" + // this export will be added via add-exports |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| "src/org/eclipse/Planet.java", |
| "package org.eclipse;\n" + |
| "public class Planet {}\n" |
| }; |
| IJavaProject p1 = setupModuleProject("morg.astro", sources); |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathAttribute addExports = new ClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, |
| "morg.astro/org.astro=com.greetings:morg.astro/org.eclipse=com.greetings"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {modAttr, addExports}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires morg.astro;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld implements World {\n" + |
| " org.eclipse.Planet planet;\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("morg.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void testAddReads() throws CoreException, IOException { |
| try { |
| // org.astro defines the "real" org.astro.World: |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p = setupModuleProject("org.astro", sources); |
| |
| // build mod.one with a private copy of org.astro.World: |
| String[] src1 = new String[] { |
| "src/module-info.java", |
| "module mod.one {\n" + |
| " exports one.p;\n" + |
| "}\n", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World { public String name(); }\n", |
| "src/one/p/C.java", |
| "package one.p;\n" + |
| "public class C {\n" + |
| " public void test(org.astro.World w) {\n" + |
| " System.out.println(w.name());\n" + |
| " }\n" + |
| "}\n" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p.getPath(), null, false, |
| new IClasspathAttribute[] { modAttr }, |
| false/*not exported*/); |
| IJavaProject p1 = setupModuleProject("mod.one", src1, new IClasspathEntry[] { dep }); |
| p1.setOption(JavaCore.COMPILER_PB_API_LEAKS, JavaCore.IGNORE); // the stub org.astro.World is not exported but used in API |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| |
| // jar-up without the private copy: |
| deleteFile("/mod.one/src/org/astro/World.java"); |
| deleteFile("/mod.one/bin/org/astro/World.class"); |
| String modOneJarPath = getWorkspacePath()+File.separator+"mod.one.jar"; |
| Util.zip(new File(getWorkspacePath()+"/mod.one/bin"), modOneJarPath); |
| |
| // com.greetings depends on both other modules: |
| String[] src2 = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires org.astro;\n" + |
| " requires mod.one;\n" + |
| "}", |
| "src/com/greetings/MyTest.java", |
| "package com.greetings;\n" + |
| "public class MyTest {\n" + |
| " public void test(one.p.C c, org.astro.World w) {\n" + |
| " c.test(w);\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep1 = JavaCore.newProjectEntry(p.getPath(), null, false, |
| new IClasspathAttribute[] {new ClasspathAttribute("module", "true")}, |
| false/*not exported*/); |
| // need to re-wire dependency mod.one -> org.astro for resolving one.p.C: |
| IClasspathEntry dep2 = JavaCore.newLibraryEntry(new Path(modOneJarPath), null, null, null, |
| new IClasspathAttribute[] { |
| new ClasspathAttribute("module", "true"), |
| new ClasspathAttribute(IClasspathAttribute.ADD_READS, "mod.one=org.astro") |
| }, |
| false/*not exported*/); |
| IJavaProject p2 = setupModuleProject("com.greetings", src2, new IClasspathEntry[] { dep1, dep2 }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| |
| // check that reconcile respects --add-reads, too: |
| this.problemRequestor.reset(); |
| ICompilationUnit cu = getCompilationUnit("/com.greetings/src/com/greetings/MyTest.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| } finally { |
| deleteProject("mod.one"); |
| deleteProject("org.astro"); |
| deleteProject("com.greetings"); |
| } |
| } |
| public void testBug520147c() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", src); |
| src = new String[] { |
| "src/org/eclipse/pack1/SomeWorld.java", |
| "package org.eclipse.pack1;\n" + |
| "import org.astro.World;\n" + |
| "public class SomeWorld implements World {\n" + |
| " public String name() {\n" + |
| " return \" Some World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| src = new String[] { |
| "src/module-info.java", |
| "module test {\n" + |
| " exports test;\n" + |
| " requires com.greetings;\n" + |
| " requires org.astro;\n" + |
| "}", |
| "src/test/Main.java", |
| "package test;\n" + |
| "import org.eclipse.pack1.SomeWorld;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " org.astro.World world = new SomeWorld();\n" + |
| " System.out.println(world.name());\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, new IClasspathAttribute[] {modAttr}, false); |
| IJavaProject p3 = setupModuleProject("test", src, new IClasspathEntry[] {dep, dep2}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p3.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Name of automatic module \'com.greetings\' is unstable, it is derived from the module\'s file name.", |
| markers); |
| } finally { |
| this.deleteProject("test"); |
| this.deleteProject("com.greetings"); |
| this.deleteProject("org.astro"); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| @Deprecated |
| public void testBug519935() throws CoreException, IOException { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("org.astro", src); |
| src = new String[] { |
| "src/org/eclipse/pack/Test.java", |
| "package org.eclipse.pack;\n" + |
| "import org.astro.World;\n" + |
| "public class Test implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath()); |
| IJavaProject p2 = setupModuleProject("test", src, new IClasspathEntry[] {dep}); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| src = new String[] { |
| "src/module-info.java", |
| "module test_automodules {\n" + |
| " requires bin;\n" + |
| " requires org.astro;\n" + |
| "}", |
| "src/test/Main.java", |
| "package test;\n" + |
| "import org.eclipse.pack.Test;\n" + |
| "import org.astro.*;\n" + |
| "public class Main {\n" + |
| " public static void main(String[] args) {\n" + |
| " World world = new Test();\n" + |
| " System.out.println(world.name());\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| dep = JavaCore.newLibraryEntry(p2.getProject().findMember("bin").getFullPath(), null, null, |
| ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p1.getPath(), null, true, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| setupModuleProject("testSOE", src, new IClasspathEntry[] {dep, dep2}); |
| this.workingCopies = new ICompilationUnit[1]; |
| this.workingCopies[0] = getCompilationUnit("/testSOE/src/test/Main.java").getWorkingCopy(this.wcOwner, null); |
| this.problemRequestor.initialize(src[3].toCharArray()); |
| CompilationUnit unit = this.workingCopies[0].reconcile(AST.JLS9, true, this.wcOwner, null); |
| assertNotNull("Could not reconcile", unit); |
| } finally { |
| this.deleteProject("test"); |
| this.deleteProject("testSOE"); |
| this.deleteProject("org.astro"); |
| JavaCore.setOptions(javaCoreOptions); |
| } |
| } |
| @Deprecated |
| public void testBug520310() throws CoreException, IOException { |
| try { |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module mod.one {\n" + |
| // " requires mod.two;\n" + |
| " exports org.astro;\n" + |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}" |
| }; |
| IClasspathEntry modDep = JavaCore.newContainerEntry(new Path(JavaCore.MODULE_PATH_CONTAINER_ID)); |
| IJavaProject p1 = setupModuleProject("mod.one", src, new IClasspathEntry[] {modDep}); |
| |
| src = new String[] { |
| "src/module-info.java", |
| "module mod.two {\n" + |
| " requires mod.one;\n" + |
| " exports test;\n" + |
| "}", |
| "src/test/Test.java", |
| "package test;\n" + |
| "import org.astro.World;\n" + |
| "public class Test implements World {\n" + |
| " public String name() {\n" + |
| " return \" My World!!\";\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("mod.two", src, new IClasspathEntry[] {modDep}); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers in mod.one", "", markers); |
| markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers in mod.two", "", markers); |
| |
| editFile("/mod.one/src/module-info.java", |
| "module mod.one {\n" + |
| " requires mod.two;\n" + // added |
| " exports org.astro;\n" + |
| "}"); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); // modules see each other only on 2nd attempt, don't ask me... |
| markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers in mod.one", |
| "Cycle exists in module dependencies, Module mod.one requires itself via mod.two", |
| markers); |
| markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers in mod.two", |
| "The type org.astro.World is not accessible\n" + // cannot use cyclic requires |
| "Cycle exists in module dependencies, Module mod.two requires itself via mod.one\n" + |
| "World cannot be resolved to a type", |
| markers); |
| |
| this.workingCopies = new ICompilationUnit[1]; |
| this.workingCopies[0] = getCompilationUnit("/mod.two/src/module-info.java").getWorkingCopy(this.wcOwner, null); |
| this.problemRequestor.initialize(src[1].toCharArray()); |
| CompilationUnit unit = this.workingCopies[0].reconcile(AST.JLS9, true, this.wcOwner, null); |
| assertNotNull("Could not reconcile", unit); |
| } finally { |
| this.deleteProject("mod.one"); |
| this.deleteProject("mod.two"); |
| } |
| } |
| public void testBug521346() throws CoreException, IOException { |
| IJavaProject javaProject = null; |
| try { |
| String src = |
| "import java.*;\n" + |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " System.out.println(true);\n" + |
| " }\n" + |
| "}"; |
| javaProject = createJava9Project("Test"); |
| this.problemRequestor.initialize(src.toCharArray()); |
| getWorkingCopy("/Test/src/X.java", src, true); |
| assertProblems("should have not problems", |
| "----------\n" + |
| "1. ERROR in /Test/src/X.java (at line 1)\n" + |
| " import java.*;\n" + |
| " ^^^^\n" + |
| "The package java is not accessible\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| if (javaProject != null) |
| deleteProject(javaProject); |
| } |
| } |
| public void testAutoModule1() throws Exception { |
| IJavaProject javaProject = null; |
| try { |
| String[] sources = { |
| "p/a/X.java", |
| "package p.a;\n" + |
| "public class X {}\n;" |
| }; |
| String outputDirectory = Util.getOutputDirectory(); |
| |
| String jarPath = outputDirectory + File.separator + "lib-x.jar"; |
| Util.createJar(sources, jarPath, "1.8"); |
| |
| javaProject = createJava9Project("mod.one", new String[] {"src"}); |
| IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| addClasspathEntry(javaProject, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false)); |
| |
| String srcMod = |
| "module mod.one { \n" + |
| " requires lib.x;\n" + // lib.x is derived from lib-x.jar |
| "}"; |
| createFile("/mod.one/src/module-info.java", |
| srcMod); |
| createFolder("mod.one/src/q"); |
| String srcX = |
| "package q;\n" + |
| "public class X {\n" + |
| " p.a.X f;\n" + |
| "}"; |
| createFile("/mod.one/src/q/X.java", srcX); |
| |
| this.problemRequestor.initialize(srcMod.toCharArray()); |
| getWorkingCopy("/mod.one/module-info.java", srcMod, true); |
| assertProblems("module-info should have one warning", |
| "----------\n" + |
| "1. WARNING in /mod.one/module-info.java (at line 2)\n" + |
| " requires lib.x;\n" + |
| " ^^^^^\n" + |
| "Name of automatic module \'lib.x\' is unstable, it is derived from the module\'s file name.\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.initialize(srcX.toCharArray()); |
| getWorkingCopy("/mod.one/src/q/X.java", srcX, true); |
| assertProblems("X should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| if (javaProject != null) |
| deleteProject(javaProject); |
| } |
| } |
| public void testAutoModule2() throws Exception { |
| IJavaProject javaProject = null; |
| try { |
| String[] sources = { |
| "p/a/X.java", |
| "package p.a;\n" + |
| "public class X {}\n;", |
| }; |
| String[] mfSource = { |
| "META-INF/MANIFEST.MF", |
| "Manifest-Version: 1.0\n" + |
| "Automatic-Module-Name: org.eclipse.lib.x\n" |
| }; |
| String outputDirectory = Util.getOutputDirectory(); |
| |
| String jarPath = outputDirectory + File.separator + "lib-x.jar"; |
| Util.createJar(sources, mfSource, jarPath, "1.8"); |
| |
| javaProject = createJava9Project("mod.one", new String[] {"src"}); |
| IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| addClasspathEntry(javaProject, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false)); |
| |
| String srcMod = |
| "module mod.one { \n" + |
| " requires org.eclipse.lib.x;\n" + // from jar attribute |
| "}"; |
| createFile("/mod.one/src/module-info.java", |
| srcMod); |
| createFolder("mod.one/src/q"); |
| String srcX = |
| "package q;\n" + |
| "public class X {\n" + |
| " p.a.X f;\n" + |
| "}"; |
| createFile("/mod.one/src/q/X.java", srcX); |
| |
| this.problemRequestor.initialize(srcMod.toCharArray()); |
| getWorkingCopy("/mod.one/module-info.java", srcMod, true); |
| assertProblems("module-info should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.initialize(srcX.toCharArray()); |
| getWorkingCopy("/mod.one/src/q/X.java", srcX, true); |
| assertProblems("X should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| if (javaProject != null) |
| deleteProject(javaProject); |
| } |
| } |
| public void testAutoModule3() throws Exception { |
| IJavaProject javaProject = null, auto = null; |
| try { |
| auto = createJava9Project("auto", new String[] {"src"}); |
| createFolder("auto/src/p/a"); |
| createFile("auto/src/p/a/X.java", |
| "package p.a;\n" + |
| "public class X {}\n;"); |
| createFolder("auto/META-INF"); |
| createFile("auto/META-INF/MANIFEST.MF", |
| "Manifest-Version: 1.0\n" + |
| "Automatic-Module-Name: org.eclipse.lib.x\n"); |
| |
| javaProject = createJava9Project("mod.one", new String[] {"src"}); |
| IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| addClasspathEntry(javaProject, JavaCore.newProjectEntry(auto.getPath(), null, false, attributes, false)); |
| |
| String srcMod = |
| "module mod.one { \n" + |
| " requires org.eclipse.lib.x;\n" + // from manifest attribute |
| "}"; |
| createFile("/mod.one/src/module-info.java", |
| srcMod); |
| createFolder("mod.one/src/q"); |
| String srcX = |
| "package q;\n" + |
| "public class X {\n" + |
| " p.a.X f;\n" + |
| "}"; |
| createFile("/mod.one/src/q/X.java", srcX); |
| auto.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| this.problemRequestor.initialize(srcMod.toCharArray()); |
| getWorkingCopy("/mod.one/module-info.java", srcMod, true); |
| assertProblems("module-info should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.initialize(srcX.toCharArray()); |
| getWorkingCopy("/mod.one/src/q/X.java", srcX, true); |
| assertProblems("X should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| if (javaProject != null) |
| deleteProject(javaProject); |
| if (auto != null) |
| deleteProject(auto); |
| } |
| } |
| |
| public void testAutoModule4() throws Exception { |
| IJavaProject javaProject = null; |
| IJavaProject javaProject2 = null; |
| try { |
| // auto module as jar: |
| String[] sources = { |
| "p/a/X.java", |
| "package p.a;\n" + |
| "public class X {}\n;", |
| }; |
| String[] mfSource = { |
| "META-INF/MANIFEST.MF", |
| "Manifest-Version: 1.0\n" + |
| "Automatic-Module-Name: org.eclipse.lib.x\n" // automatic module reads all (incl. mod.one below) |
| }; |
| String outputDirectory = Util.getOutputDirectory(); |
| |
| String jarPath = outputDirectory + File.separator + "lib-x.jar"; |
| Util.createJar(sources, mfSource, jarPath, "1.8"); |
| |
| // first source module: |
| javaProject = createJava9Project("mod.one", new String[] {"src"}); |
| IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| addClasspathEntry(javaProject, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false)); |
| |
| String srcMod = |
| "module mod.one { \n" + |
| " requires org.eclipse.lib.x;\n" + // creates cycle mod.one -> org.eclipse.lib.x -> mod.one |
| " exports p.q.api;\n" + |
| "}"; |
| createFile("/mod.one/src/module-info.java", srcMod); |
| createFolder("mod.one/src/p/q/api"); |
| String srcX = |
| "package p.q.api;\n" + |
| "public class X {\n" + |
| " p.a.X f;\n" + |
| "}"; |
| createFile("/mod.one/src/p/q/api/X.java", srcX); |
| |
| // second source module: |
| javaProject2 = createJava9Project("mod.two", new String[] {"src"}); |
| addClasspathEntry(javaProject2, JavaCore.newProjectEntry(new Path("/mod.one"), null, false, attributes, false)); |
| addClasspathEntry(javaProject2, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false)); |
| String srcMod2 = |
| "module mod.two { \n" + |
| " requires mod.one;\n" + |
| "}"; |
| createFile("/mod.two/src/module-info.java", srcMod2); |
| createFolder("mod.two/src/p/q"); |
| String srcY = |
| "package p.q;\n" + |
| "import p.q.api.X;\n" + // here we saw "The package p.q.api is accessible from more than one module: mod.one, mod.one" |
| "public class Y {\n" + |
| " X f;\n" + |
| "}"; |
| createFile("/mod.two/src/p/q/Y.java", srcY); |
| |
| this.problemRequestor.initialize(srcMod.toCharArray()); |
| getWorkingCopy("/mod.one/module-info.java", srcMod, true); |
| assertProblems("module-info should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.initialize(srcX.toCharArray()); |
| getWorkingCopy("/mod.one/src/p/q/api/X.java", srcX, true); |
| assertProblems("X should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.initialize(srcY.toCharArray()); |
| getWorkingCopy("/mod.two/src/p/q/Y.java", srcY, true); |
| assertProblems("Y should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertMarkers("markers in mod.one", "", javaProject); |
| |
| javaProject2.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertMarkers("markers in mod.two", "", javaProject2); |
| |
| javaProject.getProject().getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| if (javaProject != null) |
| deleteProject(javaProject); |
| if (javaProject2 != null) |
| deleteProject(javaProject2); |
| } |
| } |
| // like testAutoModule3 without name derived from project, not manifest - warning suppressed |
| public void testAutoModule5() throws Exception { |
| IJavaProject javaProject = null, auto = null; |
| try { |
| auto = createJava9Project("auto", new String[] {"src"}); |
| createFolder("auto/src/p/a"); |
| createFile("auto/src/p/a/X.java", |
| "package p.a;\n" + |
| "public class X {}\n;"); |
| |
| javaProject = createJava9Project("mod.one", new String[] {"src"}); |
| IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| addClasspathEntry(javaProject, JavaCore.newProjectEntry(auto.getPath(), null, false, attributes, false)); |
| |
| String srcMod = |
| "@SuppressWarnings(\"module\")\n" + |
| "module mod.one { \n" + |
| " requires auto;\n" + |
| "}"; |
| createFile("/mod.one/src/module-info.java", |
| srcMod); |
| createFolder("mod.one/src/q"); |
| String srcX = |
| "package q;\n" + |
| "public class X {\n" + |
| " p.a.X f;\n" + |
| "}"; |
| createFile("/mod.one/src/q/X.java", srcX); |
| auto.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| this.problemRequestor.initialize(srcMod.toCharArray()); |
| getWorkingCopy("/mod.one/module-info.java", srcMod, true); |
| assertProblems("module-info should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.initialize(srcX.toCharArray()); |
| getWorkingCopy("/mod.one/src/q/X.java", srcX, true); |
| assertProblems("X should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| if (javaProject != null) |
| deleteProject(javaProject); |
| if (auto != null) |
| deleteProject(auto); |
| } |
| } |
| // like testAutoModule5, warning configured as ERROR |
| public void testAutoModule6() throws Exception { |
| IJavaProject javaProject = null, auto = null; |
| try { |
| auto = createJava9Project("auto", new String[] {"src"}); |
| createFolder("auto/src/p/a"); |
| createFile("auto/src/p/a/X.java", |
| "package p.a;\n" + |
| "public class X {}\n;"); |
| |
| javaProject = createJava9Project("mod.one", new String[] {"src"}); |
| IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| addClasspathEntry(javaProject, JavaCore.newProjectEntry(auto.getPath(), null, false, attributes, false)); |
| javaProject.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.ERROR); |
| |
| String srcMod = |
| "module mod.one { \n" + |
| " requires auto;\n" + |
| "}"; |
| createFile("/mod.one/src/module-info.java", |
| srcMod); |
| auto.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| this.problemRequestor.initialize(srcMod.toCharArray()); |
| getWorkingCopy("/mod.one/module-info.java", srcMod, true); |
| assertProblems("module-info should have only one error", |
| "----------\n" + |
| "1. ERROR in /mod.one/module-info.java (at line 2)\n" + |
| " requires auto;\n" + |
| " ^^^^\n" + |
| "Name of automatic module \'auto\' is unstable, it is derived from the module\'s file name.\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| if (javaProject != null) |
| deleteProject(javaProject); |
| if (auto != null) |
| deleteProject(auto); |
| } |
| } |
| |
| // patch can see unexported type from host (and package accessible method), but not vice versa |
| public void testPatch1() throws CoreException, IOException { |
| try { |
| IJavaProject mainProject = createJava9Project("org.astro"); |
| String[] sources = { |
| "src/module-info.java", |
| "module org.astro {\n" + // no exports |
| "}", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "public class World {\n" + |
| " public String name() { return \"world\"; }\n" + |
| " void internalTest() { }\n" + |
| " public org.astro.test.WorldTest test;\n" + |
| "}", |
| }; |
| createSourceFiles(mainProject, sources); |
| |
| IJavaProject patchProject = createJava9Project("org.astro.patch"); |
| IClasspathAttribute[] attributes = { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"), |
| JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "org.astro") |
| }; |
| addClasspathEntry(patchProject, JavaCore.newProjectEntry(new Path("/org.astro"), null, false, attributes, false)); |
| String[] patchSources = { |
| "src/org/astro/test/WorldTest.java", |
| "package org.astro.test;\n" + |
| "import org.astro.*;\n" + |
| "public class WorldTest {\n" + |
| " void testWorld(World w) {\n" + |
| " w.name();\n" + |
| " }\n" + |
| "}\n", |
| "src/org/astro/Test2.java", |
| "package org.astro;\n" + |
| "class Test2 {\n" + |
| " void test(World w) {\n" + |
| " w.internalTest();\n" + // package access |
| " }\n" + |
| "}\n" |
| }; |
| createSourceFiles(patchProject, patchSources); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = mainProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "org.astro.test cannot be resolved to a type", // missing reverse dependency |
| markers); |
| |
| this.problemRequestor.reset(); |
| ICompilationUnit cu = getCompilationUnit("/org.astro.patch/src/org/astro/test/WorldTest.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.reset(); |
| cu = getCompilationUnit("/org.astro/src/org/astro/World.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /org.astro/src/org/astro/World.java\n" + |
| "org.astro.test cannot be resolved to a type\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| } finally { |
| this.deleteProject("org.astro"); |
| this.deleteProject("org.astro.patch"); |
| } |
| } |
| |
| // patch can see unexported type from host - JRE patched from two source folders |
| public void testPatch2() throws CoreException, IOException { |
| try { |
| IClasspathAttribute[] attributes = { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"), |
| JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "java.desktop=/missing.path::java.base=/org.astro.patch/src:/org.astro.patch/src2") |
| }; |
| IJavaProject patchProject = createJava9ProjectWithJREAttributes("org.astro.patch", new String[]{"src", "src2"}, attributes); |
| |
| String[] patchSources = { |
| "src/org/astro/Test2.java", |
| "package org.astro;\n" + |
| "class Test2 {\n" + |
| " int test(jdk.internal.misc.Unsafe unsafe) {\n" + |
| " return unsafe.addressSize();\n" + |
| " }\n" + |
| "}\n", |
| "src2/jdk/internal/misc/Test3.java", |
| "package jdk.internal.misc;\n" + |
| "class Test3 {\n" + |
| " Signal.NativeHandler handler;\n" + // package access |
| "}\n" |
| }; |
| createSourceFiles(patchProject, patchSources); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| |
| this.problemRequestor.reset(); |
| ICompilationUnit cu = getCompilationUnit("/org.astro.patch/src/org/astro/Test2.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| } finally { |
| this.deleteProject("org.astro.patch"); |
| } |
| } |
| |
| // patch can share a package with its host - jar |
| public void testPatch3() throws CoreException, IOException { |
| try { |
| String[] sources = { |
| "p/a/X.java", |
| "package p.a;\n" + |
| "class X {}\n;", // package access |
| "module-info.java", |
| "module mod.one {\n" + // no exports |
| "}\n" |
| }; |
| String outputDirectory = Util.getOutputDirectory(); |
| |
| String jarPath = outputDirectory + File.separator + "mod-one.jar"; |
| Util.createJar(sources, jarPath, "9"); |
| |
| IJavaProject patchProject = createJava9Project("mod.one.patch"); |
| IClasspathAttribute[] attributes = { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"), |
| JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "mod.one=/mod.one.patch") |
| }; |
| addClasspathEntry(patchProject, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false)); |
| |
| String[] patchSources = { |
| "src/p/a/Test2.java", |
| "package p.a;\n" + |
| "class Test2 extends X {\n" + |
| "}\n" |
| }; |
| createSourceFiles(patchProject, patchSources); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| |
| this.problemRequestor.reset(); |
| ICompilationUnit cu = getCompilationUnit("/mod.one.patch/src/p/a/Test2.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| } finally { |
| this.deleteProject("mod.one.patch"); |
| } |
| } |
| public void testLimitModules1() throws CoreException, IOException { |
| try { |
| IClasspathAttribute[] attributes = { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"), |
| JavaCore.newClasspathAttribute(IClasspathAttribute.LIMIT_MODULES, "java.base,java.desktop") |
| }; |
| IJavaProject project = createJava9ProjectWithJREAttributes("org.astro", new String[]{"src", "src2"}, attributes); |
| |
| String[] sources = { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " requires java.base;\n" + |
| " requires java.desktop;\n" + |
| " requires java.datatransfer;\n" + // within the closure of java.desktop |
| " requires java.sql;\n" + // not included |
| "}\n", |
| "src/org/astro/Test2.java", |
| "package org.astro;\n" + |
| "class Test2 {\n" + |
| " java.awt.Window window;\n" + |
| "}\n", |
| "src2/org/astro/Test3.java", |
| "package org.astro;\n" + |
| "class Test3 {\n" + |
| " java.awt.datatransfer.Clipboard clippy;\n" + |
| "}\n" |
| }; |
| createSourceFiles(project, sources); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "java.sql cannot be resolved to a module", // outside limited scope |
| markers); |
| |
| this.problemRequestor.reset(); |
| ICompilationUnit cu = getCompilationUnit("/org.astro/src/module-info.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /org.astro/src/module-info.java\n" + |
| "java.sql cannot be resolved to a module\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.reset(); |
| cu = getCompilationUnit("/org.astro/src/org/astro/Test2.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.reset(); |
| cu = getCompilationUnit("/org.astro/src/org/astro/Test3.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| } finally { |
| this.deleteProject("org.astro"); |
| } |
| } |
| public void testLimitModules2() throws CoreException, IOException { |
| try { |
| IClasspathAttribute[] attributes = { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"), |
| JavaCore.newClasspathAttribute(IClasspathAttribute.LIMIT_MODULES, "java.se") // test transitive closure |
| }; |
| IJavaProject project = createJava9ProjectWithJREAttributes("org.astro", new String[]{"src", "src2"}, attributes); |
| |
| String[] sources = { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " requires java.base;\n" + |
| " requires java.desktop;\n" + |
| " requires java.datatransfer;\n" + |
| " requires java.sql;\n" + |
| "}\n", |
| "src/org/astro/Test2.java", |
| "package org.astro;\n" + |
| "class Test2 {\n" + |
| " java.awt.Window window;\n" + |
| "}\n", |
| "src2/org/astro/Test3.java", |
| "package org.astro;\n" + |
| "class Test3 {\n" + |
| " java.awt.datatransfer.Clipboard clippy;\n" + |
| "}\n" |
| }; |
| createSourceFiles(project, sources); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "", |
| markers); |
| |
| this.problemRequestor.reset(); |
| ICompilationUnit cu = getCompilationUnit("/org.astro/src/module-info.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.reset(); |
| cu = getCompilationUnit("/org.astro/src/org/astro/Test2.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.reset(); |
| cu = getCompilationUnit("/org.astro/src/org/astro/Test3.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| } finally { |
| this.deleteProject("org.astro"); |
| } |
| } |
| public void testDefaultRootModules() throws CoreException, IOException { |
| try { |
| |
| IJavaProject project = createJava9Project("org.astro", new String[]{"src"}); |
| |
| String[] sources = { |
| "src/org/astro/ProblemWithPostConstruct.java", |
| "package org.astro;\n" + |
| "import javax.annotation.PostConstruct;\n" + |
| "\n" + |
| "public class ProblemWithPostConstruct {\n" + |
| " @PostConstruct void init() {}\n" + |
| "}\n" |
| }; |
| createSourceFiles(project, sources); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The import javax.annotation.PostConstruct cannot be resolved\n" + |
| "PostConstruct cannot be resolved to a type", // not in default root modules: java.xml.ws.annotation |
| markers); |
| |
| this.problemRequestor.reset(); |
| ICompilationUnit cu = getCompilationUnit("/org.astro/src/org/astro/ProblemWithPostConstruct.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /org.astro/src/org/astro/ProblemWithPostConstruct.java\n" + |
| "The import javax.annotation.PostConstruct cannot be resolved\n" + |
| "----------\n" + |
| "2. ERROR in /org.astro/src/org/astro/ProblemWithPostConstruct.java\n" + |
| "PostConstruct cannot be resolved to a type\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| this.deleteProject("org.astro"); |
| } |
| } |
| public void testBug522398() throws CoreException { |
| try { |
| |
| String[] sources = new String[] { |
| "src/javax/xml/mysubpackage/MyClass.java", |
| "package javax.xml.mysubpackage;\n" + |
| "\n" + |
| "public class MyClass {\n" + |
| "}\n" + |
| "\n" + |
| "", |
| "src/nonmodular/UsesMySubPackage.java", |
| "package nonmodular;\n" + |
| "\n" + |
| "import javax.xml.mysubpackage.MyClass;\n" + |
| "\n" + |
| "public class UsesMySubPackage {\n" + |
| " public MyClass field;\n" + |
| "}\n" + |
| "", |
| }; |
| IJavaProject p1 = setupModuleProject("nonmodular1", sources); |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/nonmodular2/Problem.java", |
| "package nonmodular2;\n" + |
| "\n" + |
| "import javax.xml.XMLConstants;\n" + |
| "\n" + |
| "import nonmodular.UsesMySubPackage;\n" + |
| "\n" + |
| "public class Problem extends nonmodular.UsesMySubPackage {\n" + |
| " String s = XMLConstants.NULL_NS_URI;\n" + |
| "}\n" + |
| "", |
| }; |
| IJavaProject p2 = setupModuleProject("nonmodular2", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| deleteProject("nonmodular1"); |
| deleteProject("nonmodular2"); |
| } |
| } |
| public void testBug522330() throws CoreException, IOException { |
| try { |
| String[] sources = new String[] { |
| "src/javax/net/ServerSocketFactory1.java", |
| "package javax.net;\n" + |
| "\n" + |
| "public class ServerSocketFactory1 {\n" + |
| "}\n" + |
| "\n" + |
| "", |
| }; |
| IJavaProject p1 = setupModuleProject("nonmodular1", sources); |
| p1.setOption(JavaCore.COMPILER_COMPLIANCE, "1.8"); // compile with 1.8 compliance to avoid error about package conflict |
| |
| IClasspathEntry dep = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/nonmodular2/Problem.java", |
| "package nonmodular2;\n" + |
| "\n" + |
| "import javax.net.ServerSocketFactory;\n" + |
| "\n" + |
| "public class Problem {\n" + |
| " Object o = ServerSocketFactory.getDefault();\n" + |
| "} \n" + |
| "", |
| }; |
| IJavaProject p2 = setupModuleProject("nonmodular2", src, new IClasspathEntry[] { dep }); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("unexpected markers", |
| "The package javax.net is accessible from more than one module: <unnamed>, java.base\n" + |
| "ServerSocketFactory cannot be resolved", |
| markers); |
| } finally { |
| deleteProject("nonmodular1"); |
| deleteProject("nonmodular2"); |
| } |
| } |
| |
| public void testBug522503() throws Exception { |
| try { |
| IJavaProject p1 = setupModuleProject("mod.one", |
| new String[] { |
| "src/module-info.java", |
| "module mod.one {\n" + |
| " exports p1;\n" + |
| "}\n", |
| "src/p1/API.java", |
| "package p1;\n" + |
| "public class API {}\n" |
| }); |
| IClasspathAttribute[] attr = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| IClasspathEntry[] deps = { JavaCore.newLibraryEntry(p1.getOutputLocation(), null, null, null, attr, false) }; |
| String[] sources2 = new String[] { |
| "src/module-info.java", |
| "module mod.two {\n" + |
| " requires mod.one;\n" + |
| "}\n", |
| "src/client/Client.java", |
| "package client;\n" + |
| "import p1.API;\n" + |
| "public class Client {\n" + |
| " API api;\n" + |
| "}\n" |
| }; |
| IJavaProject p2 = setupModuleProject("mod.two", sources2, deps); |
| p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| |
| this.problemRequestor.reset(); |
| ICompilationUnit cu = getCompilationUnit("/mod.two/src/client/Client.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject("mod.one"); |
| deleteProject("mod.two"); |
| } |
| } |
| public void testBug522671() throws Exception { |
| try { |
| IJavaProject p1 = setupModuleProject("util", |
| new String[] { |
| "src/module-info.java", |
| "module util {\n" + |
| " exports my.util;\n" + |
| "}\n" + |
| "", |
| "src/my/util/Data.java", |
| "package my.util;\n" + |
| "public class Data {\n" + |
| "}\n" + |
| "", |
| "src/my/util/AnnotatedInModule.java", |
| "package my.util;\n" + |
| "public abstract class AnnotatedInModule {\n" + |
| " abstract public Data getTime();\n" + |
| "}\n" + |
| "", |
| }); |
| IJavaProject p2 = setupModuleProject("util2", |
| new String[] { |
| "src/module-info.java", |
| "module util2 {\n" + |
| " exports my.util.nested;\n" + |
| "}\n" + |
| "", |
| "src/my/util/nested/Unrelated.java", |
| "package my.util.nested;\n" + |
| "class Unrelated {\n" + |
| "}\n" + |
| "", |
| }); |
| String[] sources3 = { |
| "src/a/other/AnnotatedInOtherNonModule.java", |
| "package a.other;\n" + |
| "import my.util.Data;\n" + |
| "public class AnnotatedInOtherNonModule {\n" + |
| " Data generationDate;\n" + |
| "}\n" + |
| "", |
| }; |
| IClasspathAttribute[] attr = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| // modulepath |
| IClasspathEntry[] deps3 = { JavaCore.newProjectEntry(p1.getPath(), null, false, attr, false) }; |
| IJavaProject p3 = setupModuleProject("other", sources3, deps3); |
| |
| String[] sources4 = { |
| "src/test/Test.java", |
| "package test;\n" + |
| "\n" + |
| "import a.other.AnnotatedInOtherNonModule;\n" + |
| "import my.util.AnnotatedInModule;\n" + |
| "import my.util.Data;\n" + |
| "\n" + |
| "public class Test extends AnnotatedInOtherNonModule {\n" + |
| " public Data f(AnnotatedInModule calendar) {\n" + |
| " return calendar.getTime();\n" + |
| " }\n" + |
| "}\n" + |
| "", |
| }; |
| IClasspathEntry[] deps4 = { // |
| // modulepath (with split package my.util) |
| JavaCore.newProjectEntry(p1.getPath(), null, false, attr, false), // |
| JavaCore.newProjectEntry(p2.getPath(), null, false, attr, false), // |
| // classpath |
| JavaCore.newProjectEntry(p3.getPath()) // |
| }; |
| IJavaProject p4 = setupModuleProject("test", sources4, deps4); |
| p4.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| assertNoErrors(); |
| |
| this.problemRequestor.reset(); |
| ICompilationUnit cu = getCompilationUnit("/test/src/test/Test.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject("util"); |
| deleteProject("util2"); |
| deleteProject("other"); |
| deleteProject("test"); |
| } |
| } |
| public void testBug522671b() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/nonmodular1/HasConstructorWithProperties.java", |
| "package nonmodular1;\n" + |
| "\n" + |
| "import java.util.Properties;\n" + |
| "\n" + |
| "public class HasConstructorWithProperties {\n" + |
| "\n" + |
| " public HasConstructorWithProperties(Properties loadedProperties) {\n" + |
| " }\n" + |
| "\n" + |
| " protected Properties method() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "\n" + |
| "}\n" + |
| "", |
| "src/nonmodular1/HasPropertiesField.java", |
| "package nonmodular1;\n" + |
| "\n" + |
| "import java.util.Properties;\n" + |
| "\n" + |
| "public class HasPropertiesField {\n" + |
| " Properties properties;\n" + |
| "}\n" + |
| "", |
| }; |
| IJavaProject p1 = setupModuleProject("nonmodular1", sources); |
| |
| String[] sources2 = new String[] { |
| "src/java/util/dummy/Dummy.java", |
| "package java.util.dummy;\n" + |
| "\n" + |
| "public class Dummy {\n" + |
| "}\n" + |
| "\n" + |
| "", |
| }; |
| IJavaProject p2 = setupModuleProject("nonmodular2", sources2); |
| p2.setOption(JavaCore.COMPILER_COMPLIANCE, "1.8"); // compile with 1.8 compliance to avoid error about package conflict |
| |
| IClasspathEntry dep1 = JavaCore.newProjectEntry(p1.getPath(), null, false, |
| new IClasspathAttribute[] {}, |
| false/*not exported*/); |
| IClasspathEntry dep2 = JavaCore.newProjectEntry(p2.getPath(), null, false, |
| new IClasspathAttribute[] {}, |
| false/*not exported*/); |
| String[] src = new String[] { |
| "src/test/a/UsesHasPropertiesField.java", |
| "package test.a;\n" + |
| "\n" + |
| "import nonmodular1.HasPropertiesField;\n" + |
| "\n" + |
| "public class UsesHasPropertiesField extends HasPropertiesField {\n" + |
| "}\n" + |
| "", |
| "src/test/b/Test.java", |
| "package test.b;\n" + |
| "\n" + |
| "import java.util.Properties;\n" + |
| "\n" + |
| "import nonmodular1.HasConstructorWithProperties;\n" + |
| "\n" + |
| "public final class Test {\n" + |
| " public static Object test(Properties cassandraConf) {\n" + |
| " return new HasConstructorWithProperties(cassandraConf);\n" + |
| " }\n" + |
| "}\n" + |
| "", |
| }; |
| IJavaProject p3 = setupModuleProject("nonmodular3", src, new IClasspathEntry[] { dep1, dep2 }); |
| p3.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| deleteProject("nonmodular1"); |
| deleteProject("nonmodular2"); |
| deleteProject("nonmodular3"); |
| } |
| } |
| |
| public void testBug525522() throws Exception { |
| try { |
| // non-modular substitute for java.jnlp: |
| IClasspathAttribute[] jreAttribs = { JavaCore.newClasspathAttribute(IClasspathAttribute.LIMIT_MODULES, "java.base,java.desktop,java.rmi,java.sql") }; |
| IJavaProject jnlp = createJava9ProjectWithJREAttributes("jnlp", new String[] {"src"}, jreAttribs); |
| createFolder("jnlp/src/javax/jnlp"); |
| createFile("jnlp/src/javax/jnlp/UnavailableServiceException.java", |
| "package javax.jnlp;\n" + |
| "@SuppressWarnings(\"serial\")\n" + |
| "public class UnavailableServiceException extends Exception {\n" + |
| "}\n"); |
| createFile("jnlp/src/javax/jnlp/ServiceManager.java", |
| "package javax.jnlp;\n" + |
| "public class ServiceManager {\n" + |
| " public static void lookup(String s) throws UnavailableServiceException {}\n" + |
| "}\n"); |
| |
| // non-modular project consuming the non-modular jnlp, instead of the module from the JRE: |
| IJavaProject p1 = createJava9ProjectWithJREAttributes("nonmod1", new String[] {"src"}, jreAttribs); |
| addClasspathEntry(p1, JavaCore.newProjectEntry(jnlp.getPath())); |
| |
| createFolder("nonmod1/src/test"); |
| createFile("nonmod1/src/test/Test.java", |
| "package test;\n" + |
| "import javax.jnlp.ServiceManager;\n" + |
| "import javax.jnlp.UnavailableServiceException;\n" + |
| "\n" + |
| "public class Test {\n" + |
| "\n" + |
| " void init() {\n" + |
| " try {\n" + |
| " ServiceManager.lookup(\"\");\n" + |
| " } catch (final UnavailableServiceException e) {\n" + |
| " e.printStackTrace();\n" + |
| " }\n" + |
| "\n" + |
| " }\n" + |
| "}\n"); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| |
| this.problemRequestor.reset(); |
| ICompilationUnit cu = getCompilationUnit("/nonmod1/src/test/Test.java"); |
| cu.getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| } finally { |
| deleteProject("jnlp"); |
| deleteProject("nonmod1"); |
| } |
| } |
| |
| public void testBug525603() throws Exception { |
| IJavaProject javaProject = null; |
| try { |
| String[] sources = { |
| "com/automod1/pack/DummyA.java", |
| "package com.automod1.pack;\n" + |
| "public class DummyA {}\n;" |
| }; |
| String outputDirectory = Util.getOutputDirectory(); |
| |
| String jarPath = outputDirectory + File.separator + "automod.jar"; |
| Util.createJar(sources, jarPath, "1.8"); |
| |
| javaProject = createJava9Project("mod1", new String[] {"src"}); |
| IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| addClasspathEntry(javaProject, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, attributes, false)); |
| |
| String srcMod = |
| "module mod1 {\n" + |
| " exports com.mod1.pack1;\n" + |
| " requires automod;\n" + |
| "}"; |
| createFile("/mod1/src/module-info.java", |
| srcMod); |
| createFolder("/mod1/src/com/mod1/pack1"); |
| String srcX = |
| "package com.mod1.pack1;\n" + |
| "public class Dummy {\n" + |
| "}"; |
| createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX); |
| |
| this.problemRequestor.initialize(srcMod.toCharArray()); |
| getWorkingCopy("/mod1/src/module-info.java", srcMod, true); |
| assertProblems("module-info should have exactly one warning", |
| "----------\n" + |
| "1. WARNING in /mod1/src/module-info.java (at line 3)\n" + |
| " requires automod;\n" + |
| " ^^^^^^^\n" + |
| "Name of automatic module \'automod\' is unstable, it is derived from the module\'s file name.\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.initialize(srcX.toCharArray()); |
| getWorkingCopy("/mod1/src/com/mod1/pack1/Dummy.java", srcX, true); |
| assertProblems("X should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| if (javaProject != null) |
| deleteProject(javaProject); |
| } |
| } |
| |
| public void testBug522670() throws Exception { |
| Hashtable<String, String> javaCoreOptions = JavaCore.getOptions(); |
| try { |
| Hashtable<String, String> newOptions=new Hashtable<>(javaCoreOptions); |
| newOptions.put(CompilerOptions.OPTION_Store_Annotations, JavaCore.ENABLED); |
| JavaCore.setOptions(newOptions); |
| IJavaProject p1 = setupModuleProject("util", |
| new String[] { |
| "src/module-info.java", |
| "module util {\n" + |
| " exports my.util;\n" + |
| "}\n" + |
| "", |
| "src/my/util/Data.java", |
| "package my.util;\n" + |
| "public class Data {\n" + |
| "}\n" + |
| "", |
| "src/my/util/AnnotatedInModule.java", |
| "package my.util;\n" + |
| "import static java.lang.annotation.ElementType.TYPE_USE;\n" + |
| "import java.lang.annotation.Target;\n" + |
| "@Target(TYPE_USE)\n" + |
| "@interface Y {\n" + |
| "}\n" + |
| "public abstract class AnnotatedInModule {\n" + |
| " abstract public @Y Data getTime();\n" + |
| "}\n" + |
| "", |
| }); |
| IJavaProject p2 = setupModuleProject("util2", |
| new String[] { |
| "src/module-info.java", |
| "module util2 {\n" + |
| " exports my.util.nested;\n" + |
| "}\n" + |
| "", |
| "src/my/util/nested/Unrelated.java", |
| "package my.util.nested;\n" + |
| "class Unrelated {\n" + |
| "}\n" + |
| "", |
| }); |
| String[] sources3 = { |
| "src/a/other/AnnotatedInOtherNonModule.java", |
| "package a.other;\n" + |
| "import static java.lang.annotation.ElementType.TYPE_USE;\n" + |
| "import java.lang.annotation.Target;\n" + |
| "import my.util.Data;\n" + |
| "@Target(TYPE_USE)\n" + |
| "@interface X {\n" + |
| "}\n" + |
| "public class AnnotatedInOtherNonModule {\n" + |
| " @X\n" + |
| " Data generationDate;\n" + |
| "}\n" + |
| "", |
| }; |
| IClasspathAttribute[] attr = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| // modulepath |
| IClasspathEntry[] deps3 = { JavaCore.newProjectEntry(p1.getPath(), null, false, attr, false) }; |
| IJavaProject p3 = setupModuleProject("other", sources3, deps3); |
| |
| String[] sources4 = { |
| "src/test/Test.java", |
| "package test;\n" + |
| "\n" + |
| "import a.other.AnnotatedInOtherNonModule;\n" + |
| "import my.util.AnnotatedInModule;\n" + |
| "import my.util.Data;\n" + |
| "\n" + |
| "public class Test extends AnnotatedInOtherNonModule {\n" + |
| " public Data f(AnnotatedInModule calendar) {\n" + |
| " return calendar.getTime();\n" + |
| " }\n" + |
| "}\n" + |
| "", |
| }; |
| IClasspathEntry[] deps4 = { // |
| // modulepath (with split package my.util) |
| JavaCore.newProjectEntry(p1.getPath(), null, false, attr, false), // |
| JavaCore.newProjectEntry(p2.getPath(), null, false, attr, false), // |
| // classpath |
| JavaCore.newProjectEntry(p3.getPath()) // |
| }; |
| IJavaProject p4 = setupModuleProject("test", sources4, deps4); |
| p4.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| assertNoErrors(); |
| } finally { |
| JavaCore.setOptions(javaCoreOptions); |
| deleteProject("util"); |
| deleteProject("util2"); |
| deleteProject("other"); |
| deleteProject("test"); |
| } |
| } |
| |
| public void testBug526054() throws Exception { |
| if (!isJRE9) return; |
| ClasspathJrt.resetCaches(); |
| try { |
| // jdk.rmic is not be visible to code in an unnamed module, but using requires we can see the module. |
| // only, there's nothing exported from it (which is why JEP 261 hides it from unnamed), so we --add-reads: |
| IClasspathAttribute[] attrs = new IClasspathAttribute[] { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "jdk.rmic/sun.rmi.rmic=mod1") |
| }; |
| IJavaProject javaProject = createJava9ProjectWithJREAttributes("mod1", new String[] {"src"}, attrs); |
| |
| String srcMod = |
| "module mod1 {\n" + |
| " exports com.mod1.pack1;\n" + |
| " requires jdk.rmic;\n" + |
| "}"; |
| createFile("/mod1/src/module-info.java", |
| srcMod); |
| createFolder("/mod1/src/com/mod1/pack1"); |
| String srcX = |
| "package com.mod1.pack1;\n" + |
| "import sun.rmi.rmic.Main;\n" + |
| "public class Dummy {\n" + |
| " String test() {\n" + |
| " return Main.getString(\"in\");\n" + |
| " }\n" + |
| "}"; |
| createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX); |
| |
| this.problemRequestor.initialize(srcMod.toCharArray()); |
| getWorkingCopy("/mod1/src/module-info.java", srcMod, true); |
| assertProblems("module-info should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.initialize(srcX.toCharArray()); |
| getWorkingCopy("/mod1/src/com/mod1/pack1/Dummy.java", srcX, true); |
| assertProblems("Dummy should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| } finally { |
| deleteProject("mod1"); |
| } |
| } |
| |
| public void testBug526054b() throws Exception { |
| ClasspathJrt.resetCaches(); |
| try { |
| // one project can see jdk.rmic/sun.rmi.rmic |
| IClasspathAttribute[] attrs = new IClasspathAttribute[] { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "jdk.rmic/sun.rmi.rmic=mod1") |
| }; |
| createJava9ProjectWithJREAttributes("mod1", new String[] {"src"}, attrs); |
| |
| String srcMod1 = |
| "module mod1 {\n" + |
| " exports com.mod1.pack1;\n" + |
| " requires jdk.rmic;\n" + |
| "}"; |
| createFile("/mod1/src/module-info.java", |
| srcMod1); |
| createFolder("/mod1/src/com/mod1/pack1"); |
| String srcX1 = |
| "package com.mod1.pack1;\n" + |
| "import sun.rmi.rmic.Constants;\n" + // this should never be complained against due to above add-exports. |
| "public class Dummy implements Constants {\n" + |
| "}"; |
| createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX1); |
| |
| // second project cannot see jdk.rmic/sun.rmi.rmic: |
| createJava9Project("mod2", new String[] {"src"}); |
| |
| String srcMod2 = |
| "module mod2 {\n" + |
| " exports com.mod2.pack1;\n" + |
| " requires jdk.rmic;\n" + |
| "}"; |
| createFile("/mod2/src/module-info.java", |
| srcMod2); |
| createFolder("/mod2/src/com/mod2/pack1"); |
| String srcX2 = |
| "package com.mod2.pack1;\n" + |
| "import sun.rmi.rmic.Main;\n" + |
| "public class Dummy {\n" + |
| " String test() {\n" + |
| " return Main.getString(\"in\");\n" + |
| " }\n" + |
| "}"; |
| createFile("/mod2/src/com/mod2/pack1/Dummy.java", srcX2); |
| |
| // check first: |
| this.problemRequestor.initialize(srcX1.toCharArray()); |
| getWorkingCopy("/mod1/src/com/mod1/pack1/Dummy.java", srcX1, true); |
| assertProblems("Dummy in mod1 should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| // check second: |
| this.problemRequestor.initialize(srcX2.toCharArray()); |
| getWorkingCopy("/mod2/src/com/mod2/pack1/Dummy.java", srcX2, true); |
| assertProblems("Dummy in mod2 should have problems", |
| "----------\n" + |
| "1. ERROR in /mod2/src/com/mod2/pack1/Dummy.java (at line 2)\n" + |
| " import sun.rmi.rmic.Main;\n" + |
| " ^^^^^^^^^^^^^^^^^\n" + |
| "The type sun.rmi.rmic.Main is not accessible\n" + |
| "----------\n" + |
| "2. ERROR in /mod2/src/com/mod2/pack1/Dummy.java (at line 5)\n" + |
| " return Main.getString(\"in\");\n" + |
| " ^^^^\n" + |
| "Main cannot be resolved\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| // check both in a combined build |
| getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = getWorkspace().getRoot().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type sun.rmi.rmic.Main is not accessible\n" + |
| "Main cannot be resolved", |
| markers); |
| } finally { |
| deleteProject("mod1"); |
| deleteProject("mod2"); |
| } |
| } |
| |
| public void testBug525918() throws CoreException { |
| try { |
| String[] sources = new String[] { |
| "src/module-info.java", |
| "import p.MyAbstractDriver;\n" + |
| "import p.MyAbstractDriverWithProvider;\n" + |
| "import p.MyDriverInf;\n" + |
| "import p.MyInfWithProvider;\n" + |
| "module test {\n" + |
| " requires java.sql;\n" + |
| " provides java.sql.Driver with MyDriverInf, MyAbstractDriver, MyInfWithProvider, MyAbstractDriverWithProvider;" + |
| "}", |
| "src/p/MyDriverInf.java", |
| "package p;\n" + |
| "public interface MyDriverInf extends java.sql.Driver { }", |
| "src/p/MyAbstractDriver.java", |
| "package p;\n" + |
| "public abstract class MyAbstractDriver {\n" + |
| " public MyAbstractDriver() { }\n" + |
| "}", |
| "src/p/MyInfWithProvider.java", |
| "package p;\n" + |
| "public interface MyInfWithProvider {\n" + |
| " public static java.sql.Driver provider() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}\n", |
| "src/p/MyAbstractDriverWithProvider.java", |
| "package p;\n" + |
| "public abstract class MyAbstractDriverWithProvider {\n" + |
| " public static java.sql.Driver provider() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}" |
| }; |
| IJavaProject p1 = setupModuleProject("test", sources); |
| p1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| super.sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "Invalid service implementation, the type p.MyAbstractDriver is abstract\n" + |
| "Invalid service implementation, the type p.MyDriverInf is abstract\n" + |
| "Type mismatch: cannot convert from MyAbstractDriver to Driver" |
| , markers); |
| } finally { |
| deleteProject("test"); |
| } |
| } |
| |
| public void testBug527576() throws Exception { |
| IJavaProject javaProject = null; |
| try { |
| |
| javaProject = createJava9Project("mod1", new String[] {"src"}); |
| String[] sources = { |
| "org/junit/Assert.java", |
| "package org.junit;\n" + |
| "public class Assert {}\n;" |
| }; |
| |
| Path jarPath = new Path('/' + javaProject.getProject().getName() + '/' + "localjunit.jar"); |
| Util.createJar(sources, javaProject.getProject().getWorkspace().getRoot().getFile(jarPath).getRawLocation().toOSString(), "1.8"); |
| javaProject.getProject().refreshLocal(IResource.DEPTH_INFINITE, null); |
| |
| addClasspathEntry(javaProject, JavaCore.newLibraryEntry(jarPath, null, null, null, null, false)); |
| |
| String srcMod = |
| "module mod1 {\n" + |
| "}"; |
| createFile("/mod1/src/module-info.java", |
| srcMod); |
| createFolder("/mod1/src/com/mod1/pack1"); |
| String srcX = |
| "package com.mod1.pack1;\n" + |
| "import org.junit.Assert;\n" + |
| "public class Dummy extends Assert {\n" + |
| "}"; |
| createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX); |
| |
| this.problemRequestor.initialize(srcMod.toCharArray()); |
| getWorkingCopy("/mod1/src/module-info.java", srcMod, true); |
| assertProblems("module-info should have no problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| this.problemRequestor.initialize(srcX.toCharArray()); |
| getWorkingCopy("/mod1/src/com/mod1/pack1/Dummy.java", srcX, true); |
| assertProblems("X should have errors because Assert should not be visible", |
| "----------\n" + |
| "1. ERROR in /mod1/src/com/mod1/pack1/Dummy.java (at line 2)\n" + |
| " import org.junit.Assert;\n" + |
| " ^^^^^^^^^^^^^^^^\n" + |
| "The type org.junit.Assert is not accessible\n" + |
| "----------\n" + |
| "2. ERROR in /mod1/src/com/mod1/pack1/Dummy.java (at line 3)\n" + |
| " public class Dummy extends Assert {\n" + |
| " ^^^^^^\n" + |
| "Assert cannot be resolved to a type\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| javaProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = javaProject.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type org.junit.Assert is not accessible\n" + |
| "Assert cannot be resolved to a type", |
| markers); |
| } finally { |
| if (javaProject != null) |
| deleteProject(javaProject); |
| } |
| } |
| public void testBug528467a() throws CoreException { |
| IJavaProject p1 = createJava9Project("mod.one"); |
| try { |
| IClasspathEntry[] rawClasspath = p1.getRawClasspath(); |
| String jrtPath = null; |
| for (int i = 0; i < rawClasspath.length; i++) { |
| IClasspathEntry iClasspathEntry = rawClasspath[i]; |
| if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && |
| iClasspathEntry.getPath().toString().endsWith("jrt-fs.jar")) { |
| jrtPath = iClasspathEntry.getPath().toOSString(); |
| IAccessRule[] pathRules = new IAccessRule[1]; |
| pathRules[0] = JavaCore.newAccessRule(new Path("java/awt/**"), IAccessRule.K_NON_ACCESSIBLE); |
| IClasspathEntry newEntry = JavaCore.newLibraryEntry(iClasspathEntry.getPath(), |
| iClasspathEntry.getSourceAttachmentPath(), |
| iClasspathEntry.getSourceAttachmentRootPath(), |
| pathRules, |
| iClasspathEntry.getExtraAttributes(), |
| iClasspathEntry.isExported()); |
| rawClasspath[i] = newEntry; |
| break; |
| } |
| } |
| p1.setRawClasspath(rawClasspath, null); |
| createFolder("/mod.one/src/p1"); |
| createFile("/mod.one/src/module-info.java", |
| "module mod.one {\n" + |
| " exports p1;\n" + |
| " requires java.desktop;\n" + |
| "}\n"); |
| createFile("/mod.one/src/p1/X.java", |
| "package p1;\n" + |
| "public class X {\n" |
| + " java.awt.Image im = null;\n" |
| + "}\n"); |
| |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| |
| assertMarkers("Unexpected markers", "Access restriction: The type 'Image' is not API (restriction on required library '"+ |
| jrtPath + "')", markers); |
| } finally { |
| deleteProject(p1); |
| } |
| } |
| public void testBug528467b() throws CoreException { |
| IJavaProject p1 = createJava9Project("mod.one"); |
| try { |
| IClasspathEntry[] rawClasspath = p1.getRawClasspath(); |
| String jrtPath = null; |
| for (int i = 0; i < rawClasspath.length; i++) { |
| IClasspathEntry iClasspathEntry = rawClasspath[i]; |
| if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && |
| iClasspathEntry.getPath().toString().endsWith("jrt-fs.jar")) { |
| jrtPath = iClasspathEntry.getPath().toOSString(); |
| IAccessRule[] pathRules = new IAccessRule[1]; |
| pathRules[0] = JavaCore.newAccessRule(new Path("java/awt/Image"), IAccessRule.K_NON_ACCESSIBLE); |
| IClasspathEntry newEntry = JavaCore.newLibraryEntry(iClasspathEntry.getPath(), |
| iClasspathEntry.getSourceAttachmentPath(), |
| iClasspathEntry.getSourceAttachmentRootPath(), |
| pathRules, |
| iClasspathEntry.getExtraAttributes(), |
| iClasspathEntry.isExported()); |
| rawClasspath[i] = newEntry; |
| break; |
| } |
| } |
| p1.setRawClasspath(rawClasspath, null); |
| createFolder("/mod.one/src/p1"); |
| createFile("/mod.one/src/module-info.java", |
| "module mod.one {\n" + |
| " exports p1;\n" + |
| " requires java.desktop;\n" + |
| "}\n"); |
| createFile("/mod.one/src/p1/X.java", |
| "package p1;\n" + |
| "import java.awt.*;\n" + |
| "public abstract class X extends Image {\n" + |
| " public Graphics foo() {\n" + |
| " return getGraphics();\n" + |
| " }\n" |
| + "}\n"); |
| |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| |
| assertMarkers("Unexpected markers", |
| "Access restriction: The type \'Image\' is not API (restriction on required library '"+ jrtPath + "')\n" + |
| "The type Graphics from module java.desktop may not be accessible to clients due to missing \'requires transitive\'\n" + |
| "Access restriction: The method \'Image.getGraphics()\' is not API (restriction on required library '"+ jrtPath + "')", markers); |
| } finally { |
| deleteProject(p1); |
| } |
| } |
| public void testBug528467c() throws CoreException { |
| IJavaProject p1 = createJava9Project("unnamed"); |
| try { |
| IClasspathEntry[] rawClasspath = p1.getRawClasspath(); |
| String jrtPath = null; |
| for (int i = 0; i < rawClasspath.length; i++) { |
| IClasspathEntry iClasspathEntry = rawClasspath[i]; |
| if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && |
| iClasspathEntry.getPath().toString().endsWith("jrt-fs.jar")) { |
| jrtPath = iClasspathEntry.getPath().toOSString(); |
| IAccessRule[] pathRules = new IAccessRule[1]; |
| pathRules[0] = JavaCore.newAccessRule(new Path("java/awt/**"), IAccessRule.K_NON_ACCESSIBLE); |
| IClasspathEntry newEntry = JavaCore.newLibraryEntry(iClasspathEntry.getPath(), |
| iClasspathEntry.getSourceAttachmentPath(), |
| iClasspathEntry.getSourceAttachmentRootPath(), |
| pathRules, |
| iClasspathEntry.getExtraAttributes(), |
| iClasspathEntry.isExported()); |
| rawClasspath[i] = newEntry; |
| break; |
| } |
| } |
| p1.setRawClasspath(rawClasspath, null); |
| createFolder("/unnamed/src/p1"); |
| createFile("/unnamed/src/p1/X.java", |
| "package p1;\n" + |
| "public class X {\n" |
| + " java.awt.Image im = null;\n" |
| + "}\n"); |
| |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| |
| assertMarkers("Unexpected markers", "Access restriction: The type 'Image' is not API (restriction on required library '"+ |
| jrtPath + "')", markers); |
| } finally { |
| deleteProject(p1); |
| } |
| } |
| // Bug 520713: allow test code to access code on the classpath |
| public void testWithTestAttributeAndTestDependencyOnClassPath() throws CoreException, IOException { |
| String outputDirectory = Util.getOutputDirectory(); |
| |
| String jarPath = outputDirectory + File.separator + "mytestlib.jar"; |
| IJavaProject project1 = null; |
| IJavaProject project2 = null; |
| try { |
| String[] sources = { |
| "my/test/Test.java", |
| "package my.test;\n" + |
| "public class Test {}\n;" |
| }; |
| Util.createJar(sources, jarPath, "1.8"); |
| |
| project1 = createJava9Project("Project1", new String[] {"src"}); |
| addClasspathEntry(project1, JavaCore.newSourceEntry(new Path("/Project1/src-tests"), null, null, new Path("/Project1/bin-tests"), new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true") })); |
| addClasspathEntry(project1, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true") }, false)); |
| |
| createFolder("/Project1/src/p1"); |
| createFolder("/Project1/src-tests/p1"); |
| createFile("/Project1/src/module-info.java", |
| "module m1 {\n" + |
| " exports p1;\n" + |
| "}"); |
| createFile("/Project1/src/p1/P1Class.java", |
| "package p1;\n" + |
| "\n" + |
| "public class P1Class {\n"+ |
| "}\n" |
| ); |
| createFile("/Project1/src/p1/Production1.java", |
| "package p1;\n" + |
| "\n" + |
| "public class Production1 {\n" + |
| " void p1() {\n" + |
| " new P1Class(); // ok\n" + |
| " new T1Class(); // forbidden\n" + |
| " }\n" + |
| "}\n" + |
| "" |
| ); |
| createFile("/Project1/src-tests/p1/T1Class.java", |
| "package p1;\n" + |
| "\n" + |
| "public class T1Class {\n"+ |
| "}\n" |
| ); |
| createFile("/Project1/src-tests/p1/Test1.java", |
| "package p1;\n" + |
| "\n" + |
| "public class Test1 extends my.test.Test {\n" + |
| " void test1() {\n" + |
| " new P1Class(); // ok\n" + |
| " new T1Class(); // ok\n" + |
| " }\n" + |
| "}\n" + |
| "" |
| ); |
| project1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| IMarker[] markers = project1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "T1Class cannot be resolved to a type" + |
| "", |
| markers); |
| |
| project2 = createJava9Project("Project2", new String[] {"src"}); |
| addClasspathEntry(project2, JavaCore.newProjectEntry(new Path("/Project1"), null, false, new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }, false)); |
| addClasspathEntry(project2, JavaCore.newSourceEntry(new Path("/Project2/src-tests"), null, null, new Path("/Project2/bin-tests"), new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true") })); |
| addClasspathEntry(project2, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true") }, false)); |
| createFolder("/Project2/src/p2"); |
| createFolder("/Project2/src-tests/p2"); |
| createFile("/Project2/src/module-info.java", |
| "module m2 {\n" + |
| " requires m1;\n" + |
| "}"); |
| createFile("/Project2/src/p2/P2Class.java", |
| "package p2;\n" + |
| "\n" + |
| "public class P2Class {\n"+ |
| "}\n" |
| ); |
| createFile("/Project2/src/p2/Production2.java", |
| "package p2;\n" + |
| "\n" + |
| "import p1.P1Class;\n" + |
| "import p1.T1Class;\n" + |
| "\n" + |
| "public class Production2 {\n" + |
| " void p2() {\n" + |
| " new P1Class(); // ok\n" + |
| " new P2Class(); // ok\n" + |
| " new T1Class(); // forbidden\n" + |
| " new T2Class(); // forbidden\n" + |
| " }\n" + |
| "}\n" + |
| "" |
| ); |
| createFile("/Project2/src-tests/p2/T2Class.java", |
| "package p2;\n" + |
| "\n" + |
| "public class T2Class {\n"+ |
| "}\n" |
| ); |
| createFile("/Project2/src-tests/p2/Test2.java", |
| "package p2;\n" + |
| "\n" + |
| "import p1.P1Class;\n" + |
| "import p1.T1Class;\n" + |
| "\n" + |
| "public class Test2 extends p1.Test1 {\n" + |
| " void test2() {\n" + |
| " new P1Class(); // ok\n" + |
| " new P2Class(); // ok\n" + |
| " new T1Class(); // ok\n" + |
| " new T2Class(); // ok\n" + |
| " }\n" + |
| "}\n" + |
| "" |
| ); |
| project1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| IMarker[] markers2 = project2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers2); |
| assertMarkers("Unexpected markers", |
| "The import p1.T1Class cannot be resolved\n" + |
| "T1Class cannot be resolved to a type\n" + |
| "T2Class cannot be resolved to a type", |
| markers2); |
| } finally { |
| if (project1 != null) |
| deleteProject(project1); |
| if (project2 != null) |
| deleteProject(project2); |
| new File(jarPath).delete(); |
| } |
| } |
| |
| public void testBug531579() throws Exception { |
| String outputDirectory = Util.getOutputDirectory(); |
| |
| String jarPath = outputDirectory + File.separator + "jaxb-api.jar"; |
| IJavaProject project1 = null; |
| try { |
| // these types replace inaccessible types from JRE/javax.xml.bind: |
| // (not a problem during IDE builds) |
| String[] sources = { |
| "javax/xml/bind/JAXBContext.java", |
| "package javax.xml.bind;\n" + |
| "public abstract class JAXBContext {\n" + |
| " public static JAXBContext newInstance( String contextPath )\n" + |
| " throws JAXBException {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}\n", |
| "javax/xml/bind/JAXBException.java", |
| "package javax.xml.bind;\n" + |
| "public class JAXBException extends Exception {}\n" |
| }; |
| Util.createJar(sources, jarPath, "1.8"); |
| |
| project1 = createJava9Project("Project1", new String[] {"src"}); |
| addClasspathEntry(project1, JavaCore.newLibraryEntry(new Path(jarPath), null, null)); |
| |
| createFolder("/Project1/src/p1"); |
| createFile("/Project1/src/p1/ImportJAXBType.java", |
| "package p1;\n" + |
| "\n" + |
| "import javax.xml.bind.JAXBContext;\n" + |
| "\n" + |
| "public class ImportJAXBType {\n" + |
| "\n" + |
| " public static void main(String[] args) throws Exception {\n" + |
| " JAXBContext context = JAXBContext.newInstance(\"\");\n" + |
| " }\n" + |
| "\n" + |
| "}\n" |
| ); |
| |
| project1.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| |
| IMarker[] markers = project1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The value of the local variable context is not used", |
| markers); |
| } finally { |
| if (project1 != null) |
| deleteProject(project1); |
| new File(jarPath).delete(); |
| } |
| } |
| public void testBug527569a() throws CoreException { |
| IJavaProject p1 = createJava9Project("Bug527569", "9"); |
| try { |
| createFolder("/Bug527569/src/p1"); |
| createFile("/Bug527569/src/p1/X.java", |
| "package p1;\n" + |
| "public class X {\n" + |
| " public java.util.stream.Stream<String> emptyStream() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}"); |
| |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject(p1); |
| } |
| } |
| public void testBug527569b() throws CoreException { |
| IJavaProject p1 = createJava9Project("Bug527569", "1.7"); |
| try { |
| createFolder("/Bug527569/src/p1"); |
| createFile("/Bug527569/src/p1/X.java", |
| "package p1;\n" + |
| "public class X {\n" + |
| " public java.util.stream.Stream<String> emptyStream() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}"); |
| |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject(p1); |
| } |
| } |
| public void testBug527569c() throws CoreException { |
| if (!isJRE9) return; |
| IJavaProject p1 = createJava9Project("Bug527569", "1.7"); |
| Map<String, String> options = new HashMap<>(); |
| // Make sure the new options map doesn't reset. |
| options.put(CompilerOptions.OPTION_Compliance, "1.7"); |
| options.put(CompilerOptions.OPTION_Source, "1.7"); |
| options.put(CompilerOptions.OPTION_TargetPlatform, "1.7"); |
| options.put(CompilerOptions.OPTION_Release, "enabled"); |
| p1.setOptions(options); |
| try { |
| createFolder("/Bug527569/src/p1"); |
| createFile("/Bug527569/src/p1/X.java", |
| "package p1;\n" + |
| "public class X {\n" + |
| " public java.util.stream.Stream<String> emptyStream() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}"); |
| |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "java.util.stream.Stream cannot be resolved to a type", markers); |
| } finally { |
| deleteProject(p1); |
| } |
| } |
| public void testBug527569d() throws CoreException { |
| IJavaProject p1 = createJava9Project("Bug527569", "9"); |
| try { |
| createFolder("/Bug527569/src/p1"); |
| createFile("/Bug527569/src/p1/X.java", |
| "package p1;\n" + |
| "public class X {\n" + |
| " public java.lang.Compiler getCompiler() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}"); |
| |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "The type Compiler has been deprecated since version 9 and marked for removal", markers); |
| } finally { |
| deleteProject(p1); |
| } |
| } |
| public void testBug527569e() throws CoreException { |
| if (!isJRE9 || isJRE12) return; |
| IJavaProject p1 = createJava9Project("Bug527569", "1.8"); |
| Map<String, String> options = new HashMap<>(); |
| // Make sure the new options map doesn't reset. |
| options.put(CompilerOptions.OPTION_Compliance, "1.7"); |
| options.put(CompilerOptions.OPTION_Source, "1.7"); |
| options.put(CompilerOptions.OPTION_TargetPlatform, "1.7"); |
| options.put(CompilerOptions.OPTION_Release, "enabled"); |
| p1.setOptions(options); |
| try { |
| createFolder("/Bug527569/src/p1"); |
| createFile("/Bug527569/src/p1/X.java", |
| "package p1;\n" + |
| "public class X {\n" + |
| " public java.lang.Compiler getCompiler() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}"); |
| |
| waitForManualRefresh(); |
| waitForAutoBuild(); |
| p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject(p1); |
| } |
| } |
| public void testBug522601() throws CoreException { |
| IJavaProject p1 = createJava9Project("Bug522601", "9"); |
| try { |
| IFile file = createFile("/Bug522601/test.txt", "not a jar"); |
| IClasspathAttribute modAttr = JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"); |
| addLibraryEntry(p1, file.getFullPath(), null, null, null, null, new IClasspathAttribute[] { modAttr }, false); |
| p1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "Archive for required library: \'test.txt\' in project \'Bug522601\' cannot be read or is not a valid ZIP file\n" + |
| "The project cannot be built until build path errors are resolved", markers); |
| } finally { |
| deleteProject(p1); |
| } |
| } |
| // automatic modules export all their packages |
| public void testBug532724() throws CoreException, IOException { |
| try { |
| String libPath = "externalLib/test.jar"; |
| Util.createJar( |
| new String[] { |
| "test/src/org/astro/World.java", //$NON-NLS-1$ |
| "package org.astro;\n" + |
| "public interface World {\n" + |
| " public String name();\n" + |
| "}", |
| }, |
| null, |
| new HashMap<>(), |
| null, |
| getExternalResourcePath(libPath)); |
| String[] src = new String[] { |
| "src/module-info.java", |
| "module com.greetings {\n" + |
| " requires transitive test;\n" + |
| " exports com.greetings;\n" + |
| "}", |
| "src/com/greetings/MyWorld.java", |
| "package com.greetings;\n" + |
| "import org.astro.World;\n" + |
| "public class MyWorld {\n" + |
| " public World name() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}" |
| }; |
| IClasspathAttribute modAttr = new ClasspathAttribute("module", "true"); |
| IClasspathEntry dep = JavaCore.newLibraryEntry(new Path(getExternalResourcePath(libPath)), null, null, ClasspathEntry.NO_ACCESS_RULES, |
| new IClasspathAttribute[] {modAttr}, |
| false/*not exported*/); |
| IJavaProject p2 = setupModuleProject("com.greetings", src, new IClasspathEntry[] { dep }); |
| p2.setOption(JavaCore.COMPILER_PB_UNSTABLE_AUTO_MODULE_NAME, JavaCore.IGNORE); |
| p2.setOption(JavaCore.COMPILER_PB_API_LEAKS, JavaCore.ERROR); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteExternalResource("externalLib"); |
| this.deleteProject("com.greetings"); |
| } |
| } |
| public void testBug534624a() throws CoreException, IOException { |
| IJavaProject project = null; |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| try { |
| project = setUpJavaProject("bug.test.b534624"); |
| IClasspathEntry[] rawClasspath = project.getRawClasspath(); |
| IClasspathEntry jrtEntry = getJRTLibraryEntry(); |
| for(int i = 0; i < rawClasspath.length; i++) { |
| if (rawClasspath[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER) |
| rawClasspath[i] = jrtEntry; |
| } |
| project.setRawClasspath(rawClasspath, null); |
| project.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_10); |
| project.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_10); |
| project.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_10); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "Version9 cannot be resolved to a module", markers); |
| } finally { |
| if (project != null) |
| deleteProject(project); |
| JavaCore.setOptions(options); |
| } |
| } |
| public void testBug534624b() throws CoreException, IOException { |
| IJavaProject project = null; |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| try { |
| project = setUpJavaProject("bug.test.b534624"); |
| IClasspathEntry[] rawClasspath = project.getRawClasspath(); |
| IClasspathEntry jrtEntry = getJRTLibraryEntry(); |
| for(int i = 0; i < rawClasspath.length; i++) { |
| if (rawClasspath[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER) |
| rawClasspath[i] = jrtEntry; |
| } |
| project.setRawClasspath(rawClasspath, null); |
| project.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_9); |
| project.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_9); |
| project.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_9); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "Version10 cannot be resolved to a module", markers); |
| |
| project.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_10); |
| project.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_10); |
| project.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_10); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "Version9 cannot be resolved to a module", markers); |
| } finally { |
| if (project != null) |
| deleteProject(project); |
| JavaCore.setOptions(options); |
| } |
| } |
| // missing linked jar must not cause NPE |
| public void testBug540904() throws CoreException, IOException { |
| try { |
| String[] src = new String[] { |
| "src/test/Test.java", |
| "package test;\n" + |
| "public class Test {\n" + |
| "}" |
| }; |
| IJavaProject p2 = setupModuleProject("Bug540904", src, new IClasspathEntry[] { }); |
| IFile file = getFile("/Bug540904/link.jar"); |
| file.createLink(new Path("MISSING/missing.jar"), IResource.ALLOW_MISSING_LOCAL, null); |
| addLibraryEntry(p2, file.getFullPath(), false); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| this.deleteProject("Bug540904"); |
| } |
| } |
| public void testBug540788() throws Exception { |
| try { |
| // project common: |
| IJavaProject common = createJava9Project("Bug540788.common", new String[] { "src/main/java" }); |
| createSourceFiles(common, |
| new String[] { |
| "src/main/java/module-info.java", |
| "module org.sheepy.common {\n" + |
| " requires transitive org.eclipse.emf.common;\n" + |
| " requires transitive org.eclipse.emf.ecore;\n" + |
| "}\n" |
| }); |
| IFolder libs = createFolder("/Bug540788.common/libs"); |
| String emfCommonLocation = libs.getLocation()+"/org.eclipse.emf.common.jar"; |
| Path emfCommonPath = new Path(emfCommonLocation); |
| Util.createJar( |
| new String[] { |
| "src/org/eclipse/emf/common/Foo.java", |
| "package org.eclipse.emf.common;\n" + |
| "public interface Foo {\n" + |
| "}", |
| }, |
| null, |
| new HashMap<>(), |
| null, |
| emfCommonLocation); |
| addModularLibraryEntry(common, emfCommonPath, null); |
| |
| String ecoreLocation = libs.getLocation()+"/org.eclipse.emf.ecore.jar"; |
| Path ecorePath = new Path(ecoreLocation); |
| Util.createJar( |
| new String[] { |
| "src/org/eclipse/emf/ecore/EObject.java", |
| "package org.eclipse.emf.ecore;\n" + |
| "public interface EObject {\n" + |
| "}", |
| }, |
| null, |
| new HashMap<>(), |
| null, |
| ecoreLocation); |
| addModularLibraryEntry(common, ecorePath, null); |
| // project vulkan: |
| IJavaProject vulkan = createJava9Project("Bug540788.vulkan", new String[] { "src/main/java" }); |
| createSourceFiles(vulkan, |
| new String[] { |
| "src/main/java/module-info.java", |
| "module org.sheepy.vulkan {\n" + |
| " requires transitive org.sheepy.common;\n" + |
| " exports org.sheepy.vulkan.model.resource;\n" + |
| "}\n", |
| "src/main/java/org/sheepy/vulkan/model/resource/Resource.java", |
| "package org.sheepy.vulkan.model.resource;\n" + |
| "import org.eclipse.emf.ecore.EObject;\n" + |
| "public interface Resource extends EObject {\n" + |
| "}\n", |
| "src/main/java/org/sheepy/vulkan/model/resource/VulkanBuffer.java", |
| "package org.sheepy.vulkan.model.resource;\n" + |
| "public interface VulkanBuffer extends Resource {\n" + |
| "}\n", |
| }); |
| addModularProjectEntry(vulkan, common); |
| addModularLibraryEntry(vulkan, emfCommonPath, null); |
| addModularLibraryEntry(vulkan, ecorePath, null); |
| // project vulkan.demo |
| IJavaProject vulkan_demo = createJava9Project("Bug540788.vulkan.demo", new String[] { "src/main/java" }); |
| createSourceFiles(vulkan_demo, |
| new String[] { |
| "src/main/java/module-info.java", |
| "module org.sheepy.vulkan.demo {\n" + |
| " exports org.sheepy.vulkan.demo.model;\n" + |
| " requires org.sheepy.vulkan;\n" + |
| "}\n", |
| "src/main/java/org/sheepy/vulkan/demo/model/UniformBuffer.java", |
| "package org.sheepy.vulkan.demo.model;\n" + |
| "import org.sheepy.vulkan.model.resource.VulkanBuffer;\n" + |
| "public interface UniformBuffer extends VulkanBuffer {\n" + |
| "}\n", |
| }); |
| addModularProjectEntry(vulkan_demo, vulkan); |
| addModularProjectEntry(vulkan_demo, common); |
| addModularLibraryEntry(vulkan_demo, emfCommonPath, null); |
| addModularLibraryEntry(vulkan_demo, ecorePath, null); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = vulkan_demo.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "", markers); |
| } finally { |
| deleteProject("Bug540788.common"); |
| deleteProject("Bug540788.vulkan"); |
| deleteProject("Bug540788.vulkan.demo"); |
| } |
| } |
| public void testBug541015() throws Exception { |
| try { |
| IJavaProject m1 = createJava9Project("m1", new String[] { "src" }); |
| createSourceFiles(m1, |
| new String[] { |
| "src/module-info.java", |
| "module m1 { exports org.p1; }\n", |
| "src/org/p1/T1.java", |
| "package org.p1;\n" + |
| "public class T1 {}\n" |
| }); |
| IJavaProject m2 = createJava9Project("m2", new String[] { "src" }); |
| createSourceFiles(m2, |
| new String[] { |
| "src/module-info.java", |
| "module m2 { exports org.p1; }\n", |
| "src/org/p1/T1.java", |
| "package org.p1;\n" + |
| "public class T1 {}\n" |
| }); |
| IJavaProject m3 = createJava9Project("m3", new String[] { "src" }); |
| createSourceFiles(m3, |
| new String[] { |
| "src/module-info.java", |
| "module m3 { exports org.p1; }\n", |
| "src/org/p1/T1.java", |
| "package org.p1;\n" + |
| "public class T1 {}\n" |
| }); |
| IJavaProject unnamed = createJava9Project("unnamed", new String[] { "src" }); |
| String testSource = "package test;\n" + |
| "import org.p1.T1;\n" + |
| "public class Test {\n" + |
| " T1 t1;\n" + |
| "}\n"; |
| createSourceFiles(unnamed, |
| new String[] { |
| "src/test/Test.java", |
| testSource |
| }); |
| addModularProjectEntry(unnamed, m1); |
| addModularProjectEntry(unnamed, m2); |
| addModularProjectEntry(unnamed, m3); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = unnamed.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The package org.p1 is accessible from more than one module: m1, m2, m3\n" + |
| "T1 cannot be resolved to a type", |
| markers); |
| |
| char[] sourceChars = testSource.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| getCompilationUnit("/unnamed/src/test/Test.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /unnamed/src/test/Test.java (at line 2)\n" + |
| " import org.p1.T1;\n" + |
| " ^^^^^^\n" + |
| "The package org.p1 is accessible from more than one module: m1, m2, m3\n" + |
| "----------\n" + |
| "2. ERROR in /unnamed/src/test/Test.java (at line 4)\n" + |
| " T1 t1;\n" + |
| " ^^\n" + |
| "T1 cannot be resolved to a type\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject("m1"); |
| deleteProject("m2"); |
| deleteProject("m3"); |
| deleteProject("unnamed"); |
| } |
| } |
| public void testBug536928_comment22() throws CoreException, IOException { |
| try { |
| IJavaProject project = createJava9Project("ztest", new String[] { "src" }); |
| createFolder("/ztest/lib"); |
| Util.createJar(new String[] { |
| "javax/xml/transform/Transformer.java", |
| "package javax.xml.transform;\n" + |
| "public class Transformer {}\n", |
| "javax/xml/transform/Result.java", |
| "package javax.xml.transform;\n" + |
| "public class Result {}\n" |
| }, |
| project.getProject().getLocation().toString() + "/lib/xml-apis.jar", |
| "1.8"); |
| project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null); |
| IClasspathEntry libraryEntry = JavaCore.newLibraryEntry(new Path("/ztest/lib/xml-apis.jar"), null, null); |
| addClasspathEntry(project, libraryEntry, 1); // right after src and before jrt-fs.jar |
| |
| String testSource = |
| "package com.ztest;\n" + |
| "import javax.xml.transform.Transformer;\n" + |
| "\n" + |
| "public class TestApp {\n" + |
| " Transformer ts;\n" + |
| " javax.xml.transform.Result result;\n" + |
| "}\n"; |
| createFolder("/ztest/src/com/ztest"); |
| createFile("/ztest/src/com/ztest/TestApp.java", testSource); |
| String test2Source = |
| "package com.ztest;\n" + |
| "import javax.xml.transform.*;\n" + |
| "public class Test2 {\n" + |
| " Transformer ts;\n" + |
| "}\n"; |
| createFile("/ztest/src/com/ztest/Test2.java", test2Source); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected Markers", |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + |
| "Transformer cannot be resolved to a type\n" + |
| "Transformer cannot be resolved to a type\n" + |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml", |
| markers); |
| |
| char[] sourceChars = testSource.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| getCompilationUnit("/ztest/src/com/ztest/TestApp.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /ztest/src/com/ztest/TestApp.java (at line 2)\n" + |
| " import javax.xml.transform.Transformer;\n" + |
| " ^^^^^^^^^^^^^^^^^^^\n" + |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + |
| "----------\n" + |
| "2. ERROR in /ztest/src/com/ztest/TestApp.java (at line 5)\n" + |
| " Transformer ts;\n" + |
| " ^^^^^^^^^^^\n" + |
| "Transformer cannot be resolved to a type\n" + |
| "----------\n" + |
| "3. ERROR in /ztest/src/com/ztest/TestApp.java (at line 6)\n" + |
| " javax.xml.transform.Result result;\n" + |
| " ^^^^^^^^^^^^^^^^^^^\n" + |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| sourceChars = test2Source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| getCompilationUnit("/ztest/src/com/ztest/Test2.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /ztest/src/com/ztest/Test2.java (at line 2)\n" + |
| " import javax.xml.transform.*;\n" + |
| " ^^^^^^^^^^^^^^^^^^^\n" + |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + |
| "----------\n" + |
| "2. ERROR in /ztest/src/com/ztest/Test2.java (at line 4)\n" + |
| " Transformer ts;\n" + |
| " ^^^^^^^^^^^\n" + |
| "Transformer cannot be resolved to a type\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject("ztest"); |
| } |
| } |
| public void testBug536928_comment22b() throws CoreException, IOException { |
| try { |
| IJavaProject project = createJava9Project("ztest", new String[] { "src" }); |
| createFolder("/ztest/lib"); |
| Util.createJar(new String[] { |
| "javax/xml/transform/Transformer.java", |
| "package javax.xml.transform;\n" + |
| "public class Transformer {}\n", |
| "javax/xml/transform/Result.java", |
| "package javax.xml.transform;\n" + |
| "public class Result {}\n" |
| }, |
| project.getProject().getLocation().toString() + "/lib/xml-apis.jar", |
| "1.8"); |
| project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null); |
| IClasspathEntry libraryEntry = JavaCore.newLibraryEntry(new Path("/ztest/lib/xml-apis.jar"), null, null); |
| addClasspathEntry(project, libraryEntry, 2); // DIFFERENCE HERE: place xml-apis.jar AFTER jrt-fs.jar |
| |
| String testSource = |
| "package com.ztest;\n" + |
| "import javax.xml.transform.Transformer;\n" + |
| "\n" + |
| "public class TestApp {\n" + |
| " Transformer ts;\n" + |
| " javax.xml.transform.Result result;\n" + |
| "}\n"; |
| createFolder("/ztest/src/com/ztest"); |
| createFile("/ztest/src/com/ztest/TestApp.java", testSource); |
| String test2Source = |
| "package com.ztest;\n" + |
| "import javax.xml.transform.*;\n" + |
| "public class Test2 {\n" + |
| " Transformer ts;\n" + |
| "}\n"; |
| createFile("/ztest/src/com/ztest/Test2.java", test2Source); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| IMarker[] markers = project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected Markers", |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + |
| "Transformer cannot be resolved to a type\n" + |
| "Transformer cannot be resolved to a type\n" + |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml", |
| markers); |
| |
| char[] sourceChars = testSource.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| getCompilationUnit("/ztest/src/com/ztest/TestApp.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /ztest/src/com/ztest/TestApp.java (at line 2)\n" + |
| " import javax.xml.transform.Transformer;\n" + |
| " ^^^^^^^^^^^^^^^^^^^\n" + |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + |
| "----------\n" + |
| "2. ERROR in /ztest/src/com/ztest/TestApp.java (at line 5)\n" + |
| " Transformer ts;\n" + |
| " ^^^^^^^^^^^\n" + |
| "Transformer cannot be resolved to a type\n" + |
| "----------\n" + |
| "3. ERROR in /ztest/src/com/ztest/TestApp.java (at line 6)\n" + |
| " javax.xml.transform.Result result;\n" + |
| " ^^^^^^^^^^^^^^^^^^^\n" + |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + |
| "----------\n", |
| this.problemRequestor); |
| |
| sourceChars = test2Source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| getCompilationUnit("/ztest/src/com/ztest/Test2.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. ERROR in /ztest/src/com/ztest/Test2.java (at line 2)\n" + |
| " import javax.xml.transform.*;\n" + |
| " ^^^^^^^^^^^^^^^^^^^\n" + |
| "The package javax.xml.transform is accessible from more than one module: <unnamed>, java.xml\n" + |
| "----------\n" + |
| "2. ERROR in /ztest/src/com/ztest/Test2.java (at line 4)\n" + |
| " Transformer ts;\n" + |
| " ^^^^^^^^^^^\n" + |
| "Transformer cannot be resolved to a type\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject("ztest"); |
| } |
| } |
| public void testBug536928_comment22_limited() throws CoreException, IOException { |
| try { |
| IClasspathAttribute[] limitModules = { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.LIMIT_MODULES, "java.base") |
| }; |
| IJavaProject project = createJava9ProjectWithJREAttributes("ztest", new String[] { "src" }, limitModules); |
| createFolder("/ztest/lib"); |
| Util.createJar(new String[] { |
| "javax/xml/transform/Transformer.java", |
| "package javax.xml.transform;\n" + |
| "public class Transformer {}\n", |
| "javax/xml/transform/Result.java", |
| "package javax.xml.transform;\n" + |
| "public class Result {}\n" |
| }, |
| project.getProject().getLocation().toString() + "/lib/xml-apis.jar", |
| "1.8"); |
| project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null); |
| IClasspathEntry libraryEntry = JavaCore.newLibraryEntry(new Path("/ztest/lib/xml-apis.jar"), null, null); |
| addClasspathEntry(project, libraryEntry, 1); // right after src and before jrt-fs.jar |
| |
| String testSource = |
| "package com.ztest;\n" + |
| "import javax.xml.transform.Transformer;\n" + |
| "\n" + |
| "public class TestApp {\n" + |
| " Transformer ts;\n" + |
| " javax.xml.transform.Result result;\n" + |
| "}\n"; |
| createFolder("/ztest/src/com/ztest"); |
| createFile("/ztest/src/com/ztest/TestApp.java", testSource); |
| String test2Source = |
| "package com.ztest;\n" + |
| "import javax.xml.transform.*;\n" + |
| "public class Test2 {\n" + |
| " Transformer ts;\n" + |
| "}\n"; |
| createFile("/ztest/src/com/ztest/Test2.java", test2Source); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| |
| char[] sourceChars = testSource.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| getCompilationUnit("/ztest/src/com/ztest/TestApp.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| sourceChars = test2Source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| getCompilationUnit("/ztest/src/com/ztest/Test2.java").getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject("ztest"); |
| } |
| } |
| public void testBug542896() throws CoreException { |
| IJavaProject java10Project = createJava10Project("bug", new String[] { "src" }); |
| try { |
| createFolder("/bug/src/test/platform"); |
| createFile("/bug/src/test/platform/Context.java", |
| "package test.platform;\n" + |
| "\n" + |
| "import java.net.URI;\n" + |
| "\n" + |
| "public interface Context {\n" + |
| " public URI getURI();\n" + |
| "}\n"); |
| createFile("/bug/src/test/platform/AbstractContext.java", |
| "package test.platform;\n" + |
| "\n" + |
| "import java.net.URI;\n" + |
| "import java.util.*;\n" + |
| "import test.*;\n" + |
| "\n" + |
| "public abstract class AbstractContext implements Context {\n" + |
| " Iterable<URI> uris = new ArrayList<URI>();\n" + |
| " Application application;\n" + |
| "}\n"); |
| String testSource = |
| "package test;\n" + |
| "\n" + |
| "import java.io.*;\n" + |
| "import java.net.*;\n" + |
| "import java.util.*;\n" + |
| "\n" + |
| "import test.platform.*;\n" + |
| "\n" + |
| "public interface Application // extends Foo\n" + |
| "{\n" + |
| "}\n"; |
| String testPath = "/bug/src/test/Application.java"; |
| createFile(testPath, testSource); |
| // first compile: no error: |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| char[] sourceChars = testSource.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| getCompilationUnit(testPath).getWorkingCopy(this.wcOwner, null); |
| assertProblems( |
| "Unexpected problems", |
| "----------\n" + |
| "1. WARNING in /bug/src/test/Application.java (at line 3)\n" + |
| " import java.io.*;\n" + |
| " ^^^^^^^\n" + |
| "The import java.io is never used\n" + |
| "----------\n" + |
| "2. WARNING in /bug/src/test/Application.java (at line 4)\n" + |
| " import java.net.*;\n" + |
| " ^^^^^^^^\n" + |
| "The import java.net is never used\n" + |
| "----------\n" + |
| "3. WARNING in /bug/src/test/Application.java (at line 5)\n" + |
| " import java.util.*;\n" + |
| " ^^^^^^^^^\n" + |
| "The import java.util is never used\n" + |
| "----------\n" + |
| "4. WARNING in /bug/src/test/Application.java (at line 7)\n" + |
| " import test.platform.*;\n" + |
| " ^^^^^^^^^^^^^\n" + |
| "The import test.platform is never used\n" + |
| "----------\n", |
| this.problemRequestor); |
| // introduce error: |
| String testSourceEdited = |
| "package test;\n" + |
| "\n" + |
| "import java.io.*;\n" + |
| "import java.net.*;\n" + |
| "import java.util.*;\n" + |
| "\n" + |
| "import test.platform.*;\n" + |
| "\n" + |
| "public interface Application extends Foo\n" + |
| "{\n" + |
| "}\n"; |
| editFile(testPath, testSourceEdited); |
| java10Project.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| IMarker[] markers = java10Project.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", "Foo cannot be resolved to a type", markers); |
| } finally { |
| if (java10Project != null) |
| deleteProject(java10Project); |
| } |
| } |
| public void testBug543392a() throws Exception { |
| bug543392(null); |
| } |
| public void testBug543392b() throws Exception { |
| // put other on the *modulepath*: |
| IClasspathAttribute[] attrs = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; |
| bug543392(attrs); |
| } |
| void bug543392(IClasspathAttribute[] dependencyAttrs) throws Exception { |
| IJavaProject other = createJava9Project("other"); |
| IJavaProject current = createJava9Project("current"); |
| try { |
| createFile("other/src/module-info.java", |
| "module other {\n" + |
| " exports other.p;\n" + |
| "}\n"); |
| createFolder("other/src/other/p"); |
| createFile("other/src/other/p/C.java", |
| "package other.p;\n" + |
| "public class C {}\n"); |
| |
| addClasspathEntry(current, |
| JavaCore.newProjectEntry(other.getProject().getFullPath(), null, false, dependencyAttrs, false)); // dependency, but .. |
| createFile("current/src/module-info.java", "module current {}\n"); // ... no 'requires'! |
| createFolder("current/src/current"); |
| |
| String test1path = "current/src/current/Test1.java"; |
| String test1source = |
| "package current;\n" + |
| "import other.p.C;\n" + |
| "public class Test1 {\n" + |
| "}\n"; |
| createFile(test1path, test1source); |
| String test2path = "current/src/current/Test2.java"; |
| String test2source = |
| "package current;\n" + |
| "public class Test2 {\n" + |
| " other.p.C c;\n" + |
| "}\n"; |
| createFile(test2path, test2source); |
| |
| getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| IMarker[] markers = current.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "The type other.p.C is not accessible\n" + |
| "The type other.p.C is not accessible", |
| markers); |
| |
| char[] sourceChars = test1source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| getCompilationUnit(test1path).getWorkingCopy(this.wcOwner, null); |
| assertProblems("unexpected problems", |
| "----------\n" + |
| "1. ERROR in /current/src/current/Test1.java (at line 2)\n" + |
| " import other.p.C;\n" + |
| " ^^^^^^^^^\n" + |
| "The type other.p.C is not accessible\n" + |
| "----------\n", |
| this.problemRequestor); |
| sourceChars = test2source.toCharArray(); |
| this.problemRequestor.initialize(sourceChars); |
| getCompilationUnit(test2path).getWorkingCopy(this.wcOwner, null); |
| assertProblems("unexpected problems", |
| "----------\n" + |
| "1. ERROR in /current/src/current/Test2.java (at line 3)\n" + |
| " other.p.C c;\n" + |
| " ^^^^^^^^^\n" + |
| "The type other.p.C is not accessible\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject(other); |
| deleteProject(current); |
| } |
| } |
| public void testBug541328() throws Exception { |
| IJavaProject pa = createJava9Project("m.a"); |
| IJavaProject pb = createJava9Project("m.b"); |
| IJavaProject test = createJava9Project("test"); |
| try { |
| createFolder("m.a/src/a/foo"); |
| createFile("m.a/src/a/foo/Bar.java", "package a.foo;\n public class Bar {}\n"); |
| createFile("m.a/src/module-info.java", |
| "module m.a {\n" + |
| " exports a.foo to m.b;\n" + |
| "}\n"); |
| createFile("m.b/src/module-info.java", |
| "module m.b {\n" + |
| " requires m.a;\n" + |
| " exports b;\n" + |
| "}\n"); |
| createFolder("m.b/src/b"); |
| createFile("m.b/src/b/Boo.java", |
| "package b;\n" + |
| "import a.foo.Bar;\n" + |
| "public class Boo extends Bar {}\n"); |
| addModularProjectEntry(pb, pa); |
| |
| IClasspathAttribute[] forceExport = { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"), |
| JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "m.a/a.foo=ALL-UNNAMED") |
| }; |
| addClasspathEntry(test, JavaCore.newProjectEntry(pa.getPath(), null, false, forceExport, false)); |
| addModularProjectEntry(test, pb); |
| |
| String testSource = |
| "import a.foo.Bar;\n" + |
| "import b.Boo;\n" + |
| "public class Test {\n" + |
| " Bar b = new Boo();\n" + |
| "}\n"; |
| String testPath = "test/src/Test.java"; |
| createFile(testPath, testSource); |
| getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| assertNoErrors(); |
| |
| this.problemRequestor.initialize(testSource.toCharArray()); |
| getCompilationUnit(testPath).getWorkingCopy(this.wcOwner, null); |
| assertProblems("unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject(pa); |
| deleteProject(pb); |
| deleteProject(test); |
| } |
| } |
| public void testBug543195() throws CoreException { |
| IJavaProject pj1 = createJava9Project("pj1"); |
| IJavaProject pj2 = createJava9Project("pj2"); |
| IJavaProject ptest = createJava9Project("ptest"); |
| try { |
| addModularProjectEntry(pj2, pj1); |
| addModularProjectEntry(ptest, pj2); |
| |
| createFolder("pj1/src/p"); |
| createFile("pj1/src/p/Missing.java", |
| "package p;\n" + |
| "public class Missing {\n" + |
| " public void miss() {}\n" + |
| "}\n"); |
| createFile("pj1/src/module-info.java", |
| "module pj1 {\n" + |
| " exports p;\n" + |
| "}\n"); |
| |
| createFolder("pj2/src/q"); |
| createFile("pj2/src/q/API.java", |
| "package q;\n" + |
| "public class API extends p.Missing {}\n"); |
| createFile("pj2/src/q/API2.java", |
| "package q;\n" + |
| "public class API2 extends API {}\n"); |
| createFile("pj2/src/module-info.java", |
| "module pj2 {\n" + |
| " requires pj1;\n" + |
| " exports q;\n" + |
| "}\n"); |
| getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| |
| deleteFile("pj1/bin/p/Missing.class"); |
| pj1.getProject().close(null); |
| |
| createFolder("ptest/src/p/r"); |
| createFile("ptest/src/p/r/P.java", "package p.r;\n public class P {}\n"); |
| createFolder("ptest/src/t"); |
| createFile("ptest/src/t/Test1.java", |
| "package t;\n" + |
| "import q.API2;\n" + |
| "public class Test1 {\n" + |
| " void m(API2 a) {\n" + |
| " a.miss();\n" + |
| " }\n" + |
| "}\n"); |
| String test2Path = "ptest/src/t/Test2.java"; |
| String test2Content = |
| "package t;\n" + |
| "import p.Missing;\n" + |
| "public class Test2 {}\n"; |
| createFile(test2Path, test2Content); |
| ptest.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| IMarker[] markers = ptest.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("unexpected markers", |
| "The import p.Missing cannot be resolved\n" + |
| "The method miss() is undefined for the type API2", |
| markers); |
| |
| this.problemRequestor.initialize(test2Content.toCharArray()); |
| getCompilationUnit(test2Path).getWorkingCopy(this.wcOwner, null); |
| assertProblems("unexpected problems", |
| "----------\n" + |
| "1. ERROR in /ptest/src/t/Test2.java (at line 2)\n" + |
| " import p.Missing;\n" + |
| " ^^^^^^^^^\n" + |
| "The import p.Missing cannot be resolved\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject(pj1); |
| deleteProject(pj2); |
| deleteProject(ptest); |
| } |
| } |
| |
| public void testBug543701() throws Exception { |
| IJavaProject p = createJava9Project("p"); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String jar1Path = outputDirectory + File.separator + "lib1.jar"; |
| Util.createJar(new String[] { |
| "javax/xml/transform/Result.java", |
| "package javax.xml.transform;\n" + |
| "public class Result {}\n" |
| }, new HashMap<>(), jar1Path); |
| |
| String jar2Path = outputDirectory + File.separator + "lib2.jar"; |
| Util.createJar(new String[] { |
| "p2/C2.java", |
| "package p2;\n" + |
| "import javax.xml.transform.Result;\n" + |
| "public class C2 {\n" + |
| " public void m(Number n) {}\n" + |
| " public void m(Result r) {}\n" + // Result will be ambiguous looking from project 'p', but should not break compilation |
| "}\n" |
| }, new HashMap<>(), jar2Path); |
| |
| addLibraryEntry(p, jar1Path, false); |
| addLibraryEntry(p, jar2Path, false); |
| |
| createFolder("p/src/pp"); |
| String testPath = "p/src/pp/Test.java"; |
| String testSource = |
| "package pp;\n" + |
| "import p2.C2;\n" + |
| "public class Test {\n" + |
| " void test(C2 c2) {\n" + |
| " c2.m(Integer.valueOf(1));\n" + |
| " }\n" + |
| "}\n"; |
| createFile(testPath, testSource); |
| |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| assertNoErrors(); |
| |
| this.problemRequestor.initialize(testSource.toCharArray()); |
| getCompilationUnit(testPath).getWorkingCopy(this.wcOwner, null); |
| assertProblems("unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject(p); |
| // clean up output dir |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| |
| public void testBug543441() throws Exception { |
| // unsuccessful attempt at triggering NPE on null required module |
| IJavaProject p = createJava9Project("p"); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String jar1Path = outputDirectory + File.separator + "lib1.jar"; |
| Util.createJar(new String[] { |
| "module-info.java", |
| "module lib1 {}\n" |
| }, jar1Path, "9"); |
| |
| String jar2Path = outputDirectory + File.separator + "lib2.jar"; |
| Util.createJar(new String[] { |
| "module-info.java", |
| "module lib2 {\n" + |
| " requires lib1;\n" + // will be messing when seen from project 'p' |
| " exports p2;\n" + |
| "}\n", |
| "p2/C2.java", |
| "package p2;\n" + |
| "public class C2 {}\n" |
| }, |
| null, jar2Path, new String[] { jar1Path }, "9"); |
| |
| File jar1File = new File(jar1Path); |
| jar1File.delete(); |
| |
| addModularLibraryEntry(p, new Path(jar2Path), null); |
| createFile("p/src/module-info.java", |
| "module p {\n" + |
| " requires transitive lib2;\n" + // not lib1 |
| "}\n"); |
| createFolder("p/src/pkg"); |
| createFile("p/src/pkg/Test.java", |
| "package pkg;\n" + |
| "import p2.C2;\n" + |
| "public class Test {\n" + |
| " void test(C2 c) {}\n" + |
| "}\n"); |
| |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| assertNoErrors(); |
| |
| } finally { |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| |
| public void testBug543765() throws CoreException, IOException { |
| // failure never seen in this test |
| IJavaProject m = createJava9Project("M"); |
| IJavaProject n = createJava9Project("N"); |
| IJavaProject x = createJava9Project("X"); |
| IJavaProject y = createJava9Project("Y"); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| // ------ W ------ |
| String wJarLocation = outputDirectory + File.separator + "w-0.0.1-SNAPSHOT.jar"; |
| IPath wJarPath = new Path(wJarLocation); |
| Util.createJar(new String[] { |
| "external/W.java", |
| "public class W {\n" + |
| " public static void main(String... args) {}\n" + |
| "}\n" |
| }, wJarLocation, "9"); |
| |
| // ------ X ------ |
| addModularLibraryEntry(x, wJarPath, null); |
| createFolder("X/src/com/example/x"); |
| createFile("X/src/com/example/x/X.java", |
| "package com.example.x;\n" + |
| "public class X {\n" + |
| " public static void main(String[] args) { \n" + |
| " System.out.println(\"X\");\n" + |
| " }\n" + |
| "}\n"); |
| createFile("X/src/module-info.java", |
| "open module com.example.x {\n" + |
| " exports com.example.x;\n" + |
| " requires w;\n" + |
| "}\n"); |
| |
| // ------ Y ------ |
| addModularLibraryEntry(y, wJarPath, null); |
| addModularProjectEntry(y, x); |
| createFolder("Y/src/com/example/y"); |
| createFile("Y/src/com/example/y/Y.java", |
| "package com.example.y;\n" + |
| "public class Y {\n" + |
| " public static void main(String[] args) { \n" + |
| " System.out.println(\"Y\");\n" + |
| " }\n" + |
| "}\n"); |
| createFile("Y/src/module-info.java", |
| "open module com.example.y {\n" + |
| " exports com.example.y;\n" + |
| " requires com.example.x;\n" + |
| "}\n"); |
| |
| // ------ N ------ |
| createFolder("N/src/com/example/n"); |
| createFile("N/src/com/example/n/N.java", |
| "package com.example.n;\n" + |
| "public class N {\n" + |
| " public static void main(String[] args) { \n" + |
| " System.out.println(\"N\");\n" + |
| " } \n" + |
| "}\n"); |
| createFile("N/src/module-info.java", |
| "open module n {\n" + |
| " exports com.example.n;\n" + |
| "}\n"); |
| |
| // ------ M ------ |
| // insert new entries before JRE: |
| IClasspathEntry[] entries = m.getRawClasspath(); |
| int length = entries.length; |
| System.arraycopy(entries, 0, entries = new IClasspathEntry[length + 4], 4, length); |
| entries[0] = entries[4]; |
| entries[1] = newModularLibraryEntry(wJarPath, null, null); |
| entries[2] = newModularProjectEntry(n); |
| entries[3] = newModularProjectEntry(x); |
| entries[4] = newModularProjectEntry(y); |
| m.setRawClasspath(entries, null); |
| |
| createFolder("M/src/m"); |
| String mSource = |
| "package m;\n" + |
| "import com.example.n.N;\n" + |
| "public class M {\n" + |
| " public static void main(String[] args) {\n" + |
| " System.out.println(\"M\");\n" + |
| " N.main(null);\n" + |
| " }\n" + |
| "}\n"; |
| String mPath = "M/src/m/M.java"; |
| createFile(mPath, mSource); |
| createFile("M/src/module-info.java", |
| "open module m {\n" + |
| " requires n;\n" + |
| " requires w;\n" + |
| "}\n"); |
| |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| |
| m.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| |
| this.problemRequestor.initialize(mSource.toCharArray()); |
| getCompilationUnit(mPath).getWorkingCopy(this.wcOwner, null); |
| assertProblems("unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject(m); |
| deleteProject(n); |
| deleteProject(x); |
| deleteProject(y); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| |
| public void testBug544126() throws CoreException, IOException { |
| String outputDirectory = Util.getOutputDirectory(); |
| IJavaProject p = createJava9Project("p"); |
| try { |
| String jar1Path = outputDirectory + File.separator + "auto1Lib.jar"; |
| createJar( |
| new String[] { |
| "org/test/Root.java", |
| "package org.test;\n" + |
| "public class Root {}\n" |
| }, |
| jar1Path); |
| String jar2Path = outputDirectory + File.separator + "auto2Lib.jar"; |
| createJar( |
| new String[] { |
| "org/test/ext/Ext.java", |
| "package org.test.ext;\n" + |
| "public class Ext {}\n" |
| }, |
| jar2Path); |
| addModularLibraryEntry(p, new Path(jar1Path), null); |
| addModularLibraryEntry(p, new Path(jar2Path), null); |
| createFolder("p/src/test"); |
| String testPath = "p/src/test/Test.java"; |
| String testSource = |
| "package test;\n" + |
| "import org.test.Root;\n" + |
| "public class Test {\n" + |
| " public static void main(String[] args) { \n" + |
| " System.out.println(new Root());\n" + |
| " }\n" + |
| "}\n"; |
| createFile(testPath, testSource); |
| createFile("p/src/module-info.java", |
| "module test {\n" + |
| " requires auto1Lib;\n" + |
| " requires auto2Lib;\n" + |
| "}\n"); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| |
| this.problemRequestor.initialize(testSource.toCharArray()); |
| getCompilationUnit(testPath).getWorkingCopy(this.wcOwner, null); |
| assertProblems("unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| |
| public void testBug544432() throws CoreException { |
| IJavaProject prjA = createJava9Project("A"); |
| IJavaProject prjB = createJava9Project("B"); |
| try { |
| createFolder("A/src/com/a"); |
| createFile("A/src/com/a/A.java", |
| "package com.a;\n" + |
| "\n" + |
| "public class A {}\n"); |
| createFile("A/src/module-info.java", |
| "open module com.a {\n" + |
| " exports com.a;\n" + |
| "}\n"); |
| |
| addModularProjectEntry(prjB, prjA); |
| createFolder("B/src/com/a/b"); |
| String bPath = "B/src/com/a/b/B.java"; |
| String bSource = |
| "package com.a.b;\n" + |
| "import com.a.A;\n" + |
| "public class B {\n" + |
| " \n" + |
| " public static void main(String[] args) {\n" + |
| " A a = new A();\n" + |
| " System.out.println(a);\n" + |
| " }\n" + |
| "}\n"; |
| createFile(bPath, bSource); |
| createFile("B/src/module-info.java", |
| "open module com.a.b {\n" + |
| " requires com.a;\n" + |
| "}\n"); |
| getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| assertNoErrors(); |
| |
| this.problemRequestor.initialize(bSource.toCharArray()); |
| getCompilationUnit(bPath).getWorkingCopy(this.wcOwner, null); |
| assertProblems("unexpected problems", |
| "----------\n" + |
| "----------\n", |
| this.problemRequestor); |
| } finally { |
| deleteProject(prjA); |
| deleteProject(prjB); |
| } |
| } |
| |
| public void testReleaseOption1() throws Exception { |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "public class X {\n" + |
| "}"; |
| String mPath = "p/src/X.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption2() throws Exception { |
| if (!isJRE12) |
| return; |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_6); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "public class X {\n" + |
| " public java.util.stream.Stream<String> emptyStream() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}"; |
| String mPath = "p/src/X.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "The project was not built due to \"release 6 is not found in the system\". " |
| + "Fix the problem, then try refreshing this project and building it since it may be inconsistent", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption3() throws Exception { |
| if (isJRE12) |
| return; |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "public class X {\n" + |
| " public java.util.stream.Stream<String> emptyStream() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}"; |
| String mPath = "p/src/X.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "java.util.stream.Stream cannot be resolved to a type", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption4() throws Exception { |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "public class X {\n" + |
| " public java.util.stream.Stream<String> emptyStream() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}"; |
| String mPath = "p/src/X.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption5() throws Exception { |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "public class X {\n" + |
| " public java.util.stream.Stream<String> emptyStream() {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}"; |
| String mPath = "p/src/X.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "java.util.stream.Stream cannot be resolved to a type", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption6() throws Exception { |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "interface I {\n" + |
| " int add(int x, int y);\n" + |
| "}\n" + |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " I i = (x, y) -> {\n" + |
| " return x + y;\n" + |
| " };\n" + |
| " }\n" + |
| "}\n"; |
| String mPath = "p/src/X.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "Lambda expressions are allowed only at source level 1.8 or above", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption7() throws Exception { |
| if (isJRE12) |
| return; |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_6); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "import java.io.*;\n" + |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " try {\n" + |
| " System.out.println();\n" + |
| " Reader r = new FileReader(args[0]);\n" + |
| " r.read();\n" + |
| " } catch(IOException | FileNotFoundException e) {\n" + |
| " e.printStackTrace();\n" + |
| " }\n" + |
| " }\n" + |
| "}"; |
| String mPath = "p/src/X.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| assertMarkers("Unexpected markers", |
| "Multi-catch parameters are not allowed for source level below 1.7\n" + |
| "The exception FileNotFoundException is already caught by the alternative IOException", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption8() throws Exception { |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_9); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_9); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_9); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "module mod.one { \n" + |
| " requires java.base;\n" + |
| "}"; |
| String mPath = "p/src/module-info.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption9() throws Exception { |
| if (!isJRE10) return; |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_10); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_10); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_10); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "module mod.one { \n" + |
| " requires java.base;\n" + |
| "}"; |
| String mPath = "p/src/module-info.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption10() throws Exception { |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "module mod.one { \n" + |
| " requires java.base;\n" + |
| "}"; |
| String mPath = "p/src/module-info.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| sortMarkers(markers); |
| String expected = |
| "Syntax error on token \"module\", package expected\n" + |
| "Syntax error on token(s), misplaced construct(s)\n" + |
| "Syntax error on token \".\", , expected\n" + |
| "Syntax error on token \"}\", delete this token"; |
| assertMarkers("Unexpected markers", |
| expected, markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption11() throws Exception { |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| createFolder("p/src/foo"); |
| createFile( |
| "p/src/foo/Module.java", |
| "package foo;\n" + |
| "public class Module {}\n"); |
| createFile( |
| "p/src/foo/X.java", |
| "package foo;\n" + |
| "public class X { \n" + |
| " public Module getModule(String name) {\n" + |
| " return null;\n" + |
| " }\n" + |
| "}"); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption12() throws Exception { |
| if (!isJRE12) |
| return; |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "import java.io.*;\n" + |
| "\n" + |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " String str = Integer.toUnsignedString(1, 1);\n" + |
| " }\n" + |
| "}"; |
| String mPath = "p/src/X.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "The method toUnsignedString(int, int) is undefined for the type Integer", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testReleaseOption13() throws Exception { |
| if (!isJRE12) |
| return; |
| Hashtable<String, String> options = JavaCore.getOptions(); |
| IJavaProject p = createJava9Project("p"); |
| p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8); |
| p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED); |
| String outputDirectory = Util.getOutputDirectory(); |
| try { |
| String testSource = "\n" + |
| "public class X {\n" + |
| " public static void main(String[] args) {\n" + |
| " Integer.toUnsignedString(1, 1);\n" + |
| " }\n" + |
| "}"; |
| String mPath = "p/src/X.java"; |
| createFile(mPath, |
| testSource); |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| assertMarkers("Unexpected markers", |
| "", markers); |
| |
| } finally { |
| JavaCore.setOptions(options); |
| deleteProject(p); |
| File outputDir = new File(outputDirectory); |
| if (outputDir.exists()) |
| Util.flushDirectoryContent(outputDir); |
| } |
| } |
| public void testBug547114a() throws CoreException, IOException { |
| String outputDirectory = Util.getOutputDirectory(); |
| String jarPath = outputDirectory + File.separator + "lib.jar"; |
| try { |
| // focus project has no module-info, to trigger path where LE#knownPackages is not empty when processing add-reads |
| String[] sources = new String[] { |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "import p.C;\n" + |
| "public class World {\n" + |
| " C f;\n" + |
| "}\n" |
| }; |
| IJavaProject p = setupModuleProject("org.astro", sources); |
| |
| Util.createJar(new String[] { |
| "/lib/src/module-info.java", |
| "module lib {\n" + |
| " exports p;\n" + |
| "}\n", |
| "/lib/src/p/C.java", |
| "package p;\n" + |
| "public class C {}\n", |
| }, |
| jarPath, |
| "9"); |
| addClasspathEntry(p, JavaCore.newLibraryEntry(new Path(jarPath), null, null, null, |
| new IClasspathAttribute[] { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"), |
| JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_READS, "lib=missing.module") // problematic directive on jar-dependency |
| }, |
| false)); |
| |
| p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); |
| waitForAutoBuild(); |
| |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| // 1. marker is on the project, second on the "current" CU: World.java. |
| assertMarkers("Unexpected markers", |
| "The project was not built since its build path has a problem: missing.module cannot be resolved to a module, it is referenced from an add-reads directive. Fix the build path then try building this project\n" + |
| "missing.module cannot be resolved to a module, it is referenced from an add-reads directive", |
| markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteFile(jarPath); |
| } |
| } |
| public void testBug547114b() throws CoreException, IOException { |
| try { |
| IJavaProject p = setupModuleProject("org.astro", new String[] { |
| "src/module-info.java", |
| "module org.astro {\n" + |
| " requires lib;\n" + |
| "}\n", |
| "src/org/astro/World.java", |
| "package org.astro;\n" + |
| "import p.C;\n" + |
| "public class World {\n" + |
| " C f;\n" + |
| "}\n" |
| }); |
| |
| IJavaProject lib = setupModuleProject("lib", new String[] { |
| "src/module-info.java", |
| "module lib {\n" + |
| " exports p;\n" + |
| "}\n", |
| "src/p/C.java", |
| "package p;\n" + |
| "public class C {}\n", |
| }); |
| addClasspathEntry(p, JavaCore.newProjectEntry(lib.getPath(), null, false, |
| new IClasspathAttribute[] { |
| JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"), |
| JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_READS, "lib=missing.module") // problematic directive on project dependency |
| }, |
| false)); |
| |
| ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); |
| waitForAutoBuild(); |
| |
| IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); |
| // 1. marker is on the project, second on the "current" CU: World.java. |
| assertMarkers("Unexpected markers", |
| "The project was not built since its build path has a problem: missing.module cannot be resolved to a module, it is referenced from an add-reads directive. Fix the build path then try building this project\n" + |
| "missing.module cannot be resolved to a module, it is referenced from an add-reads directive", |
| markers); |
| } finally { |
| deleteProject("org.astro"); |
| deleteProject("lib"); |
| } |
| } |
| protected void assertNoErrors() throws CoreException { |
| for (IProject p : getWorkspace().getRoot().getProjects()) { |
| int maxSeverity = p.findMaxProblemSeverity(null, true, IResource.DEPTH_INFINITE); |
| if (maxSeverity == IMarker.SEVERITY_ERROR) { |
| for (IMarker marker : p.findMarkers(null, true, IResource.DEPTH_INFINITE)) |
| System.err.println("Marker "+ marker.toString()); |
| } |
| assertFalse("Unexpected errors in project " + p.getName(), maxSeverity == IMarker.SEVERITY_ERROR); |
| } |
| } |
| // sort by CHAR_START then MESSAGE |
| protected void sortMarkers(IMarker[] markers) { |
| Arrays.sort(markers, Comparator.comparingInt((IMarker a) -> a.getAttribute(IMarker.CHAR_START, 0)) |
| .thenComparing((IMarker a) -> a.getAttribute(IMarker.MESSAGE, ""))); |
| } |
| } |