diff options
author | Andrew Niefer | 2011-03-29 20:18:18 +0000 |
---|---|---|
committer | Andrew Niefer | 2011-03-29 20:18:18 +0000 |
commit | 97f2679658e469a116525e4538505b18f279b5b4 (patch) | |
tree | 571c9e7d3305c24793220b36b7ac8c1bcff1ab26 | |
parent | b747a91b877dd64240ec1a3806a8b0c7c480a3e4 (diff) | |
download | eclipse.pde.build-97f2679658e469a116525e4538505b18f279b5b4.tar.gz eclipse.pde.build-97f2679658e469a116525e4538505b18f279b5b4.tar.xz eclipse.pde.build-97f2679658e469a116525e4538505b18f279b5b4.zip |
Bug 157375 - PDE should support building against nested JARsv20110330publisher_incubator_before_merge
7 files changed, 248 insertions, 45 deletions
diff --git a/org.eclipse.pde.build.tests/src/org/eclipse/pde/build/internal/tests/ScriptGenerationTests.java b/org.eclipse.pde.build.tests/src/org/eclipse/pde/build/internal/tests/ScriptGenerationTests.java index 991eea92..66b96f16 100644 --- a/org.eclipse.pde.build.tests/src/org/eclipse/pde/build/internal/tests/ScriptGenerationTests.java +++ b/org.eclipse.pde.build.tests/src/org/eclipse/pde/build/internal/tests/ScriptGenerationTests.java @@ -2153,4 +2153,86 @@ public class ScriptGenerationTests extends PDETestCase { Utils.storeBuildProperties(buildFolder, properties); runBuild(buildFolder); } + + public void testBug157375_NestedJars() throws Exception { + IFolder root = newTest("157375"); + IFolder buildFolder = Utils.createFolder(root, "first"); + + IFolder host = Utils.createFolder(buildFolder, "plugins/Host"); + Attributes additional = new Attributes(); + additional.put(new Attributes.Name("Bundle-Classpath"), "a.jar, c.jar"); + Utils.generateBundleManifest(host, "Host", "1.0.0", additional); + Properties properties = new Properties(); + properties.put("source.a.jar", "src_a"); + properties.put("source.b.jar", "src_b"); + properties.put("bin.includes", "META-INF/, a.jar, b.jar"); + Utils.storeBuildProperties(host, properties); + + StringBuffer buffer = new StringBuffer(); + buffer.append("package a; \n"); + buffer.append("public class A { } \n"); + Utils.writeBuffer(host.getFile("src_a/a/A.java"), buffer); + + buffer = new StringBuffer(); + buffer.append("package b; \n"); + buffer.append("public class B { } \n"); + Utils.writeBuffer(host.getFile("src_b/b/B.java"), buffer); + + IFolder fragment = Utils.createFolder(buildFolder, "plugins/fragment"); + additional = new Attributes(); + additional.put(new Attributes.Name("Fragment-Host"), "Host"); + Utils.generateBundleManifest(fragment, "fragment", "1.0.0", additional); + properties = new Properties(); + properties.put("source.c.jar", "src_c"); + properties.put("bin.includes", "META-INF/, c.jar"); + Utils.storeBuildProperties(fragment, properties); + + buffer = new StringBuffer(); + buffer.append("package c; \n"); + buffer.append("public class C { } \n"); + Utils.writeBuffer(fragment.getFile("src_c/c/C.java"), buffer); + + Utils.generateFeature(buildFolder, "F", null, new String[] {"Host", "fragment"}); + + properties = BuildConfiguration.getBuilderProperties(buildFolder); + properties.put("topLevelElementId", "F"); + properties.put("p2.gathering", "true"); + properties.put("baseLocation", ""); + Utils.storeBuildProperties(buildFolder, properties); + + runBuild(buildFolder); + + IFolder second = Utils.createFolder(root, "second"); + IFolder plugins = Utils.createFolder(second, "target/plugins"); + buildFolder.getFile("buildRepo/plugins/fragment_1.0.0.jar").getLocation().toFile().renameTo(plugins.getFile("Host_1.0.0.jar").getLocation().toFile()); + + Utils.generateFeature(second, "F", null, new String[] {"D"}); + + IFolder d = Utils.createFolder(second, "plugins/d"); + additional = new Attributes(); + additional.put(new Attributes.Name("Require-Bundle"), "Host"); + Utils.generateBundleManifest(d, "D", "1.0.0", additional); + properties = new Properties(); + properties.put("jars.extra.classpath", "platform:/plugin/Host/b.jar"); + Utils.generatePluginBuildProperties(d, properties); + + buffer = new StringBuffer(); + buffer.append("package d; \n"); + buffer.append("import a.A; \n"); + buffer.append("import b.B; \n"); + buffer.append("import c.C; \n"); + buffer.append("public class D { \n"); + buffer.append(" public A a = new A(); \n"); + buffer.append(" public B b = new B(); \n"); + buffer.append(" public C c = new C(); \n"); + buffer.append("} \n"); + Utils.writeBuffer(d.getFile("src/d/D.java"), buffer); + + properties = BuildConfiguration.getBuilderProperties(second); + properties.put("topLevelElementId", "F"); + properties.put("pluginPath", buildFolder.getFolder("buildRepo").getLocation().toOSString()); + properties.put("baseLocation", second.getFolder("target").getLocation().toOSString()); + Utils.storeBuildProperties(second, properties); + runBuild(second); + } } diff --git a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/BuildScriptGenerator.java b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/BuildScriptGenerator.java index 6f4ce13f..449643ad 100644 --- a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/BuildScriptGenerator.java +++ b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/BuildScriptGenerator.java @@ -89,7 +89,7 @@ public class BuildScriptGenerator extends AbstractScriptGenerator { // the default id is a generic feature name as uber source features have no inherent // semantics or scope. private String sourceBundleTemplateFeature = "org.eclipse.pde.build.uber.feature"; //$NON-NLS-1$ - private String sourceBundleFeatureId = null; //default is sourceBundleTemplateFeature + ".source" + private String sourceBundleFeatureId = null; //default is sourceBundleTemplateFeature + ".source" // the default version is simply time-based as uber source features have no inherent // semantics or scope. @@ -164,7 +164,7 @@ public class BuildScriptGenerator extends AbstractScriptGenerator { String[] modelInfo = getNameAndVersion((String) iterator.next()); generator.setBuildSiteFactory(siteFactory); generator.setModelId(modelInfo[0], modelInfo[1]); - + generator.setFeatureGenerator(new BuildDirector()); generator.setPluginPath(pluginPath); generator.setDevEntries(devEntries); generator.setCompiledElements(generator.getCompiledElements()); @@ -181,7 +181,7 @@ public class BuildScriptGenerator extends AbstractScriptGenerator { //Filtering is not required here, since we are only generating the build for a plugin or a fragment generator.setBuildSiteFactory(siteFactory); generator.setModel(bundlesToBuild[i]); - + generator.setFeatureGenerator(new BuildDirector()); generator.setPluginPath(pluginPath); generator.setDevEntries(devEntries); generator.setCompiledElements(generator.getCompiledElements()); diff --git a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/IXMLConstants.java b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/IXMLConstants.java index b083281a..b8c7ffbe 100644 --- a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/IXMLConstants.java +++ b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/IXMLConstants.java @@ -50,6 +50,7 @@ public interface IXMLConstants { public static final String TARGET_ASSEMBLE_ARCHIVE_CONDITION = "assemble.archive.condition"; //$NON-NLS-1$ public static final String TARGET_CLEANUP_ASSEMBLY = "cleanup.assembly"; //$NON-NLS-1$ public static final String TARGET_COPY_SRC_INCLUDES = "copy.src.includes"; //$NON-NLS-1$ + public static final String TARGET_NESTED_JARS = ".nestedJars"; //$NON-NLS-1$ public static final String TARGET_INIT = "init"; //$NON-NLS-1$ public static final String TARGET_MAIN = "main"; //$NON-NLS-1$ public static final String TARGET_GZIP_RESULTS = "gzipResults"; //$NON-NLS-1$ diff --git a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/ant/AntScript.java b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/ant/AntScript.java index 04cdc3cb..ecc81243 100644 --- a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/ant/AntScript.java +++ b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/ant/AntScript.java @@ -378,6 +378,28 @@ public class AntScript implements IAntScript { } } + public void printUnzipTask(String zipFile, String destDir, boolean overWrite, String includePatterns, String excludePatterns) { + printTab(); + output.print("<unzip"); //$NON-NLS-1$ + printAttribute("src", zipFile, true); //$NON-NLS-1$ + printAttribute("dest", destDir, true); //$NON-NLS-1$ + printAttribute("overwrite", Boolean.toString(overWrite), true); //$NON-NLS-1$ + if (includePatterns == null && excludePatterns == null) { + output.println("/>"); //$NON-NLS-1$ + } else { + output.println(">"); //$NON-NLS-1$ + indent++; + printTab(); + output.print("<patternset"); //$NON-NLS-1$ + printAttribute("includes", includePatterns, false); //$NON-NLS-1$ + printAttribute("excludes", excludePatterns, false); //$NON-NLS-1$ + output.println("/>"); //$NON-NLS-1$ + indent--; + printTab(); + output.println("</unzip>"); //$NON-NLS-1$ + } + } + public void printTarTask(String zipfile, String basedir, boolean filesOnly, boolean update, FileSet[] fileSets) { printTab(); output.print("<tar"); //$NON-NLS-1$ diff --git a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/BuildDirector.java b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/BuildDirector.java index 9019681b..dab255e0 100644 --- a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/BuildDirector.java +++ b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/BuildDirector.java @@ -10,11 +10,13 @@ *******************************************************************************/ package org.eclipse.pde.internal.build.builder; +import java.io.File; import java.util.*; import org.eclipse.core.runtime.*; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.util.NLS; import org.eclipse.pde.internal.build.*; +import org.eclipse.pde.internal.build.builder.ClasspathComputer3_0.ClasspathElement; import org.eclipse.pde.internal.build.site.BuildTimeFeature; import org.eclipse.pde.internal.build.site.compatibility.Feature; import org.eclipse.pde.internal.build.site.compatibility.FeatureEntry; @@ -78,6 +80,30 @@ public class BuildDirector extends AbstractBuildScriptGenerator { this.assemblyData = assemblageInformation; } + private final Map extractedLocations = new HashMap(); + + public String getExtractedRoot(ClasspathElement element) { + if (element.getSubPath() == null) + return element.getPath(); + + String absolute = element.getAbsolutePath(); + if (extractedLocations.containsKey(absolute)) { + return (String) extractedLocations.get(absolute); + } + + //Use the jar name, append a suffix if that name is already taken + String name = new File(absolute).getName(); + if (name.endsWith(".jar")) //$NON-NLS-1$ + name = name.substring(0, name.length() - 4); + String destination = name; + while (extractedLocations.containsValue(destination)) { + destination = name + '_' + Integer.toHexString(destination.hashCode()); + } + + extractedLocations.put(absolute, destination); + return destination; + } + /** * Returns a list of BundleDescription objects representing the elements delivered by the feature. * diff --git a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer3_0.java b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer3_0.java index a3afbea0..e667a5c6 100644 --- a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer3_0.java +++ b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer3_0.java @@ -25,8 +25,9 @@ import org.eclipse.pde.internal.build.site.compatibility.FeatureEntry; import org.osgi.framework.Filter; public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConstants, IXMLConstants, IBuildPropertiesConstants { - public static class ClasspathElement { + public class ClasspathElement { private final String path; + private final String subPath; private String accessRules; /** @@ -35,8 +36,11 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta * @param accessRules * @throws NullPointerException if path is null */ - public ClasspathElement(String path, String accessRules) { + protected ClasspathElement(String path, String subPath, String accessRules) { + if (path == null) + throw new NullPointerException(); this.path = path; + this.subPath = subPath; this.accessRules = accessRules; } @@ -48,10 +52,21 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta return path; } + public String getSubPath() { + return subPath; + } + public String getAccessRules() { return accessRules; } + public String getAbsolutePath() { + if (new File(path).isAbsolute()) + return path; + + return modelLocation + '/' + path; + } + public void addRules(String newRule) { if (accessRules.equals("") || accessRules.equals(newRule)) //$NON-NLS-1$ return; @@ -70,19 +85,26 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta public boolean equals(Object obj) { if (obj instanceof ClasspathElement) { ClasspathElement element = (ClasspathElement) obj; - return (path != null && path.equals(element.getPath())); + if (!path.equals(element.getPath())) + return false; + if (subPath != null && subPath.equals(element.getSubPath())) + return false; + return true; } return false; } public int hashCode() { - return path.hashCode(); + int result = path.hashCode(); + return 13 * result + ((subPath == null) ? 0 : subPath.hashCode()); } - public static String normalize(String path) { - //always use '/' as a path separator to help with comparing paths in equals - return path.replaceAll("\\\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$ - } + } + private static String normalize(String path) { + if (path == null) + return null; + //always use '/' as a path separator to help with comparing paths in equals + return path.replaceAll("\\\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$ } private static final String EXCLUDE_ALL_RULE = "?**/*"; //$NON-NLS-1$ @@ -92,6 +114,7 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta private Map pathElements = null; private boolean allowBinaryCycles = false; private Set requiredIds = null; + protected String modelLocation = null; public ClasspathComputer3_0(ModelBuildScriptGenerator modelGenerator) { this.generator = modelGenerator; @@ -109,7 +132,7 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta public List getClasspath(BundleDescription model, ModelBuildScriptGenerator.CompiledEntry jar) throws CoreException { List classpath = new ArrayList(20); List pluginChain = new ArrayList(10); //The list of plugins added to detect cycle - String location = generator.getLocation(model); + modelLocation = generator.getLocation(model); Set addedPlugins = new HashSet(10); //The set of all the plugins already added to the classpath (this allows for optimization) pathElements = new HashMap(); visiblePackages = getVisiblePackages(model); @@ -117,10 +140,10 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta allowBinaryCycles = AbstractScriptGenerator.getPropertyAsBoolean(IBuildPropertiesConstants.PROPERTY_ALLOW_BINARY_CYCLES); //PREREQUISITE - addPrerequisites(model, classpath, location, pluginChain, addedPlugins); + addPrerequisites(model, classpath, modelLocation, pluginChain, addedPlugins); //SELF - addSelf(model, jar, classpath, location, pluginChain, addedPlugins); + addSelf(model, jar, classpath, modelLocation, pluginChain, addedPlugins); recordRequiredIds(model); @@ -327,14 +350,16 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta } String path = null; - if ("jar".equalsIgnoreCase(basePath.getFileExtension())) { //$NON-NLS-1$ + String subPath = null; + Path libraryPath = new Path(libraryName); + if (libraryPath.isAbsolute()) { + path = libraryPath.toOSString(); + } else if ("jar".equalsIgnoreCase(basePath.getFileExtension())) { //$NON-NLS-1$ + if ("jar".equalsIgnoreCase(libraryPath.getFileExtension())) //$NON-NLS-1$ + subPath = libraryPath.toOSString(); path = basePath.toOSString(); } else { - Path libraryPath = new Path(libraryName); - if (libraryPath.isAbsolute()) - path = libraryPath.toOSString(); - else - path = basePath.append(libraryPath).toOSString(); + path = basePath.append(libraryPath).toOSString(); } path = ModelBuildScriptGenerator.replaceVariables(path, pluginKey == null ? false : generator.getCompiledElements().contains(pluginKey)); String secondaryPath = null; @@ -345,21 +370,24 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta } - addClasspathElementWithRule(classpath, path, rules); + addClasspathElementWithRule(classpath, path, subPath, rules); if (secondaryPath != null) { - addClasspathElementWithRule(classpath, secondaryPath, rules); + addClasspathElementWithRule(classpath, secondaryPath, null, rules); } } - private void addClasspathElementWithRule(List classpath, String path, String rules) { - String normalizedPath = ClasspathElement.normalize(path); - ClasspathElement existing = (ClasspathElement) pathElements.get(normalizedPath); + private void addClasspathElementWithRule(List classpath, String path, String subPath, String rules) { + path = normalize(path); + subPath = normalize(subPath); + + String elementsKey = subPath != null ? path + '/' + subPath : path; + ClasspathElement existing = (ClasspathElement) pathElements.get(elementsKey); if (existing != null) { existing.addRules(rules); } else { - ClasspathElement element = new ClasspathElement(normalizedPath, rules); + ClasspathElement element = new ClasspathElement(path, subPath, rules); classpath.add(element); - pathElements.put(normalizedPath, element); + pathElements.put(elementsKey, element); } } @@ -424,9 +452,9 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta for (int i = 0; i < extra.length; i++) { //Potential pb: if the path refers to something that is being compiled (which is supposetly not the case, but who knows...) //the user will get $basexx instead of $ws - String toAdd = computeExtraPath(extra[i], classpath, location); - if (toAdd != null) - addPathAndCheck(null, new Path(toAdd), "", modelProperties, classpath); //$NON-NLS-1$ + String[] toAdd = computeExtraPath(extra[i], classpath, location); + if (toAdd != null && toAdd.length == 2) + addPathAndCheck(null, new Path(toAdd[0]), toAdd[1], modelProperties, classpath); } } @@ -435,9 +463,9 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta for (int i = 0; i < jarSpecificExtraClasspath.length; i++) { //Potential pb: if the path refers to something that is being compiled (which is supposetly not the case, but who knows...) //the user will get $basexx instead of $ws - String toAdd = computeExtraPath(jarSpecificExtraClasspath[i], classpath, location); - if (toAdd != null) - addPathAndCheck(null, new Path(toAdd), "", modelProperties, classpath); //$NON-NLS-1$ + String[] toAdd = computeExtraPath(jarSpecificExtraClasspath[i], classpath, location); + if (toAdd != null && toAdd.length == 2) + addPathAndCheck(null, new Path(toAdd[0]), toAdd[1], modelProperties, classpath); } } @@ -448,14 +476,14 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta * @return String the relative path * @throws CoreException */ - private String computeExtraPath(String url, List classpath, String location) throws CoreException { + private String[] computeExtraPath(String url, List classpath, String location) throws CoreException { String relativePath = null; String[] urlfragments = Utils.getArrayFromString(url, "/"); //$NON-NLS-1$ // A valid platform url for a plugin has a leat 3 segments. if (urlfragments.length > 2 && urlfragments[0].equals(PlatformURLHandler.PROTOCOL + PlatformURLHandler.PROTOCOL_SEPARATOR)) { - String modelLocation = null; + String bundleLocation = null; BundleDescription bundle = null; if (urlfragments[1].equalsIgnoreCase(PLUGIN) || urlfragments[1].equalsIgnoreCase(FRAGMENT)) { bundle = generator.getSite(false).getRegistry().getResolvedBundle(urlfragments[2]); @@ -472,12 +500,13 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta return null; } - modelLocation = generator.getLocation(bundle); - if (modelLocation != null) { - for (int i = 3; i < urlfragments.length; i++) { - modelLocation += '/' + urlfragments[i]; + bundleLocation = generator.getLocation(bundle); + if (bundleLocation != null) { + String entry = urlfragments[3]; + for (int i = 4; i < urlfragments.length; i++) { + entry += '/' + urlfragments[i]; } - return Utils.makeRelative(new Path(modelLocation), new Path(location)).toOSString(); + return new String[] {Utils.makeRelative(new Path(bundleLocation), new Path(location)).toOSString(), entry}; } } else if (urlfragments[1].equalsIgnoreCase("resource")) { //$NON-NLS-1$ String message = NLS.bind(Messages.exception_url, generator.getModel().getSymbolicName() + '/' + generator.getPropertiesFileName() + ": " + url); //$NON-NLS-1$ @@ -500,7 +529,7 @@ public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConsta // String message = Policy.bind("exception.url", PROPERTIES_FILE + "::"+url); //$NON-NLS-1$ //$NON-NLS-2$ // throw new CoreException(new Status(IStatus.ERROR,PI_PDEBUILD, IPDEBuildConstants.EXCEPTION_MALFORMED_URL, message,e)); } - return relativePath; + return new String[] {relativePath, ""}; //$NON-NLS-1$ } //Add the prerequisite of a given plugin (target) diff --git a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ModelBuildScriptGenerator.java b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ModelBuildScriptGenerator.java index db5d950d..0f086afb 100644 --- a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ModelBuildScriptGenerator.java +++ b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ModelBuildScriptGenerator.java @@ -1433,8 +1433,13 @@ public class ModelBuildScriptGenerator extends AbstractBuildScriptGenerator { if (classpath.size() > 0 && classpath.get(0) instanceof ClasspathElement) { for (Iterator iterator = classpath.iterator(); iterator.hasNext();) { ClasspathElement element = (ClasspathElement) iterator.next(); - if (element.getPath() != null && element.getPath().length() > 0 && element.getAccessRules().length() > 0) { - String path = element.getPath(); + if (element.getPath() != null && element.getAccessRules().length() > 0) { + String path = null; + if (element.getSubPath() == null) + path = element.getPath(); + else + path = featureGenerator.getExtractedRoot(element) + '/' + element.getSubPath(); + if (path.startsWith(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER))) { //remove leading ${build.result.folder}/ path = path.substring(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER).length() + 1); @@ -1460,6 +1465,39 @@ public class ModelBuildScriptGenerator extends AbstractBuildScriptGenerator { } /** + * Add a target to extract any nested jars we need to compile against + * @param classpath + * @param entry + * @return a new classpath list containing the extracted locations + */ + private List generateExtractNestedJars(List classpath, CompiledEntry entry) { + script.printTargetDeclaration(entry.getName(false) + TARGET_NESTED_JARS, null, null, null, null); + + if (classpath == null || classpath.size() == 0 || !(classpath.get(0) instanceof ClasspathElement)) { + script.printTargetEnd(); + return classpath; + } + + List extracted = new ArrayList(classpath.size()); + for (Iterator iterator = classpath.iterator(); iterator.hasNext();) { + ClasspathElement element = (ClasspathElement) iterator.next(); + + if (element.getSubPath() == null) + extracted.add(element); + else { + String destPath = featureGenerator.getExtractedRoot(element); + String destDir = Utils.getPropertyFormat(PROPERTY_BUILD_DIRECTORY) + '/' + "nestedJars" + '/' + destPath.toString(); //$NON-NLS-1$ + script.printMkdirTask(destDir); + script.printUnzipTask(element.getPath(), destDir, false, element.getSubPath(), null); + extracted.add(destDir + '/' + element.getSubPath()); + } + } + script.printTargetEnd(); + + return extracted; + } + + /** * Add the "jar" target to the given Ant script using the given classpath and * jar as parameters. * @@ -1469,11 +1507,16 @@ public class ModelBuildScriptGenerator extends AbstractBuildScriptGenerator { private void generateCompilationTarget(List classpath, CompiledEntry entry) { script.println(); String name = entry.getName(false); - script.printTargetDeclaration(name, TARGET_INIT, null, entry.getName(true), NLS.bind(Messages.build_plugin_jar, model.getSymbolicName() + ' ' + name)); + + //extract nested jars and update the classpath with the new locations + List extractedPath = generateExtractNestedJars(classpath, entry); + + String depends = TARGET_INIT + "," + name + TARGET_NESTED_JARS; //$NON-NLS-1$ + script.printTargetDeclaration(name, depends, null, entry.getName(true), NLS.bind(Messages.build_plugin_jar, model.getSymbolicName() + ' ' + name)); String destdir = (entry.getType() == CompiledEntry.FOLDER) ? getJARLocation(entry.getName(true)) : getTempJARFolderLocation(entry.getName(true)); script.printDeleteTask(destdir, null, null); script.printMkdirTask(destdir); - script.printPathStructure("path", name + PROPERTY_CLASSPATH, classpath); //$NON-NLS-1$ + script.printPathStructure("path", name + PROPERTY_CLASSPATH, extractedPath); //$NON-NLS-1$ String[] sources = entry.getSource(); Map params = null, references = null; |