Jboss EAP 6.1 spring modules class loading not working - spring

I have a spring integration project deployed in jboss as a WAR file.
The project uses maven and structured to support any type of archival War or Jar.
However, the dependencies of the project (all spring jars and custom jars) should be externalized
The reason would be that, later there would be 100s of Spring Integration flows would be deployed and if we have the jars in WEB-INF/libs the size of WAR grows to ~ 50MB. As we have abstracted much of our functionality in a seperate jar (would be added as dependency to my spring integration project), Externalization will result in reducing the WAR file to ~ 5 KB.
I do not have a web.xml and use the WebInitializer for loading the context (Which is part of my common functionality and added as dependency)
Below is what I have tried with JBOSS.
Created a module com.xxx.yyy and added all my spring/third party and custom jars as resources.
Added the dependency to manifest file. (This did not work)
Added the jboss-deployment-structure.xml to my war WEB-INF (did not work)
If I give the wrong module name its throws errors as module
not found.
The war gets deployed, but not initialized. If I have the dependencies in my WEB-INF/lib, everything works as expected.
Below is the jboss deployment structure xml that I used.
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
<deployment>
<dependencies>
<module name="com.xxx.yyy" services="import" >
<imports>
<include path="META-INF**"/>
<include path="org**"/>
</imports>
</module>
</dependencies>
</deployment>
</jboss-deployment-structure>
Here is the expectation,
Externalize the Jar dependencies.
Import the dependencies to my war(manifest or jboss-deployment-structure.xml)
Should be used Spring Service should be initialize.
The deployed war should be working as it does if the libraries are
in WEB-INF
Please help...

With JBOSS EAP 6, Its not possible to deploy the war without a web.xml, But such is possible only with tomcat or by using spring boot.
Also, to address this problem, we had to create a dummy web.xml and use jboss modules to load dependencies.

Related

Exclude all modules from Wildfly 10

I'm trying to deploy my Spring-boot app to a wildlfy server.
However, i'm finding some conflicts between the libs.
So, i want my app to use only what i define on my pom, and completely ignore all wildfly modules.
Is it possible?
Using Wildfly 10 and spring-boot 2.x
Modules
Yes, it is possible. According to the RedHat docs, §3.4, and according to my practice which I have tested several times: You can PREVENT A Module being implicitly loaded. For this:
Create (if not already existing) jboss-deployment-structure.xml file and add this into that file:
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.javassist" />
<module name="org.dom4j" />
<module name="org.apache.commons.configuration" />
<!--and so on.. -->
</exclusions>
</deployment>
</jboss-deployment-structure>
add this (jboss-deployment-structure.xml) file to the project (For a web application (WAR) add this file to the WEB-INF directory. For an EJB archive (JAR) add it to the META-INF directory).
Sub-systems
On the other hand, EAR files (modules) will most likely include sub-systems, like WAR and JAR files. You can exclude only sub-system, from the module, as well. For this, include this snippet in the same (jboss-deployment-structure.xml) file:
<exclude-subsystems>
<subsystem name="SUBSYSTEM_NAME" />
</exclude-subsystems>

Deployed Web application getting nosuchmethod error for javax.json.JsonValue.asJsonArray - Jboss eap 7.0 linux server

I have a web application deployed to jboss eap 7.0 on linux.
Within my java code I am using javax.json.JsonValue.asJsonArray method.
When I run locally on tomcat all runs fine.
Once I deploy to Jboss I get a nosuchmethod error on asJsonArray method. within my WEB-INF\lib folder I have the necessary json jar with that method javax.json-1.1.4.jar. I have discovered that under modules within Jboss it has its own version of javax.json \jboss-eap-7.0\modules\system\layers\base\org\glassfish\javax\json\main\javax.json-1.0.3.redhat-1.jar.
It is my speculation that when I run my application it is first looking at jar within the Jboss modules directory rather than the jar within the WEB-INF\lib folder in the war file. How do I direct the application to reference the jar within the WEB-INF\lib and not the jar withing the jboss modules?
You can exclude the JBoss provided dependency using jboss-deployment-structure.xml file which you need to place under the WEB-INF directory of your war. You have to specify the exclusion dependencies something like below.
`<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="$LIBRARY_OR_MODULE_YOU_WANT_TO_EXCLUDE"/>
</exclusions>
</deployment>
</jboss-deployment-structure>`
e.g. <module name="javax.json.api"/>

Websphere Liberty Profile: [WARNING ] SRVE0190E: File not found in library that is contained in the EAR file

Currently I have a problem during migrating a Java Enterprise project form old WAS-8 to Liberty Profile 17. In my case the environment cannto find a bunch of css/js files in the richfaces jar. Loading a page in the browser, WLP17 writes warnings like this into the logfile:
[WARNING ] SRVE0190E: File not found: /org.richfaces.resources/javax.faces.resource/org.richfaces.staticResource/4.5.17.Final/PackedCompressed/org.richfaces/jquery.js
I build the project using maven and I defined the richfaces dependency in the parent pom like this:
<dependency>
<groupId>org.richfaces</groupId>
<artifactId>richfaces</artifactId>
<version>4.5.17.Final</version>
</dependency>
Then, I have several EJB and WAR projects that are packed together into an EAR file. The WAR projects using richfaces contain a richfaces dependency with scope provided:
<dependency>
<groupId>org.richfaces</groupId>
<artifactId>richfaces</artifactId>
<scope>provided</scope>
</dependency>
Finally, the EAR pom has the dependency on richfaces to ensure that the library is included in the EAR file. For any reason the liberty is not able to find resources located in the richfaces jar.
I inspected the created EAR file, it contains the richfaces libraries. Then, I inspected the richfaces libraries, the also contain the files that are not found.
Is there any more configuration I have to do?
Jar libraries which are expected to serve static files from META-INF/resources/ should be bundled in the web application WAR. Section 4.6 from the Servlet 3.0 spec is relevant:
The getResource and getResourceAsStream methods take a String with a
leading “/” as an argument that gives the path of the resource
relative to the root of the context or relative to the
META-INF/resources directory of a JAR file inside the web
application’s WEB-INF/lib directory...
#wtlucy's comment did solve my problem. Thank you.
I have put the richfaces libraries into the WAR files that need these libraries.

How is a war file created for spring boot with maven?

I'm trying to follow the guide for converting a spring project to a war.
http://spring.io/guides/gs/convert-jar-to-war/
It starts out using maven and gradle and then right after the jar portion it completely forgets about maven and only has gradle updates.
There are two main changes that you need to make in the pom. The first is to change the project's packaging type to war:
<groupId>org.springframework</groupId>
<artifactId>gs-convert-jar-to-war</artifactId>
<version>0.1.0</version>
<packaging>war</packaging>
The second is to add a dependency on spring-boot-starter-tomcat and mark it as provided:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
mvn package will now produce a war file that can be run using java -jar or deployed to a separate servlet container.
There is an official guide at spring:
http://spring.io/guides/gs/convert-jar-to-war-maven/
Pay attention to "Initialize the servlet" section.
It explains an important point of adding a class that substitutes web.xml. Without it (or without proper web.xml) you will get a war file but when deployed nothing will be accessible in browser as nothing will be registered as your request dispatcher.
Also note that it is best to run this example on Tomcat 8 as it supports latest servlet specs. I have spent number of hours trying to figure out why it does not work on my Tomcat 7.

One Spring Boot project, deploy to both JAR or WAR

Is there a way to have a single Spring Boot project be packagable into both JAR and WAR without changing the pom.xml or the application source?
I've read Converting a Spring Boot JAR Application to a WAR, but it converts the project to WAR and it loses the ability to be packaged as JAR.
I don't expect mvn package to do both. What I want is something like mvn i-want-a-jar and it would package the project as JAR. Or I could run mvn i-want-a-war and it would package the project as WAR.
Is this possible?
I managed to do it by adding
<packaging>${packaging.type}</packaging>
to the POM file and then setting different profiles for JAR and WAR:
<profiles>
<profile>
<id>jar</id>
<properties>
<packaging.type>jar</packaging.type>
</properties>
</profile>
<profile>
<id>war</id>
<properties>
<packaging.type>war</packaging.type>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
</profiles>
Now mvn package -P war produces a WAR and mvn package -P jar produces a JAR.
Another option is to create separate modules for JAR and WAR, but I didn't go that route.
What's wrong with a WAR file that's executable? Isn't that what you really need?
P.S. like
java -jar name.war
We've recently had a similar requirement, where an existing Spring Boot based project that was originally packaged as an executable Jar needed to support Tomcat and WildFly deployments.
Due to some dependencies used in this project (for example WebJars), a simple switch to WAR package wasn't an option since some of those dependencies were required for WildFly (VFS support) but not for other deployment.
The solution was to restructure the project modules in a way that core module contained the actual project but without having Spring Boot’s plugin applied, while several package modules would depend on core module and configure deployment artifact specifics (Boot and other plugins, deployment specific dependencies etc.).
That way project build was able to generate multiple deployment artifacts (Boot's executable JAR, traditional WAR and WildFly specific WAR) in a single build run.
In case anyone finds this useful, the sample project to demonstrate the approach is available on Github. The project can be built by either Gradle or Maven.

Resources