how can maven-bundle-plugin find packages in Import-Package - maven

Is there any relationship between the bundles mentioned in the <dependencies> tag and the <Import-Package> tag? I mean if we don't define dependency, then maven-bundle-plugin can not find the packages in <Import-Package> tag?

Maven uses the jars listed in the dependencies section to create a classpath. This class path is used by bnd (the engine in the maven bundle plugin) to analyze what your code is referring to through byte code analysis.
maven dependency -> classpath -> bnd analysis -> import statements

Import-Package is used to refine the list of package imports which the maven bundle plugin generates automatically for you. For example, you could declare some imports optional, or add imports for classes which are only accessed by reflection. In most cases it shouldn't be necessary to specify anything at all for Import-Package since the default is * - that is, any external packages referenced in your bytecode will be imported.
The dependencies section provides the pool of bundles used by the compiler to generate the bytecode, and bnd (which is what the bundle plugin under the covers) to improve the package imports. For example, it will add version ranges based on the exported versions in a providing bundle in the dependencies list (or in transitive dependencies).

Related

maven-bundle-plugin include non existing dependencies

I have a stange problem with the "maven-bundle-plugin" in a Eclipse Plugin Project.
When I compile the project, i see on the Manifest.xml, on the "Import-Package" section a lot of java packages imports for a lot of packages that doesn't exists on my classpath, for Example:
Import-Package:
COM.newmonics.PercClassLoader,
android.os,
bitronix.tm,
bitronix.tm.jndi,
bitronix.tm.resource.common,
bitronix.tm.resource.jdbc,
bitronix.tm.resource.jms,
bsh,
com.arjuna.ats.arjuna.common,
com.arjuna.ats.arjuna.recovery,
com.arjuna.ats.internal.jdbc,
com.arjuna.ats.internal.jta.recovery.arjunacore,
com.arjuna.ats.jbossatx.jta,
All of this packages don't exists on my project or in my dependencies, but maven-bundle-plugin add it to the Manifest, and I have no idea why. Any idea or suggestion? Thanks.
The bundle plugin generates Import-Package for the packages that are referred to by your project. These are the packages that should be exported by other bundles, so that your bundle can use them runtime. My first guess is that your classes refer to these packages, so check your source code first.
If your project really doesn't refer to those packages, please check if your pom.xml has specified these packages in an <Import-Package> directive in the plugin configuration. Perhaps it was copy/pasted from another project?
It could also be that you have embedded dependencies in your bundle jar that refer to the packages. To find out, you can unpack your jar (e.g. using the rjar tool) and grep the class files recursively for e.g. bitronix/tm.

Add non-osgi jars to RCP4 project

I am building an RCP4 application.
I have two non-osgi jars called a.jar and b.jar. Both jars have tons of non-osgi dependencies. One of the dependencies of a.jar is b.jar. So the hierarchy looks like this:
My application
|--a.jar
|----aDependency1.jar
|----aDependency2.jar
|----aDependencyN.jar
|----b.jar
|------bDependency1.jar
|------bDependency2.jar
|------bDependencyN.jar
Some of the bDependencyN.jars are different versions of the aDependencyN.jars
(An example is commons-logging-1.0.4.jar vs commons-logging-1.1.2.jar)
I need to directly reference a.jar and b.jar from my RCP4 application. In other words, when I write code, I will import packages from a.jar and b.jar)
Which is the best approach:
Use bnd 2.4 via command-line to turn all non-osgi jars into osgi ones. I then add every jar to my project via target file
Create a new project "Plug-in from existing JAR archives", and select a.jar and all of its dependencies and export it as a "deployable plugin and fragment" called a.with.libs.jar. I do the same with b.jar and create b.with.libs.jar. I then add those 2 new jars to my project via target file
Create a new project "Plug-in from existing JAR archives", and select a.jar and all of its dependencies, and b.jar and all of its dependencies and export it as a "deployable plugin and fragment" called ab.with.libs.jar. I then add the new jar to my project via target file
Is there a better approach than the suggestions above?
One option is to use bnd-platform (I am also the author) to manage third party dependencies and create OSGi bundles from them. You can use it with both dependencies retrieved from Maven repositories and local Jars (see the README). When you configure a Maven dependency it will also include the transitive dependencies. Under the hood it uses bnd. If needed you can also customize how the Jars are wrapped. bnd-platform is a plugin for Gradle, you can easily start with this template - just add your dependencies and provide the configuration as described in the project README (bundle symbolic names, versions) and run gradlew bundles. The created bundles can then be added to the target platform. You can also use bnd-platform to build a p2 repository / update site.

how to use maven bundle plugin to exclude package out of bundle

i have a bundle that uses maven-jaxb2-plugin to generate all classes to target/generated/src/main/java. Then i use maven bundle plugin to create a bundle. It simply works.
Now, i want to exclude (remove) a generated package com.xxx.yyyy.common out of this bundle. So i use:
<Export-Package>
!com.xxx.yyyy.common,com.xxx.*
</Export-Package>
But after having a bundle, that package is still there inside the bundle.
I have made it works.
Basically, we need to use a combination between <Export-Package> and <Private-Package>. Tell maven bundle plugin to not export this package and this package is not a private package --> that means we dont need to keep this package in the bundle
<Export-Package>!com.xxx.yyyy.common</Export-Package>
<Private-Package>!com.xxx.yyyy.common</Private-Package>
The syntax you use, is just to exclude the package from being exported, not from being packaged. You need to use standard maven assembly instructions for excluding something from the packaged artifact. This is no goal for the maven-bundle-plugin, the maven-bundle-plugin only generates OSGi-Manifest entries from your packaged artifact.

How to build two different jar packages with maven-assembly-plugin?

My project consists of three maven packages and application class (in default package). The existing configuration (defined in pom.xml) uses maven-assembly-plugin to create single executable jar-with-dependencies.
I'd like to add an execution *descriptorRef* \ whatever to create a distributalbe jar package that will contain only classes from two packages out of three (one is a mock-up).
Is it possible?
If I define an configuration can I make it relate to one but not the other?
I have absolutely done this. You can configure multiple executions of the Maven Jar Plugin in the package phase and specify different includes / excludes for each execution.
See Maven Jar Plugin documentation, particularly the section entitled: "How to create an additional attached jar artifact from the project."
If you must use the Assembly plugin, you should just create a new assembly descriptor using the jar-with-dependencies as a template, but adding the inclusions / exclusions to your liking.

Javadoc creation with maven

We have created a new artifact to generate javadoc. We have 40 artifacts defined as dependencies. Task is to create javadoc.jar and html pages for the 40 dependency artifacts.
Whats the best approach to achieve this in maven?
This is very unusual. Javadoc works on sources, not compiled classes, whereas maven dependencies reference classes, not sources.
So to make this work you'll have to do all of this:
since this is a dedicated javadoc artifact, it won't have a main JAR artifact, so you'll probably want to set the packaging to POM
make sure all your referenced artifacts have attached sources
add <classifier>sources</classifier> to all your dependencies
unpack all dependencies to a common root folder using dependency:unpack-dependencies
run javadoc on that folder
create a jar using the maven-assembly-plugin
attach that jar to the build using the buildhelper plugin
On re-reading the question: I'm assuming that you want to create combined docs of all dependencies. If not, you'll need 40 separate executions each of the javadoc, assembly and buildhelper plugins. Good luck with that.
A slightly more automated approach than the answer above:
So to make this work you'll have to do all of this:
since this is a dedicated javadoc artifact, it won't have a main JAR artifact, so you'll probably want to set the packaging to POM
make sure all your referenced artifacts have attached sources
add <classifier>sources</classifier> to all your dependencies
unpack all dependencies to a common root folder using dependency:unpack-dependencies
Change your sources directory to where you unpacked all the dependencies
Use the source plugin to manage all the Javadoc generation and deployment

Resources