I've got a CXF web service app in Fuse, and it's got a reference in a camel context xml file to a jar containing my files generated from a WSDL.
<cxf:cxfEndpoint id="LookupEndpoint"
address="${my.LookupUri}"
serviceClass="com.whatever.IWebService"
wsdlURL="wsdl/MyWsdl.wsdl"/>
com.whatever.* is in my <Import-Package> list. The jar is in my maven dependencies. I can say import com.whatever.IWebService; and it doesn't complain.
But maven-bundle-plugin doesn't include this package in the MANIFEST.MF
It includes all my other packages that I requested. But not this one. So in Fuse, when I deploy it, I get ClassNotFoundException, referring to the context.xml class loading.
It is very frustrating. Is there a way to maybe force the plugin to import a certain package? Because their auto-magical dependency solver is ignoring my <Import-Package>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${version.maven-bundle-plugin}</version>
<extensions>true</extensions>
<configuration>
<manifestLocation>src/main/resources/META-INF</manifestLocation>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Import-Package>
*,
com.imports.this.one.fine*,
com.imports.this.one.just.fine*,
com.imports.does.not.import.this.one.*,
</Import-Package>
<Export-Package>
com.something.export.*
</Export-Package>
</instructions>
</configuration>
</plugin>
When you use <Import-Package> with a wildcard, then an OSGi Import-Package header is generated for all packages matching the wildcard that the code in your bundle depends on.
If the maven-bundle-plugin is not generating an import for the package you expect, it means that the code in your bundle doesn't actually reference that package.
Rather than importing this package, shouldn't it be included in the bundle?? Why do you want to import it?
Related
How can I achieve that the plugin does not inline the dependencies in the new build jar file?
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Category>tools</Bundle-Category>
<Fragment-Host>org.jsmpp.jsmpp</Fragment-Host>
<Private-Package>!</Private-Package>
<Export-Package>
org.jsmpp.*;version="2.2.3"
</Export-Package>
<Import-Package>!org.slf4j</Import-Package>
<Bundle-Version>2.2.3</Bundle-Version>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jsmpp</groupId>
<artifactId>jsmpp</artifactId>
</dependency>
</dependencies>
The plugin does not inline any dependencies, unless you include an Embed-Dependency instruction. That instruction can be inherited from a parent POM.
All packages that match the <Export-Package> instruction are included in the bundle, even if those packages come from a dependency. So you can either specify all packages from your bundle explicitly, or use a wildcard and exclude unwanted packages with the '!' prefix, e.g.
<Export-Package>
org.jsmpp.*;version="2.2.3",
!org.jsmpp.donotwant
</Export-Package>
see maven-bundle-plugin documentation
Use _exportcontents instead of Export-Package.
_exportcontents affect only the manifest, whereas Export-Package modify the manifest and the content of your bundle.
see: http://www.aqute.biz/Bnd/Format
If I have a OSGI Bundle that has dependency jars nested inside the OSGI Bundle jar, do I need to list those classes in the Import-Package manifest so that I could use them? I would think not.
Also how do I add these dependency jars into my bundle. Do I just put them in the root folder? Do I need to add anything to the manifest file to be able to use these dependencies?
Avoid using Bundle-ClassPath manually. You can use maven-bundle-plugin to solve and embed your third party dependencies like this:
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.5.3</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId};singleton:=true</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Export-Package>lumina.extensions.drivers.luminadb</Export-Package>
<Bundle-Activator>lumina.extensions.drivers.luminadb.internal.Activator</Bundle-Activator>
<Embed-Dependency> YOUR ARTIFACT ID HERE </Embed-Dependency>
</instructions>
</configuration>
</plugin>
(...)
</plugins>
For more information visit http://web.ist.utl.pt/ist162500/?p=110
You should not use Import-Package for embedded jars. Instead use Bundle-ClassPath: .,myjar.jar to add the embedded jars to the bundle classpath.
I have a parent pom.xml which builds a series of modules. As part of the parent pom.xml I read a configuration and put a number of variables into the build environment:
BUILD_DATE=2014/07/24 15\:37\:06
BUILD_NUMBER=78
VERSION=GGY1.6
I wish to place this information into the manifest jar file. I am doing this as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<finalName>atf</finalName>
<archive>
<manifestEntries>
<Built-Date>${maven.build.timestamp}</Built-Date>
<Version>${VERSION}B${BUILD_NUMBER}</Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
I am not sure which section of the pom.xml this should go into. I have put it in the build phase, and in some modules this works out ok, but in others it comes out in the manifest as:
Created-By: Apache Maven 3.0.5
Built-Date: 28/07/2014-16:00
Version: ${VERSION}B${BUILD_NUMBER}
Archiver-Version: Plexus Archiver
Is there a specific place in the pom.xml I need to put the maven-jar-plugin in order for it to pick up variables created by the parent?
I think the missing piece in the modules pom.xml files was this:
<plugin><groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
</plugin>
Any module pom which had this piece added, populated the manifest correctly... along with the maven-jar-plugin snippet. It looks like both are needed in order to access the values set by the parent pom.xml
I've been having some problems with a WAR module and its difficulty in loading a taglib. I kept getting this exception:
JSPG0047E: Unable to locate tag library for uri http://www.springframework.org/tags/form
at com.ibm.ws.jsp.translator.visitor.tagfiledep.TagFileDependencyVisitor.visitCustomTagStart(TagFileDependencyVisitor.java:76)
at com.ibm.ws.jsp.translator.visitor.JspVisitor.processJspElement(JspVisitor.java:366)
at com.ibm.ws.jsp.translator.visitor.JspVisitor.processChildren(JspVisitor.java:419)
at com.ibm.ws.jsp.translator.visitor.JspVisitor.processJspElement(JspVisitor.java:369)
...
After a bit of searching, I found a lot of suggestions that the spring jars need to be on the application's classpath. I checked in my EAR's lib folder and sure enough, spring-web and spring-webmvc were there.
It should be noted that the EAR is built with skinny WARs - since they use most of the same libraries, all library files are in MyAppEAR/lib instead of MyAppEAR/MyWAR1/WEB-INF/lib, MyAppEAR/MyWAR2/WEB-INF/lib, MyAppEAR/MyWAR3/WEB-INF/lib, etc...
I did finally manage to resolve this missing taglib error, but I had to move spring-web and spring-webmvc to MyAppEAR/MyWAR1/WEB-INF/lib.
So I have a couple of questions:
Is this the only way to fix this problem?
If so, how can I build a sort-of skinny WAR using maven? Currently, the EAR part of the POM looks like this:
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.8</version>
<configuration>
<applicationName>MyAppEAR</applicationName>
<defaultLibBundleDir>lib</defaultLibBundleDir>
<skinnyWars>true</skinnyWars>
I guess I could turn off skinny WARs and then have some other step remove all libraries from the WAR files and copy them to MyAppEAR/lib except for the spring web jars, but I am hoping there's a better solution.
I had the same issues myself - I just couldn't access Spring or Sitemesh's TLDs when my spring JAR files were in my ear/lib folder!
Including the classpath in the MANIFEST was causing my app server go haywire (since all dependencies were being loaded twice).
(Yes, I also have skinnyWars set to true in my maven-ear-plugin).
The only way I could have gone round the issue was by including Spring and sitemesh by including them in maven-war-plugin's configuration:
<packagingExcludes>%regex[WEB-INF/lib/(?!spring|sitemesh).*.jar]</packagingExcludes>
Not the most elegant solution, but the least damaging I could find.
This is my full configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<!--
Q. Why is this set?
A. maven-ear-plugin in our EAR modules have `skinnyWars` enabled to that WAR files
would not include any third-party libraries in the WAR's WEB-INF/lib folder, however
this does not work for ejbs (like our own EJB modules).
We'll need to exclude them from here anyway (except for a few select JARS)...
-->
<packagingExcludes>%regex[WEB-INF/lib/(?!spring|sitemesh).*.jar]</packagingExcludes>
<archive>
<manifest>
<addClasspath>false</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
PS. My setup is JBoss EAP 6.x and an ear file with several EJBs, WARs and third-party JARs.
I think I got it working.
In the WAR's POM file:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<packagingExcludes>WEB-INF/lib/*.jar,WEB-INF/*.xmi</packagingExcludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>../../WEB-INF/lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
This causes the generated WAR file to have a META-INF/MANIFEST.MF file with classpath entries that look like ../WEB-INF/lib/$someJarFile - that is the relative path from the WAR to the EAR's library folder. I guess the WAR needs to have the classpath specified, having the libraries in the EAR just isn't enough.
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