Wildfly module classloading - java

I have come across a rather curious issue with wildfly classloading. I have a java-ee webapp, structured as follows:
some.ear
+- some.war
+- EJBs.jar
both the war and the jar require some spring classes to function properly. I defined a spring module containing the relevant classes. Within jboss-deployment-structure I have a section as follows:
<jboss-deployment-structure>
<deployment>
<dependencies>
...
<module name="org.springframework.spring-web"/>
...
</dependencies>
</deployment>
After launching my webapp, I get a ClassNotFoundException when deploying the war-archive.
If I add an additional section
<sub-deployment name="some.war">
<dependencies>
...
<module name="org.springframework.spring-web"/>
...
</dependencies>
</sub-deployment>
it works.
My understanding is, that every module from the main-deployment section should also be visible in all sub-deployments.
Can anyone shed some light on this issue?

Each sub-deployment would need it's own set of module dependencies. If you were to include the module libraries in the EAR/lib directory instead of creating a module then you'd not need to add the module dependency for each sub-deployment.

Related

How to deploy a module in an Alfresco deployed in Tomcat

I have successfully deployed alfresco community 4.2.f in a Tomcat 7.0.59 with a database MySQL5.6 and jdk1.8.0_141
No problems thus far, now, I got a module developed by our company which I need to be deployed in alfresco. This module invokes a WS which will send a PDF to some place.
I got this module in a jar compiled with jdk1.8.0_141
I tried to put it inside the alfresco.war before deployment in Tomcat in WEB-INF/lib but when I do that and deploy with startup.bat from Tomcat it pops in the console
instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/codehaus/xfire/XFireRuntimeException
I understand this exception is caused by putting the jar inside the war.
I was told that the jar was compiled also in jdk8.
Also, tell you that if instead of this jar I put inside the alfresco.war in WEB-INF/classes a properties file to get our database in deployment it works fine.
The problem is when I try to deploy the module.
I saw there are quite tutorials pointing to do something like:
java -jar bin/alfresco-mmt.jar
I can't do that because this is done installing alfresco with its wizard I assume. I did it deploying alfresco in a fresh tomcat installation.
Does anyone know how to deploy our module with the way we deployed alfresco? Thank you.
You have two ways to install your amp :
The first traditional one :
This is the one installed with the apply amp procédure (alfresco-mmt).
To me, this is not true that it is not compatible with your installation. You can easily find the bin folder (containing the alfresco-mmt.jar file) here in the alfresco packaging : https://download.alfresco.com/release/community/4.2.f-build-00012/alfresco-community-4.2.f.zip
When you have it, you can follow the documentation : http://docs.alfresco.com/4.2/tasks/amp-install.html
And apply your amp for example following this way :
java -jar alfresco-mmt.jar install <AMPFileLocation> <WARFileLocation>
The second one :
You can recreate the war with the alfresco sdk and include in the build the module you created.
If you follow this documentation : http://docs.alfresco.com/4.2/tasks/dev-extensions-maven-sdk-tutorials-all-in-one-archetype.html
the war produced in the target folder of the repo part will contain your module, since the pom of this module will contains a dependency to the amp module :
...
<dependencies>
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco</artifactId>
<type>war</type>
</dependency>
<!-- Demonstrating the dependency on the repo AMP developed in the 'amp'
module -->
<dependency>
<groupId>x.y.z</groupId>
<artifactId>my-amp</artifactId>
<version>${my-amp.version}</version>
<type>amp</type>
</dependency>
</dependencies>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<!-- Here is can control the order of overlay of your (WAR, AMP, etc.)
dependencies | NOTE: At least one WAR dependency must be uncompressed first
| NOTE: In order to have a dependency effectively added to the WAR you need
to | explicitly mention it in the overlay section. | NOTE: First-win resource
strategy is used by the WAR plugin -->
<overlays>
<!-- Current project customizations -->
<overlay />
<!-- The Alfresco WAR -->
<overlay>
<groupId>${alfresco.groupId}</groupId>
<artifactId>alfresco</artifactId>
<type>war</type>
<!-- To allow inclusion of META-INF -->
<excludes />
</overlay>
<!-- Add / order your AMPs here -
<overlay>
<groupId>x.y.z</groupId>
<artifactId>my-amp</artifactId>
<type>amp</type>
</overlay>
</overlays>
</configuration>
</plugin>
</plugins>
</build>

java.lang.LinkageError: Failed to link freemarker/core/TemplateElement

My problem is that i have an ejb which internally uses freemarker tool to generate a HTML page, built and deployed to JBoss EAP 6.4.10. When i try to access this functionality (which generates HTML code using freemarker tool), jboss throwing below errors:
java.lang.LinkageError: Failed to link freemarker/core/TemplateElement
Caused by: java.lang.NoClassDefFoundError: javax/swing/tree/TreeNode
I added freemarker jar in my jboss modules and it's module.xml looks like this:
<module xmlns="urn:jboss:module:1.1" name="org.freemarker">
<resources>
<resource-root path="freemarker-2.3.25.jar"/>
</resources>
<dependencies>
</dependencies>
</module>
Finally it is found out that the error is due to missing dependency 'javax.api' in freemaker's module.xml file, after adding this dependency in module.xml as below the problem has resolved.
<module xmlns="urn:jboss:module:1.1" name="org.freemarker">
<resources>
<resource-root path="freemarker-2.3.25.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
</dependencies>
The Google App Engine has this same problem, that some classes that are mandatory in Java SE aren't present there. So try to use org.freemarker:freemarker-gae instead of plain org.freemarker:freemarker.
What kind of platform is that anyway, why's that class missing? Is it Google App Engine?
Update: Certainly JBoss EAP's class loader doesn't export the javax.swing package from some reason (see comments). While using freemarker-gae works that around, then you have to be careful to exclude the non-gae FreeMarker-s coming from elsewhere as transitive Maven (or Gradle, etc.) dependencies. So it would be more maintainable to fix the JBoss modules configuration instead. I saw some start JBoss EAP with -Djboss.modules.system.pkgs=javax.swing, though if Swing is available for other modules in the same JVM, then there must be a more elegant solution, such as adding something to deployment-structure.xml, or if you define your own JBoss modules then to its module.xml. Maybe you should check which standard module exports the swing packages ("javax.api"?), and try to declare that module as a dependency.

JBoss 7 Classloader -- Exclude Module Implementation

I have a simple piece of code instantiating a JBoss Hot Rod client and this is deployed in an .ear file on Jboss 7
System.out.println("Attempting to RemoteCacheManager at: "+ipAddress);
Configuration conf = new
ConfigurationBuilder().addServer().host(ipAddress).port(11222).build();
RemoteCacheManager manager = new RemoteCacheManager(conf);
RemoteCache defaultCache = manager.getCache();
System.out.println("SUCCESS OUT: Connected to RemoteCacheManager at: "+ipAddress);
logger.info("SUCCESS: Connected to RemoteCacheManager at {}",ipAddress);
However when I deploy the app it cannot find the the class/method RemoteCacheManager
Caused by: java.lang.NoSuchMethodError: org.infinispan.client.hotrod.RemoteCacheManager.<init>(Lorg/infinispan/client/hotrod/configuration/Configuration;)V
My App has a structure like this
--ear
---lib
---infinispan-client-hotrod-6.0.2-FINAL.jar
--- other .jars
---META-INF
---MANIFEST.MF
---myservice.jar
---mysrvice.war
This is caused because I include the latest hot rod client as a maven dependency but an older version is available as a module. How can I tell Jboss to exclude the older implementation in its module
Thanks
the issue in this case was not as I thought. The issue was JBoss already included an older version of hot rod as a module and hence the "java.lang.NoSuchMethodError"
The solution, to exclude a module and provide a new implementation via new maven dependency is to use the jboss-deployment-structure.xml. Place this file in ear>src>main>META-INF>application
I am being extra careful below by excluding from main deployment and subdeployment and left it here for illustration purposes. I will remove one entry later...
<?xml version="1.0"?>
<exclusions>
<module name="org.infinispan.client.hotrod"/>
</exclusions>
<sub-deployment name="myservice-ejb-1.0.1-SNAPSHOT.jar">
<!-- This corresponds to the module for a web deployment -->
<!-- it can use all the same tags as the <deployment> entry above -->
<exclusions>
<module name="org.infinispan.client.hotrod"/>
</exclusions>
</sub-deployment>
</deployment>

xalan and xerces in jboss eap 6.0.1

I'm migrating an application from Glassfish 2.1 to Jboss eap 6.0.1. Now I deploy my app in Jboss correctly but it doesn't work. I have made debug and I saw the problem. When the code arrives to this line:
OutputFormat format = OutputFormat(doc);
It fails. I made a new watch of "OutputFormat(doc)" and in the value appears this: Unknown type "org.apache.xml.serialize.OutputFormat"<
This class is inside xerces library. This library is installed as a module in my jboss. I have tried many things:
1.- Exclude jboss library and included the library in my war. Not deploy.
2.- Include my library (no JBoss' library) as a new module and, in the manifest, add this line: Dependencies: myModuleName. It deploys, but it doesn't work.
3.- The before "solution", and exclude jboss library. Not deploy.
This ocurred when the code arrives at the following line, and I have tried the same solutions:
XPathAPI.selectSingleNode( xmlTempDoc,"//a" )
The error at this time is: Unknown type "org.apache.xpath.XPathAPI"
This packages are in xercesImpl-2.9.1 and xalan-2.7.1 libraries respectively.
Can you help me, please?
Thanks,
Regards.
Try to exclude the default xalan and xerces libraries that come packaged witn JBoss EAP by adding jboss-deployment-structure.xml under /WEB-INF with below content:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclusions>
<module name="org.apache.xalan" />
<module name="org.apache.xerces" />
</exclusions>
</deployment>
</jboss-deployment-structure>
Then include yours in some path such as /lib folder.

Maven with Jenkins - Update parent pom version of dependency

I have a pom file that looks similar to this
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>myApp</groupId>
<artifactId>myAppId</artifactId>
<packaging>war</packaging>
<version>1.2-SNAPSHOT</version>
<name>Maven Test Webapp</name>
<url>http://maven.apache.org</url>
<dependency>
<groupId>com.manydesigns</groupId>
<artifactId>portofino-war</artifactId>
<version>3.1.10</version>
<type>war</type>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>TestName</finalName>
</build>
</project>
If i run 'mvn release:prepare' on the above pom file, the version of the artifact changes. i.e. it becomes
<version>1.2</version>
Now lets say i have gone and updated the portofino-war application which is a dependency of this pom file. portofino-war is now at version 3.1.11 but the parent pom file points to version 3.1.10 as shown above.
Is there any way i can update the parent pom (either via Maven or Jenkins) file if a new version of portofino-war is built?
Thanks
Edit
The application uses Maven overlays - http://maven.apache.org/plugins/maven-war-plugin/overlays.html to build a war file from other war files. This means that if any of the dependent modules are built, the parent module has to be built to produce the final war file.
The problem is that at the moment if i build any of the modules, i have to manually update the version in the parent pom file to build using the correct module version.
Edit 2
Thanks for your help Ralph. Basically this is what i would like to achieve:
What i am trying to do is create a maven project that will build a war file based on several modules. Assume the modules have the following structure:
Module 1
customerModule
|-webapp
|-jsp
|-customer
|-findCustomer.jsp
|-addNewCustomer.jsp
|-deleteCustomer.jsp
|-src
|-com
|-mycompany
|-customer
|-FindCustomerAction.java
|-AddCustomerAction.java
|-DeleteCustomer.java
Module2
productModule
|-webapp
|-jsp
|-product
|-productCustomer.jsp
|-addNewProduct.jsp
|-deleteProduct.jsp
|-src
|-com
|-mycompany
|-product
|-FindProductAction.java
|-AddProductAction.java
|-DeleteProduct.java
Module3
commonModule
|-webapp
|-css
|-style.css
|-jsp
|-templates
|-coreTemplate.jsp
|-src
com
|-mycomany
|-common
|-Logger.java
|-Access.java
|-META-INF
|-MANIFEST.MF
|-context.xml
|-WEB-INF
|-lib
|-oraclejdbc.lib
|-log4j.lib
|-common.lib
|-struts-config.xml
|-tiles-def.xml
|-web.xml
Each of the modules shown will be developed by a different team. Each team produces a war file and installs it in the local maven repository. As an example the repository could look like this
com
|-customerModule
|-customerModule.v2.1.war
|-customerModule.v3.0.war
|-productModule
|-productModule.v3.0.war
|-productModule.v3.1.war
|-commonModule
|-commonModule.v0.5.war
|-commonModule.v3.0.war
Now the build manager uses the above war files to build the final deployable war file. I was originally planning to use maven overlays to merge the three war files. I did test the merging of war files with overlays and found that the following configuration worked. i.e. using dependencies:
Note: These dependencies are in the commonModule pom file
<dependency>
<groupId>com</groupId>
<artifactId>customerModule</artifactId>
<version>3.0</version>
<type>war</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com</groupId>
<artifactId>productModule</artifactId>
<version>3.1</version>
<type>war</type>
<scope>compile</scope>
</dependency>
If i then build the commonModule module, i end up with one war file that contains all the contents of Module1, Module2 and Module3. Which ends up with something like this:
MyApp.war
|-webapp
|-css
|-style.css
|-jsp
|-customer
|-findCustomer.jsp
|-addNewCustomer.jsp
|-deleteCustomer.jsp
|-product
|-productCustomer.jsp
|-addNewProduct.jsp
|-deleteProduct.jsp
|-templates
|-coreTemplate.jsp
|-META-INF
|-MANIFEST.MF
|-context.xml
|-WEB-INF
|-lib
|-oraclejdbc.lib
|-log4j.lib
|-common.lib
|-customerModule.jar
|-productModule.jar
|-classes
|-com
|-mycomany
|-common
|-Logger.class
|-Access.class
|-struts-config.xml
|-tiles-def.xml
|-web.xml
The above works but requires a bit of manual intervention for a full release. Here is an example of what would happen if a module is modified
Team 1 updating module 1
- Team 1 makes changes to module 1 and check in changes into CVS
- Team 1 installs module 1 onto the maven repository by issuing mvn:prepare and mvn:perform on module 1. This adds a new version of customerModule.war on to the local repository
- Team 1 updates the dependency version for module 1 in the pom file used to merge the war files (i.e. commonModule)
- Team 1 builds the deployable war file by building the commonModule.
The above does not use a multi module project as you suggested so i am trying to understand how the versioning would work with multi module projects. For example, lets say the multi module project will look like this
MyApp
|- productModule
|-pom.xml
|- customerModule
|-pom.xml
|- commonModule
|-pom.xml
|-pom.xml
What is the difference in adding the version number in each child module compared to just havin the version number on the parent?
You say that the child modules will use the parent version. Lets say the parent version is currently version 3.4, how will it know that it is supposed to use version 3.1 of the productModule.war?
And finally, if team 1 has made a change to one of the child modules, would they still need to build it and deploy it on to the maven repository as an individual product first before building the multi-module project or can this be done as one step?
How would this work if i want to make a patch release that does not necessarily mean using the latest version of a specific module?
Thanks
For the scenario described in the "Edit" part of the question, I would recommend to put all war files in a single: multi module project.
You may want to use a dependency range instead of updating the pom: http://docs.codehaus.org/display/MAVEN/Dependency+Mediation+and+Conflict+Resolution#DependencyMediationandConflictResolution-DependencyVersionRanges

Categories

Resources