Classloading issues in JBoss AS7 - migration

JBoss AS7 Developer Guide mentions the following classloading preference from a higher priority to lower priority:
1. System Dependencies - These are dependencies that are added to the module automatically by the container, including the Java EE api's.
2. User Dependencies - These are dependencies that are added through jboss-deployment-structure.xml or through the Dependencies: manifest entry.
3. Local Resource - Class files packaged up inside the deployment itself, e.g. class files from WEB-INF/classes or WEB-INF/lib of a war.
4. Inter deployment dependencies - These are dependencies on other deployments in an ear deployment. This can include classes in an ear's lib directory, or classes defined in other ejb jars.
However, I do not understand the DIFFERENCE between #2 and #3. What kind of dependencies could be classified under category 2 above vs category 3. To me, they look the same.
As an example of migrating my Spring application from JBoss 4 to JBoss 7, I encountered a NoClassDefError for quartz 1.6 jar that our application had been using. The quartz 1.6 jar is right inside the WEB-INF/lib folder of my application. This means it correctly falls under Category 3 above. But most articles on web indicate that I have to put it in either as a JBoss 7 module or define it in the jboss-deployment-structure.xml. Why ???
I have also read the migration guidelines and did the TattleTale exercise as pointed in those guidelines. But don't quite get it on what do I do with the report? I read the answer to this Best Practice for loading 3rd party JARs in JBoss AS7 standalone deployment? - looks like quite some amount of effort will be required for the migration. Does not seem like a quick trivial task considering the numerous dependencies an application can easily have. Can someone please confirm this?
I guess I need a guideline about
For which jars do I create a module.xml? (Possible candidates -
Spring, Quartz, Apache , C3P0 connection pools etc) ???
For which jars do I have a jboss-deployment-structure.xml? (What
could be good candidates here?)
For which jars do I leave them in web-inf/lib folder? (Application
uses certain specialized math libraries - like colt.jar, excel
graphing libraries like - jxls.jar, poi.jar - these seem like good
candidates here).

JBoss AS releases used to manage their set of libraries in different ways. Earlier, Release 4.x was used to define the core server
libraries into the JBOSS_HOME/server libraries. Thereafter, each server definition had its specific library into the server//lib folder.
JBoss AS 7 follows a real modular approach deprecating all earlier approaches. The server bootstrap libraries are now located at the root of the application server. There you can find the jboss-modules.jar archive, which is all you need to bootstrap the new application server kernel, based on the JBoss modules.
For which jars do I create a module.xml? (Possible candidates -
Spring, Quartz, Apache , C3P0 connection pools etc) ???
If there are any dependency jars those could be created as modules and define in the module.xml. Also you need to defined the dependencies of the define library.
ex.
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="rezg.rezg-dto">
<dependencies>
<module name="org.apache.log4j" />
</dependencies>
<resources>
<resource-root path="rezg-dto-1.0.0.jar"/>
</resources>
</module>
Connection pool can be configured as a module and the procedure for installing a new module
requires copying the .jar libraries in the appropriate modules path and adding a
module.xml file, which declares the module and its dependencies.
For which jars do I have a jboss-deployment-structure.xml? (What could
be good candidates here?)
All the dependency jars should be defined in here. Also you can define either in the MANIFEST.MF or standalone.xml.
For which jars do I leave them in web-inf/lib folder? (Application
uses certain specialized math libraries - like colt.jar, excel
graphing libraries like - jxls.jar, poi.jar - these seem like good
candidates here).
If there are any jars which is used only in your ear or war then those could be defined in WEB-INF/lib.
However, it is recommend to use as modules.

Related

java.lang.NoSuchMethodError: org.joda.time.DateTime.now()Lorg/joda/time/DateTime; on Webogic [duplicate]

I have a maven web app project, where I use JodaTime. JodaTime is not directly referenced in my maven project, but is a part of a transitive dependency. In other words, my web app war, has another project of mine as a direct dependency, and that jar contains JodaTime.
I am getting an error after executing these two lines. It compiles fine though.
DateTime firstDate = new DateTime();
firstDate = firstDate.withYear(2016);
And here is my error:
java.lang.NoSuchMethodError: org.joda.time.DateTime.withYear(I)Lorg/joda/time/DateTime;
I know that these kinds of errors can happen if I compile and run with different versions of a library, like this answer says, but the withYear() has been around since JodaTime 1.3, since 2006, and I can't see that I could ever have imported a version that old. I've even checked my final war-file, and the only JodaTime library present, is 2.9.2.
The two lines runs fine if I create a main-method snippet, and run it from within the same project in eclipse. They only fail upon compilation into a war file, and running from my weblogic 10.3.2 server.
Does anyone have any idea on how I can proceed to debug this one?
WebLogic 10.3.6 includes this on the classpath:
joda.time_1.2.1.0.jar
This is earlier than the 1.3 that has the missing method.
Your code compiles, which is a good indication that your app's classpath has at least Joda 1.3.
Thus I suspect this is a WebLogic classpath issue. When your app uses libraries that are also on the WebLogic classpath, you need to tell WebLogic which library to use. You do this with the prefer-application-packages element in src/main/webapp/WEB-INF/weblogic.xml.
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
http://xmlns.oracle.com/weblogic/weblogic-web-app/1.3/weblogic-web-app.xsd">
<context-root>myApp</context-root>
<container-descriptor>
<prefer-application-packages>
<package-name>org.joda.time.*</package-name>
<package-name>org.slf4j.*</package-name>
<package-name>org.slf4j.impl.*</package-name>
<package-name>org.slf4j.spi.*</package-name>
<!-- others here -->
</prefer-application-packages>
</container-descriptor>
<!-- rest of weblogic.xml here -->
</weblogic-web-app>
WebLogic has a classpath analysis tool called wls-cat to help locate these conflicts, described in this blog post. One caveat - do not just copy wls-cat's prefer-application-packages block into your webapp and think you're done - you need to resolve each conflict one by one. Sometimes that means excluding dependencies from your webapp or using scope provided.

Invalid ejb jar: it contains zero ejb.

I have 2 modules: ejb and war, and ear module, that contains them. Modules build successfully, but when I try to deploy ear to glassfish, I recieve this error:
glassfish3.1.2|javax.enterprise.system.tools.admin.org.glassfish.deployment.admin|_ThreadID=17;_ThreadName=Thread-2;|Exception while deploying the app [EarModule] : Invalid ejb jar [BackEnd-1.0-SNAPSHOT.jar]: it contains zero ejb.
Note:
1. A valid ejb jar requires at least one session, entity (1.x/2.x style), or message-driven bean.
2. EJB3+ entity beans (#Entity) are POJOs and please package them as library jar.
3. If the jar file contains valid EJBs which are annotated with EJB component level annotations (#Stateless, #Stateful, #MessageDriven, #Singleton), please check server.log to see whether the annotations were processed properly.|#]
I really don't know what to do, I've found a lot of questions like mine, but there was no solution.
I understood, what was wrong. The problem was in run configurations, I'm using Intellij Idea and in run configurations there was build and make before run of my ear module. I removed this and after maven install it deployed successfully.
You have to add an EJB into your WAR or EAR file. Just Create a new Class and annotate it with #Stateless
I know this is very build specific and it uses Netbeans instead of the OP's IDE but because I was lead here and this will likely be useful to some users:
I had the following build:
Netbeans Enterprise Application with Maven
Glassfish 4.1
Java EE 7
I had tried migrating from a previous non-maven enterprise application and the clone didn't quite work the way I expected, there was some old ejb jars lying around that I deleted.
I had done quite a few things to fix it:
Ensure theres no ejb jars lying around that shouldn't be there. Ensure that you don't have accidently have the ejb module jar included more than once as this can result in the same error too (Manually deploying the ear and deployment through netbeans sometimes gave me different errors).
I used the #Remote interface on my EJB applications. Now you should not be importing your EJB into your War, you should use the annotations correctly as described https://docs.oracle.com/javaee/7/tutorial/ejb-intro004.htm
(This is more of a note) When you update any of your war or ejb, clean and build them before cleaning and building your ear (sounds funny right?).
If you are using interfaces for your session beans then you should put them in a separate jar, make a new project maven > java application. Do the same thing with your persistence entities. Add these as dependencies to both your ejb and war project.
This doesn't relate to me in particular but you should have at least 1 #stateless (or I think #stateful) annotation in a java class inside your ejb module for it to run (for the module to be considered an ejb).
I likely had to do a few more things that I forgot but if you still run into issues comment below and I'll try to update.
Just try to build & install your project using Maven , and then , deploy it in glassfish ( do not run your project directly from your IDE )
I encountered this problem as well. It occurred when I had imported a new EJB project into my Eclipse workspace. The project didn't have a reference to the Glassfish libraries then, since it was not yet included in the EAR deployment assembly.
Upon saving the Bean file, the IDE automatically imported javax.inject.Singleton instead of javax.ejb.Singleton. This made the code compile without warnings, but throw the same error as in the original post.

Glassfish application not working with maven library (gf-client)

For a school assignment I received a Netbeans project using JNDI and JMS with Glassfish (3 open source edition). All the Glassfish libraries this application is using are referenced by absolute path and all the other libraries (in the "lib" folder) are referenced by relative path.
Since my group is working with a version control system the "lib" folder is included in the repository. This works fine because it is a small project. However the Glassfish libraries are problematic as I am a Linux user and the others are Windows users. We have worked around this problem by letting Netbeans take care of the library paths.
The chosen solution 'works' but is not the best solution. I thought Maven would be a better solution.
However the "gf-client" library is giving problems. Whenever I use the Maven "gf-client" the application throw an exception:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
Both libraries have "3.1.2" as version. The structures of the libraries look identical and both MANIFEST.MF files too. The size and the md5sum of both files however are not equal.
I've tried all "gf-client" libraries I could find in the default Maven repository and none worked. No other library gives me problems.
Was able to resolve it by adding this to my pom.xml:
<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1.2</version>
</dependency>
The gf-client jar is referring to classes in other jars. The first class it was missing was probably java.naming.factory.initial. But after fixing this it still needed a bunch of other classes. Quickest way for me was to add the glassfish-embedded-all dependency.

Glassfishv3 not adding jars in ear to the classpath

I have been working on this problem for one whole day but in vain without any effective solution.
I have an ear file packaged with an ejb and a handful of jar files (including hibernate and the other dependent jar files).The ejb is stateless and enabled as a web service.
The ear file has been packaged using maven and has the below structure
ear->projectrelatedejb.jar
->hibernate.jar
->otherdependent. jar
->META-INF/application.xml
->META-INF/manifest.mf
The application.xml and manifest file are automatically generated by maven when I do a package.
When I deploy this ear file on glassfish it gets deployed with the ejb methods being accessible using web services. However when accessing the application (using soapui),
the ejb methods that perform some database functionality using hibernate throw java.lang.NoClassDefFoundError for the hibernate api during runtime.
It is obvious from the error that the hibernate jars are not on the classpath during runtime but since the jars are within the ear Glassfish should have
added it to the application classpath.
I tried various options like adding the classpath entries to the manifest.mf during the package (by using the element addClasspath with the maven-ear-plugin) which didn't do any good.Also with Glassfish we cannot add the dependent jars as modules to the application.xml unless the jars are application client jars
(Glassfish wouldn't deploy the ear file if the application.xml has the dependent jars declared as modules).
I also tried placing the jars in the lib directory within the ear (which isn't actually required) and with the manifest Class-Path header referencing the jars in the lib directory which also didn't fix the problem.
The quick and dirty fix which I can do to get this working is to place the hibernate and the other the dependent jars in Glassfish's lib directory.However,this is a bad practice
and I am somewhat reluctant to do it.
I would really appreciate if someone can provide me with a working solution to this problem.I have gone through the net looking for this problem
but couldn't find any solution.
Wondering if its a bug with glassfish or does glassfish need something special to reference the jars in an ear.
Thanks in advance.
I found a similar problem which is discussed here: http://www.tricoder.net/blog/?p=59.
Simply put, try putting the libraries in EAR/lib directory and according to JEE5 spec, glassfish will add them to class path automatically.
I used Server Library option to deploy application JARs and it worked for me.
Right click on your EAR-> Properties -> Libraries-> Add Library -> Create -> give name and change type in Library Type to Server Libraries then add JARs that should be deployed and confirm.
I work with NetBeans 7.0.1 and GlassFish server 3.1
When you say you added classpath entries to manifest.mf, which manifest.mf do you refer to? The one in ear-root/META-INF/manifest.mf ? Try adding a META-INF/MANIFEST.MF to your ejb module with Class-Path entries!

Using Maven for Coldfusion project

I have to deal with what is pretty ugly and large blob of ColdFusion code which up to this day is maintained by direct modifications on production server (don't ask). I managed to clean it up from dupes and backups and put it into Subversion, now I need tp pick a make system to be able to put this onto continuous build (TeamCity) and also scheduled releases.
To my surprise I only found pretty much a single blog article on how to retrofit CF project with Maven, so the question is - does anyone have experience successfully using Maven on CF and what in general people use to manage large CF projects?
Your suggestions, tips and links will be much appreciated
Since I don't want to start religions wars - Maven is pretty much company standard (vs Ant)
First, here's another blog you might find helpful.
build-tools-maven-and-coldfusion
I haven't tried to build ColdFusion with Maven, but I have experience with managing Maven builds for a large company. There are a few things for you to consider.
Project structure
Coldfusion cfm and cfc files should be put in src/main/resources so they are bundled in the jar (the blog referenced above overrides the Maven convention to put them in src. this is ok, but could be a problem if you later need to add anything else to the project).
I'd probably keep cfc and cfm files in separate projects with appropriate dependency declarations to link them, this keeps your cfc projects as libraries and helps reuse. It is also worth considering the granularity of the cfc projects. Generally Maven's dependency management helps you keep artifacts small, with little need to worry about finding all the jars.
Deployment
The simplest way to deliver the artifacts is to use the maven-war-plugin to create a war containing your artifacts and all their transitive dependencies. This makes each application self-contained, which can be useful. The downside of this is that you'll end up bundling the same artifacts repeatedly and they can be quite large. To mitigate this you can either use the assembly-plugin to create custom packages excluding the common components, or you can specify that certain components (e.g. ColdSpring) are scope provided, this means they won't be included in the war.
Version Management
Maven encourages a proliferation of dependencies, by default each dependency declaration has a version, this can cause maintenance issues, particularly when you want to bump the version of an external dependency. You can mitigate this by defining a parent POM or an "app" POM. Either would have a dependencyManagement section declaring the details (groupId, artifactId, and version) for common artifacts. Any POM inheriting from the parent need not declare the dependency version as it will be inherited (note this doesn't mean that all children will have all dependencies, only that any that declare a dependency don't need to declare the version). If you define an "app" project with packaging "pom" and a dependencyManagement section, you can reference it with scope import (from Maven 2.0.9 onwards), this will import the dependencyManagement section from the "app" project to the project POM. See the dependency documentation for more details.
If you declare a dependency with a scope in the dependencyManagement section, that scope will be inherited unless it is overridden in the child POM. Related to the deployment section above, this means that you can declare the common libraries scope provided in the parent to ensure they are not bundled in each applciation.
Naming Conventions
You'll need a naming convention for the packages to avoid collisions.
It's probably best to follow the Maven convention and use java package-like groupIds (org.apache.maven for maven.apache.org) and the jar name for the artifact. This convention would give the groupId "org.coldspringframework" and artifactId "coldspring" for ColdSpring.
Further distinctions might need to be made across the company. For example, if you have a web and core team, you could give the web team the groupIds com.mycompany.web.* and the core team com.mycompany.core.*
Dependency Management
You'll need to add your CFC packages to a Maven repository such as Nexus so they are accessible to other builds across the enterprise.
If you want to keep the CFC packages separate to the jars. You can specify a custom packaging type, so that they won't be mixed up with any Java artifacts. If you create a custom packaging type, the artifacts can have the ".jar" extension, but any dependency declaration must have the type set.
Here's an example following those conventions:
<dependency>
<groupId>org.coldspringframework</groupId>
<artifactId>coldspring</artifactId>
<version>1.2</version>
<!--custom packaging type helps keep separate from Java artifacts-->
<type>cfc</type>
</dependency>
There's a section in the Nexus book that describes custom lifecycles (follow the links for more details. Essentially you need to create a plugin with a META-INf/plexus/components.xml to describe the plexus mechanics (what archiver to use, what extension to output etc).
The components.xml would look something like this:
<component-set>
<components>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>cfc</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<configuration>
<phases>
<process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
<package>com.hsbc.maven.plugins:maven-jar-plugin:jar</package>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
</phases>
</configuration>
</component>
<component>
<role>org.apache.maven.artifact.handler.ArtifactHandler</role>
<role-hint>cfc</role-hint>
<implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
<configuration>
<extension>jar</extension>
<type>cfc</type>
<packaging>cfc</packaging>
</configuration>
</component>
<component>
<role>org.codehaus.plexus.archiver.Archiver</role>
<role-hint>cfc</role-hint>
<implementation>org.codehaus.plexus.archiver.zip.ZipArchiver</implementation>
<instantiation-strategy>per-lookup</instantiation-strategy>
</component>
<component>
<role>org.codehaus.plexus.archiver.UnArchiver</role>
<role-hint>cfc</role-hint>
<implementation>org.codehaus.plexus.archiver.zip.ZipUnArchiver</implementation>
<instantiation-strategy>per-lookup</instantiation-strategy>
</component>
</components>
</component-set>
Maven looked interesting to me too, but I couldn't find enough resources, and didn't have enough time to figure it out, so I moved onto what seemed to be good as well.
I understand you prefer to use Maven, I have come across several articles regarding Ant and Coldfusion, as well as a recent one about Hudson with Coldfusion.
Coldfusion also has the cfant (undocumented) tag. You can run ANT scripts right from CF?