Configure external libraries as Glassfish modules - java

I have several OSGI bundles and WAR packages which use external libraries:
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
<version>4.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>osgi-cdi-api</artifactId>
<version>3.1-b41</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
Instead of building the libraries into every OSGI bundle and WAR package is it possible to copy these libraries into /modules directory of the Glassfish server. I suppose that it's possible to use only one copy without any problem?
EDIT
I found that these libraries can be deployed as modules in Glassfish with the command:
[root#Testserver bin]# sh asadmin add-library /opt/primefaces.jar
But then for example in a simple WAR package what I need to modify in order to use Glassfish modules? The WAR package must be configured to use external libraries I suppose?

I don't think the problem is in your war file, but to be sure you can check the MANIFEST file. If the Import-Package headers are correct, there isn't anything you can do from the war file. If that's the case, there must be a way to convince Glassfish to make a module visible to a webapp (I'm no Glassfish expert, sorry).
Otherwise, fix the Import-Package headers (you can do that manually for now).

You can take a look at this section of glassfish documentation, called Module and Application Versions:
http://docs.oracle.com/cd/E26576_01/doc.312/e24929/overview.htm#gkhhv
"Application and module versioning allows multiple versions of the same application to exist in a GlassFish Server domain, which simplifies upgrade and rollback tasks. At most one version of an application or module can be enabled on a server any given time. Versioning provides extensions to tools for deploying, viewing, and managing multiple versions of modules and applications, including the Administration Console and deployment-related asadmin subcommands. Different versions of the same module or application can have the same context root or JNDI name. Use of versioning is optional."

Related

WildFly App Dev: how to reflect the runtime classpath at development time?

I am working on a Project that is deployed as .war WebApp on a single WildFly 16 instance.
Using IntelliJ Idea UE with Maven as development environment, I ask myself how to reflect the classpath that the deployed app will see at runtime in the development classpath at development time.
I have read about implicit dependencies in the Developer Guide.
So I conclude that the classpath of my deployment will contain the elements from the "Dependencies that are always added" column plus those that are added on trigger conditions (in my case these are Weld, Web, Hibernate, Resteasy, EJB3).
How can I figure out what Maven artifacts I have to import so that my development classpath equals the runtime classpath of my WebApp?
I would like to solve dependency conflicts at development time, not at runtime.
You can use the WildFly 16 Bill of Materials (BOM) for that. I'm sure you are well aware of Maven's import feature for artifacts of type POM. Just in case you are not, add these lines to your Maven pom.xml:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>wildfly-javaee8</artifactId>
<version>16.0.0.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
It enables you to reference most of WildFly's artifacts (or at least the relevant ones) as well as the Java EE 8 specification artifacts. Here's an example:
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_4.0_spec</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- And so on... -->
You still need to list all the dependencies you require though. If you have additional dependencies (not provided by WildFly), you should package them in your WAR or EAR. This way you shouldn't get any conflicts.
Oh, and one more thing, because you mentioned several dependencies, which are WildFly specific (e.g. Weld and Hibernate): Try sticking to Java EE APIs, where possible. It enables you to port your application to other application servers faster, if needed.

More than one fragment with the name [spring_web] was found. This is not legal with relative ordering

I have a spring boot application that works fine when I run it using the embedded server from Intellj. However, when I package it into .war file and deploy it on tomcat I get the following error:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/file-upload-0.0.1-SNAPSHOT]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)
at
org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:985)
at
org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: More than one fragment with the name [spring_web] was found. This is not legal with relative ordering. See section 8.2.2 2c of the Servlet specification for details. Consider using absolute ordering.
at org.apache.tomcat.util.descriptor.web.WebXml.orderWebFragments(WebXml.java:2200)
at
org.apache.tomcat.util.descriptor.web.WebXml.orderWebFragments(WebXml.java:2159)
at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1124)
at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:769)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:299)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:94)
at
org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5176)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 10 more
21-Jan-2019 01:51:04.709 SEVERE [localhost-startStop-1]
org.apache.catalina.startup.HostConfig.deployWAR Error deploying web application archive [C:\Users\dennismo\Dev\Projects\Production Prep\file-upload-module\webapps\file-upload-0.0.1-SNAPSHOT.war]
java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/file-upload-0.0.1-SNAPSHOT]]
at
org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:758)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:985)
at
org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
My project does not contain multiple web-fragment so I don't know what could be causing this problem.
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from salaryPaymentRequestRepo -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<akka.version>2.5.17</akka.version>
</properties>
<repositories>
<repository>
<id>default</id>
<url>http://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.univocity</groupId>
<artifactId>univocity-parsers</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>26.0-jre</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.4.2</version><!-- or latest version -->
<exclusions>
<exclusion>
<artifactId>javassist</artifactId>
<groupId>org.javassist</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.12</artifactId>
<version>${akka.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-stream_2.12</artifactId>
<version>${akka.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-persistence_2.12</artifactId>
<version>${akka.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-testkit_2.12</artifactId>
<version>${akka.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/resources/lib/ojdbc7-12.1.0.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
add <absolute-ordering /> tag to your web.xml just under the <display-name> tag.
should work.
Cleaning the server worked for me. Just do the following :
Right click on the server -> Clean.
Then redeploy the app on the server.
Sounds like you have two different versions of Spring, check your dependencies to see if you have a dependency to another Spring-version.
mvn dependency:tree -Dverbose -Dincludes=groupId:artifactId
I had the same problem when building a war file with maven because I did not clean before packaging and maven was including multiple versions of spring jar files from previous builds.
This error seems to happen after project's spring framework update, clearing the project history file in tomcat webapps may solve the problem.
This problem was solved by adding absolute ordering of deployment descriptors.
The tag <absolute-ordering/> was added to the web.xml
Reference:
https://www.oracle.com/technetwork/articles/javaee/javaee6overview-part2-136353.html
I had this occur after I updated the Spring Framework version in a Maven project. I was finally able to resolve the issue by running mvn clean, apparently the old Spring JARs were being picked up somewhere under target.
This error generally comes from that if we have two copy of spring in our container, which get loaded by different class loaders(in my case shared class loader and webapp class loader).
Check effective pom, if you have any bundle embed spring jars/classes, if so remove it, you should use the one installed as bundle from container.
If you manually adds all the Jars then you have to delete WEB-INF/lib/spring-web-5.2.9.RELEASE-sources.jar or similar jar file (may be your jar version will be different). Once you delete that jar tomcat will start working.
My project is Springboot based version (1.5.21.RELEASE) and generating war and deploying in physical tomcat.
I had gotten the same issue and got resolved with below approach.
Solution: Exclude tomcat-embed-websocket dependency from spring-boot-starter-web in the pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
<exclusions>
**<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
</exclusion>**
</exclusions>
</dependency>
Just an answer from newbbie to newbbies:
Make sure you place web.xml inside /WebContent/WEB-INF.
I placed it inadvertently in /WebContent (not /WEB-INF), and almost got crazy trying to unsuccessfully apply some of the proposed solutions, the error message was exactly the same.
For me this meant that I was including some "shaded jars" that bundled copies of spring within them. So all the same "spring version" but multiple copies of spring causes this.
You can check if this is the case by going to tomcat/webapps/your_webapp/WEB-INF/lib, unjarring all the jars, and searching for "spring_web"
ex:
# first unjar everything then
WEB-INF/lib $ grep spring_web . -r
spring-web-4.3.12.RELEASE/META-INF/web-fragment.xml
7: <name>spring_web</name>
some_other_shaded_jar/META-INF/web-fragment.xml
7: <name>spring_web</name>
If this is the case you'd need to use the absolute fix of the other answers or not include multiple copies of spring somehow.
Seems this is a change introduced in tomcat 7.0.93 FWIW (so it didn't throw this failure in earlier versions of tomcat 7)
Your web.xml should look like this (added <absolute-ordering/> inside the tag web-app tag)
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<absolute-ordering/>
</web-app>
I had the same problem and solved it. Got similar errors but not used spring boot. I have used spring 3.x with java 8. If above solutions are not working change the jars and search whether those jars are compatible with the java version you are using or not. spring 3.x is not compatible with java 8.
I solved similar problem by removing all my apps (I had there two different apps) from webapps folder and then redeployed my war file.
I had to add this in web.xml to make it work :
<absolute-ordering>
<name>fragment_name_if_required</name>
<others></others>
</absolute-ordering>
All these answers are great but also check if "Apache CXF" lib is in your classpath, it apparently conflicts with Spring Web 5.2.3, for me I temporary removed because I'm actually not using it and now my project is running okay.
For me, this issue happened when Tomcat was not properly installed .I have reinstalled and updated the installation path at:
eclipse window->preferences->runtime ENV -> path of the newly installed tomcat
After setting the correct path, it worked fine.
For me , it was because of 2 spring-web jars i.e. spring-web-5.02-release.jar and spring-web-sources-5.02-release.jar in build path. By removing spring-web-sources-5.02-release.jar, issue is solved.
Had the same issue and wanted to get to the root cause. I knew spring-web jar's fragment is called 'spring_web'. However my source code did not have 'spring_web' fragment anywhere else. So I used a tool (jfind) to search for 'spring_web' through an expanded form of my EAR that was generated at build time. Surprisingly, 'spring_web' was found in another project's web-fragment jar that was generated at build time. On resolving this second occurrence, the issue was gone. So it seems to be due to duplicate 'spring_web' fragment and we need to have just one.
If you have previously built the project with another version and then changed the version and tried to build again, this exception is thrown. You can delete the target folder in your application. If you still get an exception, you can go to the project directory from the terminal and type mvn clean install
Remove all the unused dependencies from the lib folder.
Now try to rerun the application on the server.
Hope it will work now.
I was fighting with this few hours. Solution for me was to invalidate IntelliJ cache.
This problem showed up when I was in the process of upgrading spring framework.
Intellij was packaging two versions of the same library and that's why I was getting an error.
This happened to me when I changed the version of one of the dependencies in pom.xml, undeploying and deploying the webapp fixed it for me
See the below Line in error log:
Caused by: java.lang.IllegalArgumentException: More than one fragment with the name [spring_web] was found. This is not legal with relative ordering. See section 8.2.2 2c of the Servlet specification for details. Consider using absolute ordering.
which says to use absolute ordering.
So, you have to add <absolute-ordering/> tag in your web.xml file inside <web-app> tag.

How to avoid duplication of derived dependencies in EAR/WAR with Maven?

To make the example as simple as possible, let's say I have classic Java EE 5 application.
Let's say I use x-lib in EAR module, and x-lib uses commons-io.
Also I use y-lib in WAR module, and y-lib uses commons-io too.
The EAR is set as provided in WAR.
The result I get is:
- app.ear
/lib
x-lib.jar
commons-io.jar
/app.war
/WEB-INF
/lib
y-lib.jar
commons-io.jar
I don't want commons-io to be packaged in app.war/WEB-INF/lib once it is packaged already in app.ear/lib.
In my war's pom.xml I have:
<dependency>
<groupId>my.group</groupId>
<artifactId>app</artifactId>
<type>ejb</artifact>
<scope>provided</scope>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>some.other.group</groupId>
<artifactId>y-lib</artifactId> <!-- This loads commons-io as compile dependency -->
<version>1.2.3</version>
</dependency>
Is there a way to tell maven that I want everything that is provided along with app ejb dependency should be set to provided and not included in WAR?
I do not want to track all those duplicated JARs and set them as provided or exclude explicitly one by one.
EDIT
I am aware of skinny-war solution. However I don't like the drwaback of duplicating dependencies in WAR and EAR. Maybe you know how to overcome this.
From the version 2.7 of the maven-ear-plugin, you can use SkinnyWars.
See here for specs: https://maven.apache.org/plugins/maven-ear-plugin/examples/skinny-wars.html
Basically, you can add the skinnyWars tag to your plugin configuration:
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<defaultLibBundleDir>lib/</defaultLibBundleDir>
<skinnyWars>true</skinnyWars>
</configuration>
</plugin>
That SHOULD be automatic if you add the EJB module as a provided dependency to your war module and let all the dependencies of that EJB come transitively. So don't add the overlapping dependencies to your war pom, just let Maven deal with it.
Is there a way to tell maven that I want everything that is provided
along with app ejb dependency should be set to provided and not
included in WAR?
In this case a think the best option by now is to use wilcards in dependency exclusion.
It is only supported in maven 3.
Below is an example of how to declare the ejbmodule dependency from a war project:
<dependency>
<groupId>ejbModuleGroupId</groupId>
<artifactId>ejbModuleArtifactId</artifactId>
<scope>provided</scope>
<type>ejb</type>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
You can use this same strategy when declaring a dependency to a ejb-client.
Depending on your maven 3 version, you'll get a nasty warning, but in newer versions it must be fine.
You need to add an exclusion like this:
<dependency>
<groupId>some.other.group</groupId>
<artifactId>y-lib</artifactId>
<version>1.2.3</version>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
</exclusions>
</dependency>

Single/complete Maven dependencies for Java EE 5 API

Is there a single maven dependency containing whole Java EE 5 spec API. Just like
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
</dependency>
for Java EE 6.
I'm using JBoss 5 and want to add single (or several) dependency as provided scope and be sure that I have everyting that is available in JBoss.
Maybe some kind of archetype exist for JBoss 5.x.x deployed project?
Based on maven central I think you need the following:
<dependency>
<groupId>javaee</groupId>
<artifactId>javaee-api</artifactId>
<version>5</version>
</dependency>

Java EE Provided dependencies in Hudson / Jenkins

I'm trying to build a Maven based Java EE project on Jenkins, but I'm getting compilation errors. The reason seems to be that the Java EE dependencies that are marked as provided in the POM logically enough aren't downloaded when the project is built.
How can I set up the POM so that the build works in Jenkins, but the EE dependencies aren't included in the WAR file?
My thanks in advance for any input you can provide.
That's strange, AFAIK the dependencies with scope "provided" are simply not placed in the built file, they should however be downloaded. Are you sure your Maven is correctly configured to download dependencies - maybe there's a proxy that's not configured.
Not sure if its the best solution, but you can add EE dependencies with scope "provided", like the example:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.27</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
Maybe there is a plugin who provides all of them to you, but I'm not sure about that.
Hope that helps

Categories

Resources