NoClassDefFoundException in N-tier application - java

I am building a project for a class that I am taking, and it consists of 4 modules
-impl (business logic/dao access)
-ejb (encapsulates business logic and provides access to it via a remote interface)
-war (web tier)
-ear (contains the war and ejb modules)
One utility class that I have inside the impl is able to populate an H2 database. It does this by running an ingestor that reads in an processes an xml file that resides in a maven repository, using various dao classes/methods to ingest the data:
String fileName = "xml/proj-data.xml";
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
When I run the ingestor through a unit test, it runs fine, but when I have everything layered, I get the NoClassDefFoundException on xml/proj-data.xml
So the basic outline that I have is:
-the war has dependencies on the impl and ejb modules
-the ejb has dependency on the impl module
-the ear has dependency on the impl, ejb, and war
This is a maven project. When I deploy the EAR to the server, the start page for the war is displayed (as I expect).
-The html page has a button that when pressed, does a post to a servlet
-The servlet has an ejb injected into it that it calls (via its remote interface).
-The ejb method makes a call back to the populate method in the impl, and thats when the exception happens, and I get a webpage back showing the exception.
Do I need to declare that repository in the WAR pom file as well?

In typing the question, I think I know what the problem may be. The repository that the xml file resides in is declared in the root pom for the project(the impl parent), NOT the pom for the impl module. Since the impl is the module that gets packaged with the EAR, I may need to declare the repository in the impl pom file as well.

Related

stateless ejb in WAR > package to EAR > local ejb call

I have an ear which contains 2 war files and each war contains stateless ejb and jersey rest classes. The interfaces locate in commons.jar file. The EAR structure looks like this:
EAR
-- /lib/commons.jar
-- rest-1.war
-- stateless-ejb-1.java
-- jersey-rest-1.java
-- rest-2.war
-- stateless-ejb-2.java
-- jersey-rest-2.java
I am trying to use stateless-ejb-1 from stateless-ejb-2 with #Inject annotation but I get a CDI deployment failure:WELD-001408: Unsatisfied dependencies error during deployment time. When I use #EJB in stateless-ejb-2 then the ear is deployed but I get a remote lookup error while calling jersey-rest-2.
This are my method call chains:
jersey-rest-1 > stateless-ejb-1: works fine
jersey-rest-2 > stateless-ejb-2 > stateless-ejb-1: I get an ejb-1 lookup error
I do not want to use remote ejb call because everything is packaged in the same ear (I would like to use #Inject instead of #EJB) but it does not work.
I guess that if I pack stateless-ejb-1.java to a jar and put it under EJB/lib than it will work. But I do not want to create a new module in my project just to pack this one file to separated jar file.
What is the solution?
You need to move stateless-ejb-1 into an ejb-jar module in the EAR.
Classes in different WAR files are never visible to each other, even when built into an EAR file.

Glassfish 3 EJB Injection from the jar archive fails

I have a strange problem with EJB injection in the glassfish 3. Maybe I just not completely understand what I do :)
So this is a problem: My project consists of 2 modules that will be assembled with gradle.
Module A
Module B
Module A is a usual glassfish module that also works fine. Module B contains general purpose staff. Module B is also a dependency of A. Module A will be deployed to glassfish as a *.war archive and Module B is in the appropriate lib folder as *.jar archive:
module-a.war and somewere inside of it ../lib/module-b.jar
What I want is: Create in the Module B a "general purpose" stateless bean and use it in the Module A. But it doesn't work...
In the Module B I created a bean:
#Stateless
public class GeneralPurposeBean {}
and I try to use it in the Module A as follows:
...
#EJB
private GeneralPurposeBean genPurpBean;
...
So how I already mentioned the GeneralPurposeBean is in the *.jar
Each time when I try to use the bean it fails with following exception:
javax.ejb.CreateException: Could not create stateless EJB
When I move the bean to the Module A it works fine but I want share this bean with other modules, that will be developed in the future. Can someone explain to me what is wrong here? So the bean will be recognized but it can't be created. What I found out through debugging is that
JCDIServiceImpl#_createJCDIInjectionContext
Doesn't recognize the bean as an enterprise bean. So everything in the *.war that directly accessible will be properly created but not what lies in the *.jar's.
For the case someone has the same problem:
If you treat one of your modules as a dependency and this module contains EJB beans you want be injected the solution for my problem was to put /META-INF/beans.xml file into the module. Otherwise container doesn't recognize the beans as EJB.
That's it.

Referencing an external class from a Jersey REST web app

I am trying a simple example of creating a RESTful API. I used the Maven jersey-quickstart-webapp archtype to create a Jersey web app. In a separate project I created a simple class: SimpleClass, which only has one method that returns "hello". I am trying to create an instance of that class in my method in the web app (I am using the default MyResource class) and call its method to get "Hello". I exported the project with the SimpleClass to a JAR file, and added that file to the build path for my Jersey project, and imported the relevant package.
When I run the web app on a local server, and call the MyResource method, I get an error with the root cause (just the top few rows):
java.lang.NoClassDefFoundError: Lorg/test/simple/SimpleClass;
java.lang.Class.getDeclaredFields0(Native Method)
java.lang.Class.privateGetDeclaredFields(Class.java:2583)
java.lang.Class.getDeclaredFields(Class.java:1916)
So, it can't find the SimpleClass class.
What am I doing wrong here? I'd really appreciate any help!
Thanks,
Yariv.
New info: I tried to create a RESTful web service without Maven. I successfully created the project with a simple "Hello World" example, and then I tried to add my own class from another project: I imported the .jar, added it to the build path, and created a class in the web service that creates an instance of my class when a GET is made to the server. My class happens to include (as members) instances of other classes, one of which connects to a MongoDB database, and when I run the service, I again get a HTTP 500 error as follows:
A MultiException has 2 exceptions. They are:
1. java.lang.NoClassDefFoundError: com/mongodb/DBObject
2. java.lang.IllegalStateException: Unable to perform operation: create on org.notes.server.NotesServer
Adding the MongoDB jar to the web project did not help. I must be missing something big here. What should I do to call code I created in another project (with a set of dependencies there) in my web service?
I'll appreciate any help I can get, I am getting nowhere with this...
I was able to resolve all these issues by adding all the relevant JARs to the deployment assembly (right-click on the project, click Properties, then select Deployment Assembly and add all the JARs that my class depends on, as well as its own JAR).
Thanks for your help, radai!

Package JBoss AOP interceptors with business dependencies as a standalone application

Here is my needs :
I have a WebService application running on a JBoss 5.1 (with a jboss-classloading configuration export-all=NON_EMPTY and import-all=true).
I want to add some interceptors on it but I can't change the legacy WS WAR.
What is my problems :
I managed to get working a simple interceptor packaged in a JAR that basically log every calls on legacy WebService.
But to achieve my goal, I need to use JAR dependencies like XML parsers, business objects, etc...
How can I package my AOP interceptors and its dependencies in one file ?
What I've tried :
In a WAR package, I have to use a similar jboss-classloading strategy to avoid conflicts, but in this context, I can't intercept anything else than classes in the WAR itself, so I can't intercept legacy WS calls.
PS : I have made all the basics to get JBoss AOP working properly :
pluggable-instrument.jar in bin folder
run.conf with -javaagent:pluggable-instrumentor.jar
aop.xml with loadTimeWeaving enabled and include package defined
jboss-aop.xml with valid pointcuts configurations (which I want in my package)
For now I found a solution by building a SAR package (JBoss Service Archive).
The SAR file look like this :
aop-interceptors.sar
META-INF/jboss-service.xml
aop-interceptors.jar
META-INF/jboss-aop.xml
com.mypackage.aop.interceptors...
com.mypackage.aop.handlers...
com.mypackage.aop.business.logic...
xml-parsers.jar
business-objects.jar
...
The SAR file is deployed in folder : jboss-5.1/server/default/deployers/jboss-aop-jboss5.deployer/
I don't know what SAR package is supposed to do ... is there a better way to do it ?

Classloader problem with EJB

I'm working on a project which includes persistence library (JPA 1.2), EJB 3 and Web presentation layer (JSF). I develop application using Eclipse and application is published on Websphere Application Server Community Edition (Geronimo 2.1.4) through eclipse plugin (but the same thing happens if I publish manually). When publishing to server I get the following error:
java.lang.NoClassDefFoundError: Could not fully load class: manager.administration.vehicles.VehicleTypeAdminBean
due to:manager/vehicles/VehicleType
in classLoader:
org.apache.geronimo.kernel.classloader.TemporaryClassLoader#18878c7
at org.apache.xbean.finder.ClassFinder.(ClassFinder.java:177)
at org.apache.xbean.finder.ClassFinder.(ClassFinder.java:146)...
In web.xml I have reference to EJB:
<ejb-local-ref>
<ejb-ref-name>ejb/VehicleTypeAdmin</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>manager.administration.vehicles.VehicleTypeAdmin</local>
<ejb-link>VehicleTypeAdminBean</ejb-link>
</ejb-local-ref>
EJB project has a reference to persistence project, and Web project has references to both projects. I don't get any compilation errors, so I suppose classes and references are correct.
I don't know if it is app server problem, but I ran previously application on the same server using same configuration parameters.
Does anybody have a clue what might be the problem?
Looks almost like it couldn't find the class manager.vehicles.VehicleType when it was attempting to create/load the class manager.administration.vehicles.VehicleTypeAdminBean.
I've encountered similar problems before. When the class loader attempts to load the class it looks at the import statements (and other class usage declarations) and then attempts to load those classes and so on until it reaches the bottom of the chain (ie java.lang.Object). If it cannot find one class along the chain (in your case it looks like it cannot load VehicleType) then it will state that it cannot load the class at the top of the chain (in your case VehicleTypeAdminBean).
Is the VehicleType class in a different jar? If you have a web module and and EJB module do you have the jar containing the VehicleType class in the appropriate place(s). Sometimes with web projects you have to put the jars in the WebContent/WEB-INF/lib folder or it won't find them.
Are both of these projects deployed separately (ie. two ears? or one ear and one war?) or are they together (ie, one ear with jars and a war inside?). I'm assuming the second given you declared your EJB local?
The jars that you are dependent on also have to be declared in your MANIFEST.MF files in the projects that use it.
I'm kind of running on guesses since I do not know your project structure. Showing that would help quite a bit. But I'd still check on where VehicleType is located with regards to your EJB class. You might find it isn't where you think it is come packaging or runtime.
Thanks #Chris for WebContent/WEB-INF/lib idea ! it works for me by following these steps :
1- Export my EJBs to a JAR (MyEJBs.jar)
2- I created another jar with your_installation_path/IBM/SDP/runtimes/your_version/binCreateEJBStrub.bat via CMD.exe, by executing this command :
createEJBStubs.bat <my_path>/MyEJBs.jar -newfile –quiet
3- A new jar will be automatically created in the same directory as MyEJBs.jar named MyEJBs_withStubs.jar
4- Put your new jar in WebContent/WEB-INF/lib
5- Call your EJBs by :
MyEJBRemote eJBRemote;
InitialContext ic = new InitialContext();
obj = ic.lookup("your_ejb_name_jndi");
eJBRemote = (MyEJBRemote ) PortableRemoteObject.narrow(obj,
MyEJBRemote.class);
eJBRemote = (MyEJBRemote ) obj;
Now you can call your EJBs from another EAR

Categories

Resources