From 1195364128f6513c02bded22580fa0e830e587d6 Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Sat, 13 Sep 2008 09:22:32 +0000 Subject: Fixed maven bundle plugin to generate the correct list of JARs from the dependency tree (including transitive dependencies in addition to direct dependencies). Generated third-party library Manifest with the Manifest symbolic name and version before the lists of imports, exports and classpath entries to make the PDE happy. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@694906 13f79535-47bb-0310-9956-ffa450edef68 --- .../sca-equinox/modules/thirdparty-library/pom.xml | 59 ++++----- .../tuscany/bundle/plugin/LibraryBundleMojo.java | 145 +++++++++++++++++---- .../tuscany/bundle/plugin/LibraryBundleUtil.java | 53 ++++++-- 3 files changed, 191 insertions(+), 66 deletions(-) (limited to 'branches/sca-equinox') diff --git a/branches/sca-equinox/modules/thirdparty-library/pom.xml b/branches/sca-equinox/modules/thirdparty-library/pom.xml index a866958ffa..6e45ad4e89 100644 --- a/branches/sca-equinox/modules/thirdparty-library/pom.xml +++ b/branches/sca-equinox/modules/thirdparty-library/pom.xml @@ -27,51 +27,37 @@ tuscany-thirdparty-library Apache Tuscany OSGi Bundle for Third Party Jars - - true - ${pom.version} - + - ${pom.groupId} - tuscany-core - ${pom.version} + org.apache.tuscany.sca + tuscany-distribution-all + 1.4-SNAPSHOT - - ${pom.groupId} - tuscany-implementation-java-runtime - ${pom.version} - - - ${pom.groupId} - tuscany-node-impl - ${pom.version} - - - ${pom.groupId} - tuscany-host-jetty - ${pom.version} - + - - maven-jar-plugin - - - ${basedir}/META-INF/MANIFEST.MF - - - + maven-clean-plugin + + + + ${basedir}/lib + + * + + false + + + + + org.apache.tuscany.sca tuscany-maven-bundle-plugin - false + true @@ -79,10 +65,11 @@ build - process-sources + process-classes + - \ No newline at end of file + diff --git a/branches/sca-equinox/tools/maven/maven-tuscany-bundle-plugin/src/main/java/org/apache/tuscany/tools/sca/tuscany/bundle/plugin/LibraryBundleMojo.java b/branches/sca-equinox/tools/maven/maven-tuscany-bundle-plugin/src/main/java/org/apache/tuscany/tools/sca/tuscany/bundle/plugin/LibraryBundleMojo.java index 5fbd3008d2..a1189d91b7 100644 --- a/branches/sca-equinox/tools/maven/maven-tuscany-bundle-plugin/src/main/java/org/apache/tuscany/tools/sca/tuscany/bundle/plugin/LibraryBundleMojo.java +++ b/branches/sca-equinox/tools/maven/maven-tuscany-bundle-plugin/src/main/java/org/apache/tuscany/tools/sca/tuscany/bundle/plugin/LibraryBundleMojo.java @@ -18,19 +18,33 @@ */ package org.apache.tuscany.tools.sca.tuscany.bundle.plugin; +import static org.apache.tuscany.tools.sca.tuscany.bundle.plugin.LibraryBundleUtil.write; + import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.jar.Manifest; import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.metadata.ArtifactMetadataSource; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactCollector; +import org.apache.maven.artifact.resolver.ArtifactNotFoundException; +import org.apache.maven.artifact.resolver.ArtifactResolutionException; +import org.apache.maven.artifact.resolver.ArtifactResolver; +import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; +import org.apache.maven.shared.dependency.tree.DependencyTree; +import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder; +import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException; /** * @version $Rev$ $Date$ @@ -55,7 +69,7 @@ public class LibraryBundleMojo extends AbstractMojo { * @parameter expression="${basedir}" * @required @readonly */ - protected File basedir; + private File basedir; /** * Used to look up Artifacts in the remote repository. @@ -64,7 +78,7 @@ public class LibraryBundleMojo extends AbstractMojo { * @required * @readonly */ - protected org.apache.maven.artifact.factory.ArtifactFactory factory; + private org.apache.maven.artifact.factory.ArtifactFactory factory; /** * Used to look up Artifacts in the remote repository. @@ -73,7 +87,7 @@ public class LibraryBundleMojo extends AbstractMojo { * @required * @readonly */ - protected org.apache.maven.artifact.resolver.ArtifactResolver resolver; + private org.apache.maven.artifact.resolver.ArtifactResolver resolver; /** * Location of the local repository. @@ -82,7 +96,7 @@ public class LibraryBundleMojo extends AbstractMojo { * @readonly * @required */ - protected org.apache.maven.artifact.repository.ArtifactRepository local; + private org.apache.maven.artifact.repository.ArtifactRepository local; /** * List of Remote Repositories used by the resolver @@ -91,42 +105,128 @@ public class LibraryBundleMojo extends AbstractMojo { * @readonly * @required */ - protected java.util.List remoteRepos; + private java.util.List remoteRepos; /** * @parameter */ - protected boolean copyJars = false; + private boolean copyJars = false; + + /** + * Dependency tree builder + * + * @component + */ + private DependencyTreeBuilder dependencyTreeBuilder; + + /** + * Artifact factory + * + * @component + */ + private ArtifactFactory artifactFactory; + + /** + * @component + */ + private ArtifactMetadataSource artifactMetadataSource; + + /** + * @component + */ + private ArtifactCollector collector; + + /** + * The local repository + * + * @parameter expression="${localRepository}" + * @required + */ + private ArtifactRepository localRepository; + + /** + * The remote repositories + * + * @parameter expression="${project.remoteArtifactRepositories}" + */ + private List remoteRepositories; + + /** + * Artifact resolver + * + * @component + */ + private ArtifactResolver artifactResolver; public void execute() throws MojoExecutionException { + Log log = getLog(); + if (project.getPackaging().equals("pom")) { return; } - Log log = getLog(); - List jarFiles = new ArrayList(); - for (Object o : project.getArtifacts()) { - Artifact a = (Artifact)o; - if (!(Artifact.SCOPE_COMPILE.equals(a.getScope()) || Artifact.SCOPE_RUNTIME.equals(a.getScope()))) { + DependencyTree dependencyTree; + try { + dependencyTree = dependencyTreeBuilder.buildDependencyTree(project, + localRepository, artifactFactory, + artifactMetadataSource, collector ); + + } catch (DependencyTreeBuilderException e) { + throw new MojoExecutionException("Could not build dependency tree", e); + } + + Set jarFiles = new HashSet(); + for (Object o : dependencyTree.getArtifacts()) { + Artifact artifact = (Artifact)o; + + if (!(Artifact.SCOPE_COMPILE.equals(artifact.getScope()) || Artifact.SCOPE_RUNTIME.equals(artifact.getScope()))) { if (log.isDebugEnabled()) { - log.debug("Skipping artifact: " + a); + log.debug("Skipping artifact: " + artifact); } continue; } + if (!"jar".equals(artifact.getType())) { + continue; + } + if ("org.apache.tuscany.sca".equals(artifact.getGroupId())) { + continue; + } + + VersionRange versionRange = artifact.getVersionRange(); + if (versionRange == null) + versionRange = VersionRange.createFromVersion(artifact.getVersion()); + Artifact dependencyArtifact = artifactFactory.createDependencyArtifact(artifact.getGroupId(), + artifact.getArtifactId(), + versionRange, + artifact.getType(), + artifact.getClassifier(), + artifact.getScope()); + + try { + artifactResolver.resolve(dependencyArtifact, remoteRepositories, localRepository); + } catch (ArtifactResolutionException e) { + log.warn("Artifact " + artifact + " could not be resolved."); + } catch (ArtifactNotFoundException e) { + log.warn("Artifact " + artifact + " could not be found."); + } + artifact = dependencyArtifact; + if (log.isDebugEnabled()) { - log.debug("Artifact: " + a); + log.debug("Artifact: " + artifact); } String bundleName = null; try { - bundleName = LibraryBundleUtil.getBundleName(a.getFile()); + bundleName = LibraryBundleUtil.getBundleName(artifact.getFile()); } catch (IOException e) { throw new MojoExecutionException(e.getMessage(), e); } if (bundleName == null) { - if (log.isDebugEnabled()) { - log.debug("Adding non-OSGi jar: " + a); + if (artifact.getFile().exists()) { + log.info("Adding third party jar: " + artifact); + jarFiles.add(artifact.getFile()); + } else { + log.warn("Third party jar not found: " + artifact); } - jarFiles.add(a.getFile()); } } @@ -145,7 +245,7 @@ public class LibraryBundleMojo extends AbstractMojo { } FileOutputStream fos = new FileOutputStream(file); - mf.write(fos); + write(mf, fos); fos.close(); if (copyJars) { @@ -164,11 +264,12 @@ public class LibraryBundleMojo extends AbstractMojo { } FileInputStream in = new FileInputStream(jar); FileOutputStream out = new FileOutputStream(jarFile); - int len = 0; - while (len > 0) { - len = in.read(buf); + for (;;) { + int len = in.read(buf); if (len > 0) { out.write(buf, 0, len); + } else { + break; } } in.close(); diff --git a/branches/sca-equinox/tools/maven/maven-tuscany-bundle-plugin/src/main/java/org/apache/tuscany/tools/sca/tuscany/bundle/plugin/LibraryBundleUtil.java b/branches/sca-equinox/tools/maven/maven-tuscany-bundle-plugin/src/main/java/org/apache/tuscany/tools/sca/tuscany/bundle/plugin/LibraryBundleUtil.java index ed4ac63533..39c02bd2b4 100644 --- a/branches/sca-equinox/tools/maven/maven-tuscany-bundle-plugin/src/main/java/org/apache/tuscany/tools/sca/tuscany/bundle/plugin/LibraryBundleUtil.java +++ b/branches/sca-equinox/tools/maven/maven-tuscany-bundle-plugin/src/main/java/org/apache/tuscany/tools/sca/tuscany/bundle/plugin/LibraryBundleUtil.java @@ -29,12 +29,13 @@ import static org.osgi.framework.Constants.EXPORT_PACKAGE; import static org.osgi.framework.Constants.IMPORT_PACKAGE; import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.OutputStream; import java.net.URL; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.jar.Attributes; import java.util.jar.JarFile; @@ -99,15 +100,18 @@ public final class LibraryBundleUtil { && entryName.length() > 0 && !entryName.startsWith(".") && entryName.endsWith(".class") // Exclude resources from Export-Package - && entryName.lastIndexOf("/") > 0) { - String pkg = entryName.substring(0, entryName.lastIndexOf("/")).replace('/', '.') + version; - packages.add(pkg); + && entryName.lastIndexOf("/") > 0 + && Character.isJavaIdentifierStart(entryName.charAt(0))) { + String pkg = entryName.substring(0, entryName.lastIndexOf("/")).replace('/', '.'); + if (!("org.apache.commons.lang.enum".equals(pkg))) { + packages.add(pkg + version); + } } } is.close(); } - static Manifest libraryManifest(List jarFiles, String name, String version, boolean copyJars) + static Manifest libraryManifest(Set jarFiles, String name, String version, boolean copyJars) throws IllegalStateException { try { @@ -119,9 +123,9 @@ public final class LibraryBundleUtil { for (File jarFile : jarFiles) { addPackages(jarFile, packages); if (copyJars) { - classpath.append("\"lib/"); + classpath.append("lib/"); classpath.append(jarFile.getName()); - classpath.append("\","); + classpath.append(","); } else { classpath.append("\"external:"); classpath.append(jarFile.getPath().replace(File.separatorChar, '/')); @@ -154,10 +158,10 @@ public final class LibraryBundleUtil { attributes.putValue(BUNDLE_SYMBOLICNAME, LAUNCHER_EQUINOX_LIBRARIES); attributes.putValue(BUNDLE_NAME, name); attributes.putValue(BUNDLE_VERSION, version); + attributes.putValue(DYNAMICIMPORT_PACKAGE, "*"); attributes.putValue(EXPORT_PACKAGE, exports.substring(0, exports.length() - 1)); attributes.putValue(IMPORT_PACKAGE, imports.substring(0, imports.length() - 1)); attributes.putValue(BUNDLE_CLASSPATH, classpath.substring(0, classpath.length() - 1)); - attributes.putValue(DYNAMICIMPORT_PACKAGE, "*"); return manifest; } catch (IOException e) { @@ -178,6 +182,39 @@ public final class LibraryBundleUtil { return bos.toByteArray(); } + static void write(Manifest manifest, OutputStream out) throws IOException { + DataOutputStream dos = new DataOutputStream(out); + Attributes attributes = manifest.getMainAttributes(); + write(attributes, "Manifest-Version", dos); + write(attributes, BUNDLE_MANIFESTVERSION, dos); + write(attributes, BUNDLE_SYMBOLICNAME, dos); + write(attributes, BUNDLE_NAME, dos); + write(attributes, BUNDLE_VERSION, dos); + write(attributes, DYNAMICIMPORT_PACKAGE, dos); + write(attributes, EXPORT_PACKAGE, dos); + write(attributes, IMPORT_PACKAGE, dos); + write(attributes, BUNDLE_CLASSPATH, dos); + dos.flush(); + } + + private static void write(Attributes attributes, String key, DataOutputStream dos) throws IOException { + StringBuffer line = new StringBuffer(); + line.append(key); + line.append(": "); + String value = attributes.getValue(key); + line.append(new String(value.getBytes("UTF8"))); + line.append("\r\n"); + int l = line.length(); + if (l > 72) { + for (int i = 70; i < l - 2;) { + line.insert(i, "\r\n "); + i += 72; + l += 3; + } + } + dos.writeBytes(line.toString()); + } + /** * Returns the name of a bundle, or null if the given file is not a bundle. * -- cgit v1.2.3