diff options
Diffstat (limited to 'maven-plugins/trunk/maven-bundle-plugin/src/main')
2 files changed, 109 insertions, 6 deletions
diff --git a/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/bundle/plugin/BundleUtil.java b/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/bundle/plugin/BundleUtil.java index 9ddd261385..813f02a181 100644 --- a/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/bundle/plugin/BundleUtil.java +++ b/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/bundle/plugin/BundleUtil.java @@ -170,8 +170,10 @@ final class BundleUtil { String packageName = packageName(export); if (!pkgs.contains(packageName)) { // Add corresponding import declaration - imports.append(export); - imports.append(','); + if (!"META-INF.services".equals(packageName)) { + imports.append(export); + imports.append(','); + } pkgs.add(packageName); exports.append(export); exports.append(','); @@ -188,7 +190,8 @@ final class BundleUtil { attributes.putValue(BUNDLE_SYMBOLICNAME, symbolicName); attributes.putValue(BUNDLE_NAME, name); attributes.putValue(BUNDLE_VERSION, version); - attributes.putValue(DYNAMICIMPORT_PACKAGE, "*"); + // The system bundle has incomplete javax.transaction* packages exported + attributes.putValue(DYNAMICIMPORT_PACKAGE, "javax.transaction;version=\"1.1\",javax.transaction.xa;version=\"1.1\",*"); if (buddyPolicy != null && buddyPolicy.length() > 0){ attributes.putValue("Eclipse-BuddyPolicy", buddyPolicy); } @@ -314,6 +317,10 @@ final class BundleUtil { ZipEntry entry; while ((entry = is.getNextEntry()) != null) { String entryName = entry.getName(); + // Export split packages for META-INF/services + if(entryName.startsWith("META-INF/services/")) { + packages.add("META-INF.services" + ";partial=true;mandatory:=partial"); + } if (!entry.isDirectory() && entryName != null && entryName.length() > 0 && !entryName.startsWith(".") diff --git a/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/bundle/plugin/ModuleBundlesBuildMojo.java b/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/bundle/plugin/ModuleBundlesBuildMojo.java index 7e9d0faea0..2bf6c1bdeb 100644 --- a/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/bundle/plugin/ModuleBundlesBuildMojo.java +++ b/maven-plugins/trunk/maven-bundle-plugin/src/main/java/org/apache/tuscany/maven/bundle/plugin/ModuleBundlesBuildMojo.java @@ -21,6 +21,10 @@ package org.apache.tuscany.maven.bundle.plugin; import static org.apache.tuscany.maven.bundle.plugin.BundleUtil.write; import static org.osgi.framework.Constants.BUNDLE_CLASSPATH; import static org.osgi.framework.Constants.BUNDLE_VERSION; +import static org.osgi.framework.Constants.RESOLUTION_DIRECTIVE; +import static org.osgi.framework.Constants.RESOLUTION_OPTIONAL; +import static org.osgi.framework.Constants.VISIBILITY_DIRECTIVE; +import static org.osgi.framework.Constants.VISIBILITY_REEXPORT; import java.io.File; import java.io.FileInputStream; @@ -56,6 +60,7 @@ import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectBuilder; import org.apache.maven.project.ProjectBuildingException; import org.apache.maven.project.artifact.InvalidDependencyVersionException; +import org.osgi.framework.Constants; /** * A maven plugin that generates a modules directory containing OSGi bundles for all the project's module dependencies. @@ -68,6 +73,8 @@ import org.apache.maven.project.artifact.InvalidDependencyVersionException; */ public class ModuleBundlesBuildMojo extends AbstractMojo { + private static final String GATEWAY_BUNDLE = "org.apache.tuscany.sca.gateway"; + /** * The project to create a distribution for. * @@ -196,6 +203,18 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { private boolean useDefaultLocation = true; /** + * Set to true to generate a gateway bundle tuscany-gateway-<version>.jar that handles split packages and META-INF/services. + * + * @parameter default-value="true" + */ + private boolean generateGatewayBundle; + + /** + * @parameter default-value="false" + */ + private boolean gatewayReexport; + + /** * Set to true to generate a plugin.xml. * * @parameter default-value="false" @@ -325,7 +344,7 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { getLog().info("MANIFEST.MF found for " + artifact + " (" + mf + ")"); return manifest; } else { - getLog().info("Overriding the manifest for "+artifact); + getLog().info("Overriding the manifest for " + artifact); Manifest manifest = BundleUtil.getManifest(artifact.getFile()); Set<File> jarFiles = new HashSet<File>(); jarFiles.add(artifact.getFile()); @@ -410,6 +429,8 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { ProjectSet bundleSymbolicNames = new ProjectSet(poms); ProjectSet bundleLocations = new ProjectSet(poms); ProjectSet jarNames = new ProjectSet(poms); + ProjectSet serviceProviders = new ProjectSet(poms); + for (Object o : project.getArtifacts()) { Artifact artifact = (Artifact)o; @@ -479,6 +500,9 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { bundleSymbolicNames.add(artifact, bundleName); bundleLocations.add(artifact, artifactFile.getName()); jarNames.add(artifact, artifactFile.getName()); + if (isServiceProvider(mf)) { + serviceProviders.add(artifact, bundleName); + } } else { // Expanding the bundle into a folder @@ -499,6 +523,9 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { bundleSymbolicNames.add(artifact, bundleName); bundleLocations.add(artifact, dir.getName()); jarNames.add(artifact, dirName + "/" + artifactFile.getName()); + if (isServiceProvider(mf)) { + serviceProviders.add(artifact, bundleName); + } } } else if ("war".equals(artifact.getType())) { @@ -576,6 +603,9 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { bundleSymbolicNames.add(artifact, symbolicName); bundleLocations.add(artifact, dir.getName()); jarNames.add(artifact, dirName + "/" + artifactFile.getName()); + if (isServiceProvider(mf)) { + serviceProviders.add(artifact, symbolicName); + } } } @@ -614,9 +644,16 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { fos.close(); bundleSymbolicNames.add(artifact, symbolicName); bundleLocations.add(artifact, dir.getName()); + if (isServiceProvider(mf)) { + serviceProviders.add(artifact, symbolicName); + } } } + if (generateGatewayBundle) { + generateGatewayBundle(serviceProviders); + } + // Generate a PDE target if (generateTargetPlatform) { generatePDETarget(bundleSymbolicNames, root, log); @@ -648,6 +685,59 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { } } + + private static boolean isServiceProvider(Manifest mf) { + if (mf != null) { + String export = (String)mf.getMainAttributes().getValue(Constants.EXPORT_PACKAGE); + if (export != null && export.contains("META-INF.services")) { + return true; + } + } + return false; + } + + /** + * Generate a gateway bundle that aggregate other bundles to handle split packages + * @param bundleSymbolicNames + * @throws FileNotFoundException + * @throws IOException + */ + private void generateGatewayBundle(ProjectSet bundleSymbolicNames) throws FileNotFoundException, IOException { + Manifest manifest = new Manifest(); + Attributes attrs = manifest.getMainAttributes(); + StringBuffer requireBundle = new StringBuffer(); + for (String name : new HashSet<String>(bundleSymbolicNames.artifactToNameMap.values())) { + requireBundle.append(name).append(";").append(RESOLUTION_DIRECTIVE).append(":=") + .append(RESOLUTION_OPTIONAL); + if (gatewayReexport) { + requireBundle.append(";").append(VISIBILITY_DIRECTIVE).append(":=").append(VISIBILITY_REEXPORT); + } + requireBundle.append(","); + } + int len = requireBundle.length(); + if (len > 0 && requireBundle.charAt(len - 1) == ',') { + requireBundle.deleteCharAt(len - 1); + attrs.putValue(Constants.REQUIRE_BUNDLE, requireBundle.toString()); + attrs.putValue("Manifest-Version", "1.0"); + attrs.putValue("Implementation-Vendor", "The Apache Software Foundation"); + attrs.putValue("Implementation-Vendor-Id", "org.apache"); + attrs.putValue(Constants.BUNDLE_VERSION, "2.0.0"); + attrs.putValue(Constants.BUNDLE_MANIFESTVERSION, "2"); + attrs.putValue(Constants.BUNDLE_SYMBOLICNAME, GATEWAY_BUNDLE); + attrs.putValue(Constants.BUNDLE_NAME, "Apache Tuscany SCA Gateway Bundle"); + attrs.putValue(Constants.BUNDLE_VENDOR, "The Apache Software Foundation"); + attrs.putValue(Constants.EXPORT_PACKAGE, "META-INF.services"); + attrs.putValue(Constants.DYNAMICIMPORT_PACKAGE, "*"); + attrs.putValue(Constants.BUNDLE_ACTIVATIONPOLICY, Constants.ACTIVATION_LAZY); + File file = new File(targetDirectory, "tuscany-gateway-" + project.getVersion() + ".jar"); + getLog().info("Generating gateway bundle: " + file.getAbsolutePath()); + FileOutputStream fos = new FileOutputStream(file); + JarOutputStream jos = new JarOutputStream(fos, manifest); + addFileToJar(jos, "META-INF/LICENSE", getClass().getResource("LICENSE.txt")); + addFileToJar(jos, "META-INF/NOTICE", getClass().getResource("NOTICE.txt")); + jos.close(); + } + } private void setBundleClassPath(Manifest mf, File artifactFile) { // Add the Bundle-ClassPath @@ -766,7 +856,10 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { private void generateEquinoxConfig(ProjectSet bundleLocations, File root, Log log) throws IOException { for (Map.Entry<String, Set<String>> e : bundleLocations.nameMap.entrySet()) { - Set<String> locations = e.getValue(); + Set<String> locations = new HashSet<String>(e.getValue()); + if (generateGatewayBundle) { + locations.add("tuscany-gateway-" + project.getVersion() + ".jar"); + } File feature = new File(root, "../" + featuresName + "/" + (useDistributionName ? trim(e.getKey()) : "")); File config = new File(feature, "configuration"); config.mkdirs(); @@ -807,7 +900,7 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { private void generatePDETarget(ProjectSet bundleSymbolicNames, File root, Log log) throws FileNotFoundException, IOException { for (Map.Entry<String, Set<String>> e : bundleSymbolicNames.nameMap.entrySet()) { - Set<String> bundles = e.getValue(); + Set<String> bundles = new HashSet<String>(e.getValue()); String name = trim(e.getKey()); File feature = new File(root, "../" + featuresName + "/" + (useDistributionName ? name : "")); feature.mkdirs(); @@ -817,6 +910,9 @@ public class ModuleBundlesBuildMojo extends AbstractMojo { if (!bundles.contains("org.eclipse.osgi")) { bundles.add("org.eclipse.osgi"); } + if (generateGatewayBundle) { + bundles.add(GATEWAY_BUNDLE); + } writeTarget(new PrintStream(targetFile), name, bundles, eclipseFeatures); targetFile.close(); |