Configure manifest.mf classpath in ear - maven

I have an ear application which has 3 modules:
web.war
services.jar(ejb)
domain.jar(ejb)
I worked with maven tutorial:tutorial
At the end author says about problems with manifest.mf in web module and suggesting some solutions. But this not worked for me. I think configuration is broken not only in that case. In my ear MANIFEST (classpath) i have also prefix "lib/" before services module(services are separated jar as ejb module in my app).
I saw i can use my specific prepared Manifest.mf, but i don't know how to configure it manually. Could I duplicate jars in my app modules? For example add domain.jar in services and web? Is it correct?
I have specific structure:
1.sample-ear with web and services module
2.sample-web with sample servlet(without dependencies from other project in code).
3.sample-services with dao classes(using entities)
4.sample-domain with entity beans
I tried modify manifests in every package, but I didn't find a solution. When i want to run my application on WildFly10 i get NoDefClassError (Class from domain.jar used in service.jar). Could anyone help to configure it?
On the other hand maybe you have better maven configuration in project and manually configuring the manifest.mf is not needed.

Related

WebSphere 7 org.apache.axis2.deployment.WarBasedAxisConfigurator <init> org.apache.commons.fileupload.FileUploadException

This is a strange problem. I have an existing JEE project that is and has been in production on WebSphere 7. It is a multi-module EAR file. It has 2 WARs and 1 shared Java project. Most of it is Spring 4 based, but we have some web services we host using axis2 (1.5.4). This project does not use Maven. It does use a WebSphere deployment.xml (in the EAR) with the warClassloaderPolicy="SINGLE" and the classloader mode="PARENT_LAST". This controls the classloader policies for this EAR. All the jar files that the Java project and the WARs rely on are stored at the EAR level and referenced at the module level via the manifest files. That all works fine and has for several years.
Now I was trying to convert this project to a Maven project after all these years. Initially, I left the deployment.xml file settings as they always have been. But with these settings I was getting:
java.lang.VerifyError at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl "org.springframework.oxm.jaxb.Jaxb2Marshaller".
After much googling on this site and all around and trying 50,000 things, I tried one thing, which worked for most of the app. I switched the classloader mode to "PARENT_FIRST" and all of a sudden the WAR that exclusively uses Spring 4 worked. It started up without error and I was able to run it.
But, the other WAR which hosts the axis2 web services started getting the error:
org.apache.axis2.deployment.WarBasedAxisConfigurator <init> org.apache.commons.fileupload.FileUploadException....Caused by: java.lang.NoClassDefFoundError: org.apache.commons.fileupload.FileUploadException....Caused by: java.lang.ClassNotFoundException: org.apache.commons.fileupload.FileUploadException
This class (org.apache.commons.fileupload.FileUploadException) is in both the compile and runtime classpath. In eclipse I can see it in the "Maven Dependencies" library that the m2e eclipse plugin creates from the POM files. I can also see this jar in the WebSphere runtime module classpath inspector (it shows up in there 3 times! Once under each WAR and once just in a list from the Maven repository location.)
One thing of note is that I've configured the project with a parent POM, where most of the dependencies are declared at the parent and then are inherited for each of the modules. In the EAR project, the POM is using the maven-ear-plugin with skinnyWars=true. However, it appears the skinnyWars directive is not respected when the m2e eclipse plugin deploys the EAR into the local WebSphere server (that is evident because I see these jars showing up in the classpath 3 times). But when I create an EAR using the Maven build, the EAR comes out correctly with each jar only showing up in the EAR one time.
This is my last hope to post something here and see if someone has an idea for something to try, otherwise I can't think of anything else to try.
Thanks...
Is there a particular reason you need to run with a single class loader for all the WAR modules, other than convenience? If not, you could rework the application in order to allow you to run PARENT_FIRST in the Spring WAR and PARENT_LAST in the Axis2 WAR.
If that's not an option for some reason, the path of least resistance might be to go back to PARENT_LAST and remove some libraries from the app or module. The VerifyError generally occurs if you're running with PARENT_LAST and have a library in the app that is also present in the server - in this case, the exception looks like it's coming out of JAXB, so you might want to see if simply removing JAXB (and perhaps JAXP, if present, since it's heavily used by JAXB) from the application resolves the issue with your default setup.
You could also stick with PARENT_FIRST and move the Axis2 jars to an shared library with an isolated class loader, associated with the app. An isolated shared library would make just the stuff in the shared library PARENT_LAST, so you can avoid the VerifyError and still get PARENT_LAST for Axis2. The issue in the PARENT_FIRST case appears to be because you're picking up WebSphere's copy of Axis2 but somehow have a dependency inserted from your app's copy - the failing class load is occurring in a server-level loader, so it doesn't see the copy in your app.

How can I include a resource file (logback.xml) in a project when building JAR but not when embedded in a WAR?

I'm working on a project that uses two maven projects (named core and webapp); core is built with JAR packaging and used for two different purposes: as a stand-alone app (essentially an executable JAR), and also embedded into webapp.
For its purpose as a stand-alone app, core needs to have its own logback configuration (a logback.xml file) that needs to be included on the classpath. Normal Maven convention would have me put it in src/main/resources/logback.xml. That works fine, but causes a problem when the core JAR is included in webapp. webapp needs to have its own logback configuration, but the container (tc Server or Jetty) is picking up the one from core.jar first.
I realize that logback can be told about a custom config location via a system property (-D on the command line) but that's not viable in a app container like Tomcat or Jetty.
I've read some other people asking about this situation, but none of the solutions I've seen sits well with me. One solution involved setting up a context listener that runs early in the webapp initialization and explicitly configures logback based on a <context-param>. That's a bit brutish in my opinion, and probably a hard sell to my fellow dev team when log4j "just works" in this situation.
I'm far from a Maven expert, so I'm hoping there is some elegant way to get Maven to help me here. Or perhaps some logback extension or add-on that makes it more web-app friendly. Or even a clever idea that I haven't thought of.
There are a number of possible solutions, but the easiest is to put the file in its own module and mark the dependency as provided. The, conspire to have it on the classpath when running the standalone version of the app.
The solution that we ended up using was to leave only the common "non-app" pieces (code and configuration) in core and then extract the other "app" pieces into a new module (batch-app).
The logging configuration only lives in the 2 app projects (webapp and batch-app) that depend on core. core has a logback-test.xml configuration in it, but that's excluded from the JAR that maven builds (since it's in the src/test/resources folder).

Maven ships dependencies inside war but not in jar

I have two maven projects, one (I will call it core) is an ejb-jar (ejb) and the other a war (client).
My client project consumes some ejbs inside my core...so far so good.
But I'm getting a ClassNotFoundException inside my core application because it can't find one class from apache-beanutils...I have set this dependency with compile scope in it's pom.xml but it does not get shipped inside the output jar.
When I check my client.war package I see every compile-scoped dependency inside the WEB-INF/lib folder...but in my core.jar I don't see any of it's dependencies...I'm totally confused about this.
Can someone help me? I tried to google it before asking but I didn't find anything useful so far..thanks.
You can use the maven assembly plugin to bundle all the jars in one super jar.
See this: question

Spring Rest Controllers: deployment to Tomcat

I want to develop a RESTful API within my multi-module Spring-based project using Spring Rest. For that purpose, I have a webapp module and some other business/data layer modules. For example, this would be my simplified project structure:
myProject
-- webapp (war-packaged)
-- business (jar-packaged)
-- data (jar-packaged)
Business module depends on data module and so does webapp on business module. Webapp imports successfully every module's application context. Now I want to be able to use some business module classes that do some kind of calculation according to some data retrieved from a DB in order to provide a certain resource. All examples I had a look at were quite simple and this multi-module approach was not covered at all.
What is the problem? As far as I am concerned, Tomcat loads classes in a certain order. Concretely, it first loads WEB-INF/classes and only then WEB-INF/lib (where all webapp dependencies are placed, business module in this case). So, there goes my question. Where should I place my Controller classes? If I place them within the webapp module I won't be able to autowire any business-module bean since Tomcat will throw a ClassNotFoundException when I deploy the webapp war (at least this is the behaviour I have experienced).
The answer is probably easy but I'm quite new to Spring and its world!
Thank you all in advance.
Your business and data jars would go into the WEB-INF/lib directory. Then those jars will automatically be added to the CLASSPATH for your app when you deploy it. You will need to deploy your application as a WAR file.
Ideally, you would build the business and data jars, add them to some repository, and then the build system would pull the proper version of each jar into the WEB-INF/lib directory for you.
And as to the original question, the controller classes go into the webapp/src directory.
Assuming you are using Maven 2. Make sure your assembly creator (e.g. maven war module) is including your dependent .jar files within the final .war file's WEB-INF/lib directory. This should be the default procedure (per: http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html#dependentWarIncludes ). The other concern, then is whether your sub-projects (business and data) are even creating jars so that they could be included in the WAR output.
If you have doubts as to the contents of that war file, browse the listing of it by executing
'jar tvf $WAR_FILENAME' from the command line and by observing the WEB-INF/lib directory contents. You should see your business and data jars in there. Go further by exploding your war file, then browsing the contents of business and data jar (using 'jar xvf $FILENAME' to explode in a new directory).
Hope this helps!

Maven modules - produce artifact with a mixture of sources from multiple modules

We have a multi module maven project with the following layout
project
- common (contains DTOs and other utils)
- business (containes business services)
- presentation (presentation related)
Now, we have a webservice exposed from business module and we have to give a jar file with just service interface (from 'business' module) and DTOs (from 'common' module) to a dependent application which wants to consume the web service.
What is the best way to produce this artifact using maven?
Most elegant way I could find to solve the problem (without breaking Maven recommendation of one project, one artifact principle) is as below.
Create a maven module named web-services and use CXF-Maven plugin to generate the classes required for consuming the webservice. The artifact produced (jar) will have the required classes to be distributed to web service clients.
http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html
Removing the child module for webservice from parent project's POM xml should help (if i understood the question correctly).

Resources