I have a project with produces an OSGI bundle using the maven-bundle-plugin. The configuration looks like this:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.1.0</version>
<extensions>true</extensions>
<inherited>true</inherited>
<configuration>
<instructions>
<Export-Package>${bubble.osgi.exports}</Export-Package>
<Import-Package>${bubble.osgi.imports}</Import-Package>
<Embed-Dependency>${bubble.osgi.embed.dependencies}</Embed-Dependency>
<_versionpolicy>[$(version;==;$(#)),$(version;+;$(#)))</_versionpolicy>
</instructions>
<versions>
<bubble.osgi.version.clean>${project.version}</bubble.osgi.version.clean>
</versions>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>cleanVersions</goal>
</goals>
</execution>
</executions>
</plugin>
The outcome of the project is a single jar file with all the osgi stuff, embedded dependencies etc. included. I rather would like to have 2 jars as outcome, one with the osgi stuff included and one without, as the embedded dependencies cause problems when using it just as a plain jar.
Is there any other way than using the maven assembly plugin for this?
You can move maven-bundle-plugin configuration into separate profile and use something like
mvn package -Posgi
or default. But there will only one artifact produced per build.
I would recommend to use 2 different pom.xml files (in the project) which will produces 2 different artifacts.
The default pom.xml should generate the plain library like foo:bar:1.0.0
Another pom-osgi.xml should generate the OSGi library like foor:bar-osgi:1.0.0
To build the library with another pom use
mvn -f pom-osgi.xml install
Related
I am using today maven-bundle-plugin to generate the manifest of my projects. Due to others constraints, my modules use the "jar" packaging (i can't use the "bundle" packaging), and currently, my pom look like this :
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
...
</instructions>
</configuration>
</execution>
</executions>
</plugin>
I'd like now to generate a 'Service-Component' header and the DS xml descriptor from my annotated components, but adding "<_dsannotations>*</_dsannotations>" is not working :
Service-Component header is correctly generated, but the xml are not present in the jar
If i rebuild my maven project without a clean goal, then the 'Service-Component' header have duplicates references : After digging in the code, the plugin use the old generated manifest from target/classes/META-INF/MANIFEST.MF and merge it with the new generated one. The 'Service-Component' is then concatened
So, how should i configure my pom for this to work ? For now, i use the 'unpackBundle' option (in order to have the xml in my bundle) and an empty src/main/resource/MANIFEST.MF (in order to bypass the merge of the old manifest) : it looks ugly :-)
Moreover, the 'bnd-maven-plugin' work as intended, but the integration with maven are maybe too light (or not documented?), as 'global configuration' in a parent pom, generation of the Bundle-SymbolicName or Bundle-Name, etc.
Thanks!
There is a newer plugin for maven that is closer to both bnd and maven. This plugin does not take over the jar target and properly follows the maven phases.
Take a look at http://njbartlett.name/2015/03/27/announcing-bnd-maven-plugin.html
Currently our maven build includes all the dependencies in the jar, using jar-with-dependencies.
We want to split this into two separate jars, one with the project application code and files, and one with the dependencies.
How is this done?
Thanks
This is done using the maven Assembly plugin
http://maven.apache.org/plugins/maven-assembly-plugin/
Use the maven-shade-plugin instead with following configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<configuration>
<finalName>${project.artifactId}-${project.version}-libs</finalName>
<artifactSet>
<excludes>
<exclude>${project.groupId}:${project.artifactId}</exclude>
</excludes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
The trick is to define a specific final name. This avoids the replacement of the default jar, which is packaged by the maven-jar-plugin. The default name is ${project.artifactId}-${project.version}. So simply add a suffix like libs. Then exclude the artifact itself, because the classes should not be packaged twice.
The build will result in two jar files:
${project.artifactId}-${project.version}.jar, containing the classes and files of the project
${project.artifactId}-${project.version}-libs.jar, containing the content of all the dependencies
Today I configure the Maven war plugin like this :
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>${basedir}/../common/WEB-INF/web.xml</webXml>
</configuration>
This allows me to share that web.xml between several projects.
The problem with this approach is that my Maven project is not self contained. It depends on a relative path on the file system.
Is it somehow possible to do something like this ? :
<webXml>classpath:com/mycompany/common/web.xml</webXml>
And of course, make that file available on the classpath of the plugin.
Thanks
First step is to create a dedicated Maven module with packaging type jar containing the web.xml. Let's call it com.mycompany:common.
Is it somehow possible to do something like this ? :
<webXml>classpath:com/mycompany/common/web.xml</webXml>
Have you tried i.e. you know for sure that it doesn't work? If it did I suppose you'd have to use a leading '/' (/com/...).
And of course, make that file available on the classpath of the
plugin.
That'd be easy then...just add a dependency to com.mycompany:common to make it available in the classpath. Of course it'd have to be available in your Maven repository.
If classpath: doesn't work, I'm really not sure anymore myself, you could use the maven-dependency-plugin to unpack web.xml from the JAR in order to make it available to the maven-war-plugin.
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-web-xml</id>
<phase>..any phase before packaging..</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.mycompany</groupId>
<artifactId>common</artifactId>
<version>1.0</version>
<outputDirectory>...dir you'll use for the war plugin later...</outputDirectory>
<includes>/com/mycompany/common/web.xml</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
In my maven project, the ant plugin generate multiple war files and I want to attach them all in the same artifact. I tried the build-helper-maven-plugin like this
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/*.war</file>
<type>war</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
I don't want to specify each war file separately because the ant plugin is dynamic. Is there a way to do that?
Thanks,
Providing wildcards for single artifacts does not seem to be supported by the Build Helper plugin (btw, if it did, it would likely use the includes/excludes configuration used by Resources Plugin).
I've learned that, if you choose to use Maven, it's best to just adjust your build to "the Maven way."
In this case, you should revise your build to not use the ant war plugin, and instead have a multi-module build with a separate module (sub-project) for each war file.
Alternatively, in the past I have accomplished something like you are doing via the Maven Assembly plugin, where the wars are all shipped together in a single tar/gz file. The archive (which contains each of the wars) is then attached to the build.
Note that you should prefer to have your "web apps" module have a artifact type of "pom." The assembly plugin will attach the archives to the final build.
For more information, I've found that Sonatype's online books are a great resource:
http://www.sonatype.com/Support/Books
I'm building a service which contains a client module which is using Spring. The service which will be implementing the client does not contain spring but it has a dependency on the client which has dependencies on Spring. Ideally I would like the client to include the needed Spring dependencies in the JAR but I can't seem to figure out how to accomplish this. I've seen a few different examples of using maven-assembly-plugin but I would prefer to not have to use something other than "mvn clean package" to accomplish this.
Any help is appreciated.
The maven-shade-plugin allows you to build an uber-jar containing some (or all) of your dependencies. It should allow you to do what you need.
By binding the assembly plugin's single goal to the project's build lifecycle, you can accomplish what you want by running mvn clean package.
Cut/pasting the pom configuration to do this from the usage page of the plugin,
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
[...]
</project>
Of course, you would tweak either either to use a different predefined descriptor or even use a separate descriptor file.