What must an EAR flle (java) contain? - ear

I am exploring Java EE 6 deployment choices. I understand what a WAR file is and, conceptually, I understand the purpose of an EAR file is to package together WAR modules and/or other Jar resources so that the whole deployment can be seamless.
My question is, what is the minimum that an EAR must contain. My investigation leads me to believe that there must be at least one WAR module present, as the EAR is nothing more than a wrapper and additional configuration xml.
Also, is there a definitive paper showing all the config files and the xml elements which could be included? (sometimes I find it easier to grasp concepts when I dive straight in and review the config options.)
Many thanks for your assistance

Related

How to convert EAR application into one large OSGI bundle and deploy it in Equinox container?

As part of cost cutting, management want to cease usage of websphere application servers in developer systems.
I was given task to convert the EAR file to one fat OSGI bundle and deploy it in equinox container. if successful, this set up will be shared among developers and will only be used in developer machines and not in higher enviroments.
I have searched many websites but didn't find any concrete solution.
Kindly share your ideas if any to solve the problem.
I strongly encourage you look at Open Liberty: https://openliberty.io
Open Liberty is an open source project launched by IBM last year at Java One. The goal of the project is simple: get awesome Java EE technology into the hands of developers.
Open Liberty supports Java EE 7 and MicroProfile as well as other technologies.
Unless you have a strong technical reason to convert the EAR into an OSGi bundle, you can use Open Liberty in your development environment. The install is easy:
unzip openliberty-18.0.0.1.zip
Give it a try. I think you'll be pleasantly surprised.
If you have questions, Open Liberty has a very active community and twitter or hit me up on twitter #barecode.
An EAR file is simply a JAR file that contains nested JAR files. Those nested JARs form the classpath of the application.
Converting to an OSGi bundle should be as simple as writing a META-INF/MANIFEST.MF for the top-level JAR containing the header Bundle-ClassPath header that lists the contained JARs, e.g.:
Bundle-ClassPath: a.jar, b.jar, c.jar, ...
If the EAR file also directly contains classes that are part of the application classpath, then the new bundle's JAR file should be prepended to the Bundle-ClassPath as an entry named '.' (dot), e.g.:
Bundle-ClassPath: ., a.jar, b.jar, c.jar, ...
Note that the manifest also needs to contain the mandatory OSGi headers, Bundle-Manifest: 2 and Bundle-SymbolicName: .... There is plenty of information available about this online.

maven-ear-plugin jarModule

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.

Should I use POM first or MANIFEST first when developing OSGi application with Maven?

There are two main approaches when developing an OSGi application with Maven: POM-first and MANIFEST first.
I'm looking for an answer that is in a form of a table that shows pros and cons of each method.
To be more specific, I would also like to know how it relates to:
Maturity of toolset
Vendor independence
Development ease (which includes finding people who can do the development on the tooling)
Compatibility
Avoiding ClassNotFound
Avoiding manual work
At present this is what I can come up with
POM-First Pros (using maven-bundle-plugin)
Leverages existing Maven skills, repositories and tooling.
Likely easier to find people who know how to manage pom.xml rather than MANIFEST.MF along with pom.xml
Most of the information in MANIFEST.MF can be obtained from the pom.xml itself.
Can work with other IDEs not just Eclipse based ones.
Less invasive, just add the single plugin and change the packaging type to "bundle"
POM-First Cons
ClassNotFoundException more likely to occur at runtime. However, this can be mitigated using pax-exam (although it is very complicated to set up).
Still need to understand how the MANIFEST is setup to make sure the instructions configuration element is set correctly.
MANIFEST-first Pros (using tycho-maven-plugin)
Seems to be the recommended approach, or at least talked about as the recommended approach, but I can't really see why it has significant benefit. (Hence why this question was asked).
Good for developing Eclipse plugins and integrates well with PDE
Provides tooling for testing thus allowing ClassNotFoundException to appear during JUnit testing rather than runtime.
MANIFEST-first Cons
Seems to only work well on Eclipse based IDEs. You don't have to use Eclipse, but without the PDE would you want to?
Violates DRY principles since I have to do put keep the names and versions from the POM and MANIFEST.MF in sync.
Need to name things in a specific fashion
You cannot mix, meaning existing Maven multi-project installations cannot just tack on OSGi support
A lot more configuration compared to maven-bundle-plugin is needed to get less warnings: http://wiki.eclipse.org/Tycho/Reference_Card#Examplary_parent_POM
Have to make test cases a separate project. It won't run when built in src/test/java.
Seems that it will only test classes that are exposed, in other words those in ".internal." is not testable.
If I were asked for a recommendation for an enterprise that is using Maven already and want to move to OSGi then it would be POM first
If I were asked for a recommendation for someone who is doing Eclipse plugin development, then it is Manifest first -- with tycho
I think you should choose by use case. For server side OSGi projects I favour the pom first style. It nicely matches the maven builds and is much less error prone than Manifest first.
In fact bnd which is behind the maven bundle plugin gets the Manifest right for most cases without any additional config. The trick is to use some naming rules. For example if you name internal package impl or internal the will not be exported. Using this style you can not use the Eclipse plugin perspective (at least without bndtools which I do not like) but I did not yet miss this perspective. I am a developer in the Apache Karaf, CXF and Camel projects where we use this style and it works great. Especially for CXF and Camel it is great that we can support OSGi and non OSGi deployments with the same build and tools.
For Eclipse RCP applications Manifest first is the way to go as you need the plugin perspective and the Eclipse IDE tools. If you want to combine that with maven then tycho is probably the way to go.
MANIFEST first does not lock you to Eclipse (although I'd be surprised if more than a tiny minority would use anything else). The MANIFEST is the file that counts, and needs to be added to a jar, regardless how you do that.
On the other hand, POM first completely locks you to Maven, you lose the advantage that an OSGi bundle is a regular jar you can make any way you want.
I've tried both, I really prefer MANIFEST first. The MANIFEST file is a really important file, I prefer to craft that file over crafting a file that produces that file. If something weird happens, (and it will at some point) the MANIFEST file is the first to check, it's just easier if it's your own file. Besides, you will have to be familiar with it anyway.
So, if Maven is your alpha and omega, POM first will suit you best, but you'll still need to have in-depth understanding of the MANIFEST file.

Maven copy resources in multi module project

My need is pretty basic but I could not find any clean answer to it: I simply need to be able to distribute a resource in a multi-module project.
Let us consider for example the LICENSE file, which I hereby assume to be the same for all modules. I prefer not to manually copy it into each and every module because the file could change over time. I also prefer not to statically link to resources (even if using relative paths) outside the project folder, because the modular structure can possibly change too.
Is there any plugin that can be used to robustly guarantee that each module is given the required file? It would be equally acceptable for such copy to be obtained by exploiting the POM of the parent project or directly performed by the super project in the modular hierarchy.
you could use the assembly and the dependency plugins.. did you stumble over that link?
http://www.sonatype.com/people/2008/04/how-to-share-resources-across-projects-in-maven/
it describes that option ..its from 2008, but maven is around for quite some time.. so I guess its more or less up to date
edit regarding comment
Another option is the maven-remote-resources-plugin.
For a more detailed example see:
http://maven.apache.org/plugins/maven-remote-resources-plugin/examples/sharing-resources.html
Since their intro speaks actually for itself, I quote (maven.apache.org)
This plugin is used to retrieve JARs of resources from remote repositories, process those resources, and incorporate them into JARs you build with Maven. A very common use-case is the need to package certain resources in a consistent way across your organization: at Apache it is required that every JAR produced contains a copy of the Apache license and a notice file that references all used software in a given project.

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