[323174] Existence of classpath dependencies should not break single-root
diff --git a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/AllTests.java b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/AllTests.java index b7cdc7a..3fee11e 100644 --- a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/AllTests.java +++ b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/AllTests.java
@@ -22,8 +22,7 @@ suite.addTest(ClasspathDependencyCreationTests.suite()); //suite.addTest(ClasspathDependencyValidationTests.suite()); suite.addTest(ClasspathDependencyEARTests.suite()); - //[Bug 234409] Temporarily removing these tests until underlying issue is fixed -// suite.addTest(ClasspathDependencyWebTests.suite()); + suite.addTest(ClasspathDependencyWebTests.suite()); return suite; }
diff --git a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/ClasspathDependencyEARTests.java b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/ClasspathDependencyEARTests.java index 2a6adc9..adb15ed 100644 --- a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/ClasspathDependencyEARTests.java +++ b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/ClasspathDependencyEARTests.java
@@ -70,6 +70,7 @@ //suite.addTest(new ClasspathDependencyEARTests("testEARExportJEE5")); suite.addTest(new ClasspathDependencyEARTests("testEARPublishJ2EE")); suite.addTest(new ClasspathDependencyEARTests("testEARPublishJEE5")); + suite.addTest(new ClasspathDependencyEARTests("testEARLibPublishJEE5")); return suite; } @@ -189,6 +190,10 @@ testEARPublish(true); } + public void testEARLibPublishJEE5() throws Exception { + testEARLibPublishJEE5(true); + } + private void testEARPublish(boolean JEE5) throws Exception { // create the EAR and module projects @@ -214,19 +219,41 @@ verifyPublishedEAR(earComp, archiveNames, true, JEE5); } + private void testEARLibPublishJEE5(boolean JEE5) throws Exception { + IVirtualComponent webComp = createWebProject(JEE5); + + final Set archiveNames = new HashSet(); + archiveNames.add(ClasspathDependencyTestUtil.TEST1_JAR); + archiveNames.add(ClasspathDependencyTestUtil.TEST2_JAR); + final IProject earProject = ProjectUtil.getProject(EAR_PROJECT); + final IVirtualComponent earComp = ComponentCore.createComponent(earProject); + + verifyPublishedEARLibRef(earComp, archiveNames, false, JEE5); + + addEARLibDependencyAttribute(false); + + verifyPublishedEARLibRef(earComp, archiveNames, true, JEE5); + } + private void verifyPublishedEAR(final IVirtualComponent comp, final Set archiveNames, final boolean shouldHaveDependencies, boolean isEE5) throws Exception { // verify that the published EAR contains the cp container jars from the Utility J2EEFlexProjDeployable deployable = new J2EEFlexProjDeployable(comp.getProject(), comp); try { IModuleResource[] rootmembers = deployable.members(); - IModuleResource[] members; - if (isEE5 && rootmembers.length > 0 && rootmembers[0].getName().equals("lib")) { - members = ((IModuleFolder) rootmembers[0]).members(); + IModuleResource[] members = null; + if (isEE5) { + for (int i=0; i<rootmembers.length; i++) { + String name = rootmembers[i].getName(); + if (name.equals("lib")) { + members = ((IModuleFolder)rootmembers[i]).members(); + } + } } - else { + + if (members == null) members = rootmembers; - } + Iterator it = archiveNames.iterator(); while (it.hasNext()) { String name = (String) it.next(); @@ -354,6 +381,105 @@ } } +private void verifyPublishedEARLibRef(final IVirtualComponent comp, final Set archiveNames, final boolean shouldHaveDependencies, boolean isEE5) throws Exception { + + J2EEFlexProjDeployable deployable = new J2EEFlexProjDeployable(comp.getProject(), comp); + try { + IModuleResource[] rootmembers = deployable.members(); + IModuleResource[] members = null; + if (isEE5) { + for (int i=0; i<rootmembers.length; i++) { + String name = rootmembers[i].getName(); + if (name.equals("lib")) { + members = ((IModuleFolder)rootmembers[i]).members(); + } + } + } + + if (members == null) + members = rootmembers; + + Iterator it = archiveNames.iterator(); + while (it.hasNext()) { + String name = (String) it.next(); + boolean hasArchive = false; + for (int i=0; i<members.length; i++) { + if (members[i].getName().equals(name)) { + hasArchive = true; + } + } + if (shouldHaveDependencies) { + assertTrue("Published EAR missing classpath dependency Jar " + name, hasArchive); + } else { + assertFalse("Published EAR has unexpected classpath dependency Jar " + name, hasArchive); + } + } + + IModule webModule = null; + IModule[] childModules = deployable.getChildModules(); + for (int i=0; i < childModules.length; i++) { + if (childModules[i].getName().equals(WEB_PROJECT)) { + webModule = childModules[i]; + } + } + + assertNotNull("Missing entry for web project", webModule); + + J2EEFlexProjDeployable projectModule =(J2EEFlexProjDeployable) webModule.loadAdapter(ProjectModule.class, null); + IModuleResource[] moduleMembers = projectModule.members(); + ArchiveManifest manifest = null; + boolean foundMetaInf = false; + for (int i=0; i< moduleMembers.length; i++) { + String name = moduleMembers[i].getName(); + if (name.equals("META-INF")) { + foundMetaInf = true; + IModuleResource manifestResource= ((IModuleFolder)moduleMembers[i]).members()[0]; + assertTrue(manifestResource.getModuleRelativePath().toString().equals("META-INF")); + assertTrue("Expected MANIFEST.MF, got " + manifestResource.getName(), manifestResource.getName().equals("MANIFEST.MF")); + java.io.File manifestFile = (java.io.File) manifestResource.getAdapter(java.io.File.class); + if (manifestFile == null) { + manifestFile = ((IFile) manifestResource.getAdapter(IFile.class)).getLocation().toFile(); + } + assertNotNull(manifestFile); + FileInputStream fis = null; + try { + fis = new FileInputStream(manifestFile); + manifest = new ArchiveManifestImpl(fis); + } finally { + if (fis != null) { + fis.close(); + } + } + } + } + if (!foundMetaInf) { + assertTrue("members() failed to return META-INF for web project module in published EAR", foundMetaInf); + } + + assertNotNull("Failed to retrieve MANIFEST.MF from web project module in published EAR", manifest); + + it = archiveNames.iterator(); + while (it.hasNext()) { + String name = (String) it.next(); + boolean isOnCP = false; + String[] cp = manifest.getClassPathTokenized(); + for (int j = 0; j < cp.length; j++) { + if (cp[j].equals("lib/" + name)) { + isOnCP = true; + } + } + if (shouldHaveDependencies && ClasspathDependencyEnablement.isAllowClasspathComponentDependency()) { + assertTrue("Utility project MANIFEST.MF classpath in published EAR missing entry for dependency Jar " + name, isOnCP); + } else { + assertFalse("Utility project MANIFEST.MF classpath in published EAR has unexpected entry for dependency Jar " + name, isOnCP); + } + } + + } catch (CoreException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } private IVirtualComponent createProjects(boolean JEE5) throws Exception { @@ -395,14 +521,29 @@ return webComp; } + + private IVirtualComponent createWebProject(boolean JEE5) throws Exception { + // create a Web project + int version = J2EEVersionConstants.SERVLET_2_5; + if (!JEE5) { + version = J2EEVersionConstants.SERVLET_2_4; + } + final IProject webProject = ProjectUtil.createWebProject(WEB_PROJECT, EAR_PROJECT, version, true); + final IJavaProject webJavaProject = JavaCore.create(webProject); + final IVirtualComponent webComp = ComponentCore.createComponent(webProject); + + // add a cp dependency to the Utility + ClasspathDependencyTestUtil.addCustomClasspathContainer(webJavaProject); + + return webComp; + } /** * * @param verifyClasspathDependencies - true if you want to immediately verify that * the classpath dependencies were added. Set to false if you want to verify this at - * a later time. Such as thru a members call in export or publish. - * Note: When set to true may fail a valid scenario due to JDT initialization issues. + * a later time (such as thru a members call in export or publish). * @throws Exception */ private void addDependencyAttribute(boolean verifyClasspathDependencies) throws Exception { @@ -464,4 +605,43 @@ if (verifyClasspathDependencies) ClasspathDependencyTestUtil.verifyClasspathDependencies(webComp, archiveNames); } + + /** + * + * @param verifyClasspathDependencies - true if you want to immediately verify that + * the classpath dependencies were added. Set to false if you want to verify this at + * a later time (such as thru a members call in export or publish) + * @throws Exception + */ + private void addEARLibDependencyAttribute(boolean verifyClasspathDependencies) throws Exception { + + final IProject web = ProjectUtil.getProject(WEB_PROJECT); + final IJavaProject webJava = JavaCore.create(web); + final IVirtualComponent webComp = ComponentCore.createComponent(web); + + final Set entryPaths = new HashSet(); + entryPaths.add(ClasspathDependencyTestUtil.CUSTOM_CLASSPATH_CONTAINER); + // verify that "bin" and the custom cp container are potential entries + List entries = ClasspathDependencyTestUtil.verifyPotentialClasspathEntries(webJava, entryPaths); + // verify that no entries have the classpath attribute + ClasspathDependencyTestUtil.verifyNoClasspathAttributes(webJava); + // verify that there are no classpath dependencies + ClasspathDependencyTestUtil.verifyNoClasspathDependencies(webComp); + IClasspathEntry entry = (IClasspathEntry) entries.get(0); + + // add the dependency attribute to "bin" and the cp container + for (Object o: entries) { + UpdateClasspathAttributeUtil.addDependencyAttribute(null, web.getName(), (IClasspathEntry) o, new Path("../lib")); + } + // should no longer have potential entries + ClasspathDependencyTestUtil.verifyNoPotentialClasspathEntries(webJava); + // verify that "bin" and the cp container have the attribute + ClasspathDependencyTestUtil.verifyClasspathAttributes(webJava, entryPaths); + // verify that "bin" and the cp container are dependencies + final Set archiveNames = new HashSet(); + archiveNames.add(ClasspathDependencyTestUtil.TEST1_JAR); + archiveNames.add(ClasspathDependencyTestUtil.TEST2_JAR); + if (verifyClasspathDependencies) + ClasspathDependencyTestUtil.verifyClasspathDependencies(webComp, archiveNames); + } }
diff --git a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/ClasspathDependencyWebTests.java b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/ClasspathDependencyWebTests.java index 9cca823..5688ec6 100644 --- a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/ClasspathDependencyWebTests.java +++ b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/j2ee/classpath/tests/ClasspathDependencyWebTests.java
@@ -15,6 +15,9 @@ import java.util.List; import java.util.Set; +import junit.framework.Test; +import junit.framework.TestSuite; + import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -35,12 +38,9 @@ import org.eclipse.jst.j2ee.web.componentcore.util.WebArtifactEdit; import org.eclipse.wst.common.componentcore.ComponentCore; import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; -import org.eclipse.wst.server.core.util.ModuleFolder; +import org.eclipse.wst.server.core.model.IModuleFolder; import org.eclipse.wst.server.core.model.IModuleResource; -import junit.framework.Test; -import junit.framework.TestSuite; - /** * Tests export and publish behavior for classpath component dependencies and web projects. */ @@ -60,6 +60,7 @@ //suite.addTest(new ClasspathDependencyWebTests("testWebExportJEE5")); suite.addTest(new ClasspathDependencyWebTests("testWebPublishJ2EE")); suite.addTest(new ClasspathDependencyWebTests("testWebPublishJEE5")); + suite.addTest(new ClasspathDependencyWebTests("testWebContainerPublishJEE5")); return suite; } @@ -83,7 +84,7 @@ verifyExportedWebInfLibs(webComp, archiveNames, false); // add the cp dependency attribute to the cp container in the util - addDependencyAttribute(); + addDependencyAttribute(false); // verify that the exported WAR WEB-INF/lib does contain the cp container jars from the Utility verifyExportedWebInfLibs(webComp, archiveNames, true); @@ -148,6 +149,10 @@ testWebPublish(true); } + public void testWebContainerPublishJEE5() throws Exception { + testWebContainerPublish(true); + } + private void testWebPublish(boolean JEE5) throws Exception { // create the web and utility projects @@ -160,14 +165,27 @@ verifyPublishedWebInfLibs(webComp, archiveNames, false); // add the cp dependency attribute to the cp container in the util - addDependencyAttribute(); + addDependencyAttribute(true); // verify that the exported WAR WEB-INF/lib does contain the cp container jars from the Utility verifyPublishedWebInfLibs(webComp, archiveNames, true); } + private void testWebContainerPublish(boolean JEE5) throws Exception { + IVirtualComponent webComp = createWebProject(JEE5); + + final Set archiveNames = new HashSet(); + archiveNames.add(ClasspathDependencyTestUtil.TEST1_JAR); + archiveNames.add(ClasspathDependencyTestUtil.TEST2_JAR); + + verifyPublishedWebInfContainer(webComp, archiveNames, false); + + addWebInfContainerDependencyAttribute(false); + + verifyPublishedWebInfContainer(webComp, archiveNames, true); + } + private void verifyPublishedWebInfLibs(final IVirtualComponent comp, final Set archiveNames, final boolean shouldHaveDependencies) throws Exception { - // verify that the published WAR's WEB-INF/lib contains the cp container jars from the Utility J2EEFlexProjDeployable deployable = new J2EEFlexProjDeployable(comp.getProject(), comp); try { @@ -177,12 +195,12 @@ for (int i=0; i<members.length; i++) { String name = members[i].getName(); if (name.equals("WEB-INF")) { - IModuleResource[] webInf = ((ModuleFolder)members[i]).members(); + IModuleResource[] webInf = ((IModuleFolder)members[i]).members(); for (int j=0; j<webInf.length; j++) { IModuleResource webResource = webInf[j]; assertTrue(webResource.getModuleRelativePath().toString().equals("WEB-INF")); if (webResource.getName().equals("lib")) { - IModuleResource[] webresMembers = ((ModuleFolder)webResource).members(); + IModuleResource[] webresMembers = ((IModuleFolder)webResource).members(); Iterator it = archiveNames.iterator(); while (it.hasNext()) { String archiveName = (String) it.next(); @@ -200,10 +218,10 @@ } } } else if (webResource.getName().equals("classes")) { - IModuleResource[] webresMembers = ((ModuleFolder)webResource).members(); + IModuleResource[] webresMembers = ((IModuleFolder)webResource).members(); for (j = 0; j < webresMembers.length; j++) { if (webresMembers[j].getName().equals("nested")) { - IModuleResource[] nestedMembers = ((ModuleFolder)webresMembers[j]).members(); + IModuleResource[] nestedMembers = ((IModuleFolder)webresMembers[j]).members(); assertTrue("Published WAR should have have nested folder without class folder dependency", shouldHaveDependencies); boolean hasNestedTest = false; if (nestedMembers.length == 1 && nestedMembers[0].getName().equals("test")) { @@ -227,6 +245,49 @@ } } + private void verifyPublishedWebInfContainer(final IVirtualComponent comp, final Set archiveNames, final boolean shouldHaveDependencies) throws Exception { + J2EEFlexProjDeployable deployable = new J2EEFlexProjDeployable(comp.getProject(), comp); + + try { + IModuleResource[] members = deployable.members(); + assertTrue(members.length==2); + + for (int i=0; i<members.length; i++) { + String name = members[i].getName(); + if (name.equals("WEB-INF")) { + IModuleResource[] webInf = ((IModuleFolder)members[i]).members(); + for (int j=0; j<webInf.length; j++) { + IModuleResource webResource = webInf[j]; + assertTrue(webResource.getModuleRelativePath().toString().equals("WEB-INF")); + if (webResource.getName().equals("lib")) { + IModuleResource[] webresMembers = ((IModuleFolder)webResource).members(); + Iterator it = archiveNames.iterator(); + while (it.hasNext()) { + String archiveName = (String) it.next(); + boolean hasArchive = false; + for (int k = 0; k < webresMembers.length; k++) { + String localName = webresMembers[k].getName(); + if (localName.equals(archiveName)) { + hasArchive= true; + } + } + if (shouldHaveDependencies) { + assertTrue("Published WAR missing classpath dependency Jar " + archiveName, hasArchive); + } else { + assertFalse("Published WAR has unexpected classpath dependency Jar " + archiveName, hasArchive); + } + } + } + } + } + } + + } catch (CoreException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + private IVirtualComponent createProjects(boolean JEE5) throws Exception { // create a Utility project final IProject util = ProjectUtil.createUtilityProject(UTIL_PROJECT, null, true); @@ -263,7 +324,30 @@ return webComp; } - private void addDependencyAttribute() throws Exception { + private IVirtualComponent createWebProject(boolean JEE5) throws Exception { + // create a Web project + int version = J2EEVersionConstants.SERVLET_2_5; + if (!JEE5) { + version = J2EEVersionConstants.SERVLET_2_4; + } + final IProject webProject = ProjectUtil.createWebProject(WEB_PROJECT, null, version, true); + final IJavaProject webJavaProject = JavaCore.create(webProject); + final IVirtualComponent webComp = ComponentCore.createComponent(webProject); + + // add a cp dependency to the Utility + ClasspathDependencyTestUtil.addCustomClasspathContainer(webJavaProject); + + return webComp; + } + + /** + * + * @param verifyClasspathDependencies - true if you want to immediately verify that + * the classpath dependencies were added. Set to false if you want to verify this at + * a later time (such as thru a members call in export or publish) + * @throws Exception + */ + private void addDependencyAttribute(boolean verifyClasspathDependencies) throws Exception { final IProject util = ProjectUtil.getProject(UTIL_PROJECT); final IJavaProject utilJava = JavaCore.create(util); final IVirtualComponent utilComp = ComponentCore.createComponent(util); @@ -308,4 +392,44 @@ archiveNames.add(fullWebBinPath.toString()); ClasspathDependencyTestUtil.verifyClasspathDependencies(webComp, archiveNames); } + + /** + * + * @param verifyClasspathDependencies - true if you want to immediately verify that + * the classpath dependencies were added. Set to false if you want to verify this at + * a later time (such as thru a members call in export or publish) + * @throws Exception + */ + private void addWebInfContainerDependencyAttribute(boolean verifyClasspathDependencies) throws Exception { + + final IProject web = ProjectUtil.getProject(WEB_PROJECT); + final IJavaProject webJava = JavaCore.create(web); + final IVirtualComponent webComp = ComponentCore.createComponent(web); + + final Set entryPaths = new HashSet(); + entryPaths.add(ClasspathDependencyTestUtil.CUSTOM_CLASSPATH_CONTAINER); + // verify that "bin" and the custom cp container are potential entries + List entries = ClasspathDependencyTestUtil.verifyPotentialClasspathEntries(webJava, entryPaths); + // verify that no entries have the classpath attribute + ClasspathDependencyTestUtil.verifyNoClasspathAttributes(webJava); + // verify that there are no classpath dependencies + ClasspathDependencyTestUtil.verifyNoClasspathDependencies(webComp); + IClasspathEntry entry = (IClasspathEntry) entries.get(0); + + // add the dependency attribute to "bin" and the cp container + for (Object o: entries) { + UpdateClasspathAttributeUtil.addDependencyAttribute(null, web.getName(), (IClasspathEntry) o); + } + // should no longer have potential entries + ClasspathDependencyTestUtil.verifyNoPotentialClasspathEntries(webJava); + // verify that "bin" and the cp container have the attribute + ClasspathDependencyTestUtil.verifyClasspathAttributes(webJava, entryPaths); + // verify that "bin" and the cp container are dependencies + final Set archiveNames = new HashSet(); + archiveNames.add(ClasspathDependencyTestUtil.TEST1_JAR); + archiveNames.add(ClasspathDependencyTestUtil.TEST2_JAR); + if (verifyClasspathDependencies) + ClasspathDependencyTestUtil.verifyClasspathDependencies(webComp, archiveNames); + } + }