maven-ear-plugin jarModule - maven

Can someone explain the purpose of the maven-ear-plugin jarModule? It's apparently for 3rd-party libraries: http://maven.apache.org/plugins/maven-ear-plugin/examples/including-a-third-party-library-in-application-xml.html . That said, what is the point of it if, for example, you're already using skinny WARs, and all the dependencies already go into some lib dir?
It's obviously not for other *.jar types, like EJB or application client modules. There's no explanation on the plugin website, though it's not one of the standard Java EE module types: http://docs.oracle.com/javaee/7/tutorial/doc/packaging001.htm .
I would hope they could clarify this in the plugin docs.
Thanks,
Ari

The jarModule is intended as you suggested to hold third party libraries which can indeed be packaged inside skinny war artifacrts.
I think it more come in needs when there is common dependencies between war modules inside a single ear one.

Related

Simple and Elegant Way to Include Libraries / Jar Files

My problem is similar like this question:
Storm command fails with NoClassDefFoundError after adding jsoup as provided dependency
But I want to know the latest solution and better way to solve this.
I will post the same description in storm user mailing list:
Hi all,
I am building a topology with a load of libraries, such as spring, geotools, etc. Right now, I extract each jar files and pack it into one jar, (as suggested by many forums), using maven. The problem here, each jar sometime has conflicting files, so I have to merge manually. Another thing, though I pack my libraries in jar, storm loads its libraries first. For example, I use guava 16, and storm uses guava 13. My program won't work because guava 13 is loaded.
Current solution is I change the clojure script to put my jar first in the classpath before other jars. Or, I put my jars in lib/ directory.
Is there any simple and reliable way to include jar in Storm? Sorry if this email is too long. I want to make myself clear.
You can use the maven-shade-plugin instead of the maven-assembly-plugin to build your uber-jar. Then, use the relocation feature to move classes into a different package.

Reference a eclipse plugin from a regular project

this is a more conceptual question:
I want to create an application which uses the WALA framework, which itself is packaged as a eclipse plugin, built with maven-tycho. When I try to add this as an dependency no transitive dependency gets resolved, because they are covered by the tycho build.
This is the pom of the WALA project I need at least https://github.com/wala/WALA/blob/master/com.ibm.wala.core/pom.xml
Should my application be a OSGI Bundle itself or can I create a regular jar with it without having much trouble? Which approach is more practical?
If I have seen it correctly, wala.core has only two dependencies wala.util and wala.shrike (util has none, shrike depends on util). So you might as well simply include all three dependencies in your project.
On the long haul, however, you might should indeed consider creating an osgi application instead.

What is the intended use case for Bundle-Classpath in OSGI bundles

I am trying to understand the intended use case for Bundle-Classpath in OSGI bundles.
Here is my understanding, please help me understand if this is correct.
Let's say I am working on creating an OSGI bundle which will be deployed in an ecosystem of other bundles. The bundle I am working on needs some other bundles, but they are not loaded/exported in this ecosystem, and I do not have control on what the ecosystem exports. In such a scenario, I can put these bundles inside some directory (say 'lib') which becomes part of my bundle. These bundles should also be referenced from the Bundle-Classpath, so they can be loaded.
Is this a correct use case for Bundle-Classpath ?
Will these additional bundles also be loaded in the OSGI container and will packages exported by them be available to other bundles ?
Bundle-ClassPath is intended for including dependencies in our bundle, so that our bundle can be deployed standalone.
Let's take an example. Suppose the code in my bundle uses a library, e.g. Google Guava. I have two choices for packaging my bundle:
Simply create my bundle with only my own code inside it. The bundle will now have the Import-Package statements that declare a dependency on Guava, and anybody who wants to deploy my bundle into his application will also have to deploy Guava.
Alternatively I can include a copy of Guava inside my bundle and reference it from my Bundle-ClassPath. Whoever deploys my bundle can deploy just my bundle, and doesn't need to worry about where to get Guava from. In fact, the existence of Guava inside my bundle is an implementation detail, and the deployer doesn't even need to know that I am using it.
The choice between these two options is a trade-off. Option 2 has the advantage that my bundle is easier to deploy because it is standalone -- everything it needs is right there inside it. On the other hand my bundle is much bigger than it needs to be, which could become a problem if lots of other bundles also embed their own copy of Guava.
A more severe problem with option 2 is that all of the dependencies of the library now become my dependencies as well. Actually Guava is a rare example of a Java library with no dependencies of its own... but many other Java libraries drag in a huge tree of transitive dependencies. If you use this approach with, say, Hibernate then your own bundle will also have that large dependency set. This gets very ugly, very quickly.
So, you should be cautious not to overuse Bundle-ClassPath/Embed-Dependency. You should only consider using it if the dependency is (a) small, and with no transitive dependencies, and (b) your bundle uses the library as an internal implementation detail, i.e. it is not part of your public API.
UPDATE
I forgot to answer your second question about the exports. The answer is NO, the exports of any "bundles" you put on your Bundle-ClassPath will NOT become exports of your own bundle. In fact the JARs we put on Bundle-ClassPath are not treated as bundles at all, they are just JARs.
You can choose to export packages that come from within the JARs on your Bundle-ClassPath but you have to do this in the MANIFEST.MF of your own bundle.
The most common use case for this header is the packaging of external libraries. Let's say you have some library foo.jar, and want to use its classes in your bundle.
You put the jar into your bundle like so,
/
com/company/Activator.class
foo.jar
META-INF/MANIFEST.MF
In you manifest, you can now use
Bundle-ClassPath: foo.jar,.
Remember to include the . on the classpath, or you will not be able to find the classes in your bundle.
When classes are on the Bundle-ClassPath, you can use them like any other class: use them in your code, or export them.
I think you may be a bit off here.
A Bundle-Classpath is an ordered, comma-separated list of relative
bundle JAR file locations to be searched for class and resource
requests.
What this means is that when some bundle class needs another class in
the same bundle, the entire bundle class path of the containing bundle
is searched to find the class.
From OSGI in Action.
Let's consider a concrete case. Imagine a bundle (JAR file) with the following structure:
src/a/A.class
src2/b/B.class
src3/c/C.class
if you wanted a.A, b.B and c.C to be available to each other, you'd have to define src, src2 and src3 as pertaining to the bundle classpath. That would mean you'd have to add to your manifest file the following line:
Bundle-ClassPath: src,src2,src3

how can I find the artifactId and version information for '"libopencv_java.so" and "libnative_camera_r2.2.2.so" in pom.xml in Maven?

I've searched for hours but no artifactId and version information for "libopencv_java.so" and "libnative_camera_r2.2.2.so".. I know how to add dependency into pom.xml to be included in lib/armeabi in .apk, but I just cannot find the correct information.. The pox.xml keeps complaining
"Missing artifact org.opencv:libnative_camera_r2.2.2:so:2.2.2
Missing artifact org.opencv:libopencv_java:so:1.0"
Thank you so much~!!
These are native non-Java libraries. They aren't normally handled by Maven. If you would like to use static objects in your module, I suggest you have something like ${basedir}/lib and place your static libraries in there. Add the directory as a <resource/> as well and have it included in you jar. I think it should be possible to load the .so from within the jar. This is one option.
Another option would be, (if you really, really must re-use the .so-s across modules), to extract them to a separate module and have your module depend on that one.
Either way, you'll need to do quite a bit of magic, which isn't covered by Maven by default.

Best way to package a command line Java project

I'm creating a java command line project, with no GUI. The project uses any number of open source projects : Spring, Logback, Commons CLI etc.
When I started to think about packaging, I imagined it would come out as a zip file, that could be exploded to the jar, with a lib sub directory, and dependent jars in the lib.
adapter.jar
/lib/dependencyA.jar
/lib/dependencyB.jar
etc.
I've been playing with Maven Assembly, but it's still not coming out like the above, and I haven't found any examples that do generate the structure above. Is it possible to do so ?
In addition, having a multi-module structure adds another layer of complexity that I haven't been able to resolve, as the assembly module can't find the core module as a dependency. This is my first Maven project, so am still learning how Maven works. I've been through the Sonatype book, but missed something as even using the Best Practices section couldn't get the missing dependency resolved.
The examples I've seen usually involve merging into an uber executable jar, some of which use the Shade project, some don't. My question is, is doing an uber jar including 3rd party libs like Spring etc a good idea ? Or should I persevere with my original zip / lib subdirectory plan ?
Have your assembly module depend on the modules you want to package and then use the <dependencySets> of <moduleSets> tags to include them in any layout you wish. If you have some other files that do not come from a dependency, you can put them in the deployment module itself.
Please have a good read on the assembly descriptor docs. You can pack, unpack, include/exclude and set permissions for the files in your assembly.
In case you haven't seen the sonatype book on maven, here is the relevant chapter: http://www.sonatype.com/books/mvnref-book/reference/assemblies-sect-best-practices.html
EDIT: escaped the <'s
You just need to be more specific in your assembly descriptor. Use one dependencySet that includes only the main jar and delivers it to the top, and another that excludes only the main jar and delivers to the lib dir.

Resources