Solved

JBoss : Deployment options of shared code

Posted on 2003-11-19
11
944 Views
Last Modified: 2007-12-19
We have a set of common libraries (utilities classes, Hibernate beans) that are used by multiple different J2EE applications. With Weblogic, each application is an EAR file that contains all of its JARs, plus a manifest in the EJB JAR. This works quite nicely. Each application is independent from the rest, which means that we can apply patches to individual applications on our production server, we can hot deploy the entire application, etc.

In JBoss, the default classloader architecture seems to encourage putting all the shared stuff in the [server]/lib folder. However, if I understand correctly, this code will not be hot-deployable, which really defeats the purpose of using a container in my mind (the whole reason I am learning JBoss is because I am fed up with Weblogic's unreliability while hot-deploying).

So, I tried building my EARs with a jboss-app.xml which creates a separate classloading context for each application. I was happy and thought this was working nicely, until I tried an application which looks up Home interfaces from the global JNDI namespace. What happened then is that the objects in JNDI were implementing separately loaded instances of the RemoteHome and RemoteSession interfaces, so PortableRemoteObject.narrow threw ClassCastException. I attempted to work around this problem by trying to figure out how to make JBoss use a non-JNP connection to JNDI, but I don't see a way to do this other than the HTTP invoker. Using the HTTP invoker inside the container is a big hack, but I decided to try it anyway; unfortunately this approach also failed (stack trace below).

So now I am 100% stuck. I can't deploy everything in [server]/lib, because then it won't hot deploy (right?). I also can't deploy everything in their own classloaders, because then I can't use remote Session beans through JNDI.

Surely people do stuff like this all the time. What is the right answer for my deployment situation? I have learned a lot about JBoss, and that is good. But I am ready for it all to start working now.

All this code is currently in production on a Weblogic server, so whatever my problems are they are JBoss-specific.

- kevin

Attempt to use HTTP JNDI provider:

12:41:44,986 WARN [HttpNamingContextFactory] Invalid reply content seen: class
org.jboss.invocation.InvocationException
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream
.java:2165)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputS
tream.java:2634)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:734
)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:253)
at org.jboss.invocation.http.servlet.InvokerServlet.processRequest(Invok
erServlet.java:117)
0
Comment
Question by:kgilpin
  • 5
  • 4
11 Comments
 
LVL 9

Expert Comment

by:vzilka
ID: 9782892
Since each class is loaded in its own EAR, are you sure you have the same version of the remote interface and home interface in the EAR file of the calling EJB and the component itself?
Did you try to remove the jboss-application.xml and see what happens?
0
 

Author Comment

by:kgilpin
ID: 9783674
Each app definitely has the same version of the class, because both EARs package the same JAR file (Base.jar).

If I remove the jboss-app.xml, then this part of the application works. But I get LinkerErrors (in Struts) when I hot deploy. Even if I didn't get LinkerErrors, I still would want to use the jboss-app.xml, because it is important to me to be able to independently replace the JAR files in the different applications. If I want to fix a bug in one application, I don't want to have to verify that all the other applications will work with the patched code.

I believe my problem could be reproduced in a simple manner. First, write a remote Home and Session interface. Package these interfaces into Base.jar. Then, write an EJB 'A' which implements these interfaces, and package it into A-ejb.jar. Then put both Base.jar and A-ejb.jar in an EAR file, along with a Class-Path in the manifest of A-ejb.jar that references Base.jar, and a jboss-app.xml. Next, write another EJB or web application that also packages Base.jar and also has a jboss-app.xml. This application should look up A using its global JNDI name and try to PortableRemoteObject.narrow it to the Home interface. This will fail with ClassCastException in JBoss; works fine in Weblogic 7.

Removing the jboss-app.xmls will enable application B to use bean A, but it will prevent A and B from being hot-deployable if something in Base.jar changes.
0
 
LVL 9

Expert Comment

by:vzilka
ID: 9788189
Can you put a log command that will detail the type of class you are getting? Try to remove the narrow command, and maybe do something like this:

Object o = ic.lookup("...");
System.out.println(o.getClass().getName());
System.out.flush();

The way I see it, either you ahve a faulty versioning of the class file (maybe the classpath is not configured correctly, and you are actually getting a class from someplace else - either the EJB returns something weird or your code classpath is broken) or that JBoss is trying to move the object in memory (since both files are deployed on the same server), doesn't notice that the classloader that loaded the classes is different, and then JBoss breaks.

I guess you are using JBoss 3.2.2, as this is a relatively new feature.
0
 

Author Comment

by:kgilpin
ID: 9788304
I have put in such a log command. Specifically, what I did was print out

  o.getClass()
and
  Arrays.asList( o.getClass().getInterfaces() )

The o.getClass() is a Proxy class which doesn't tell you much about what it really is. The getInterfaces() prints out the remote Session interface that I expect the object to implement.

I am quite sure that the problem is that JBoss is assuming that it can, as you say, move the object in memory, not realizing that the client and the bound object implement 2 instances of the same interface, loaded in different ClassLoaders.
0
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 

Author Comment

by:kgilpin
ID: 9788357
I have submitted a bug report to JBoss:

http://sourceforge.net/tracker/index.php?func=detail&aid=845157&group_id=22866&atid=376685

I will award the points for a workaround which solves the ClassCastException problem, or some demonstration that what I am seeing is not a JBoss bug. It would also be great to see someone reproduce this problem so I know that I am not misinterpreting what I am seeing.
0
 
LVL 9

Expert Comment

by:vzilka
ID: 9790513
Since this is a new feature in JBOss class loading mechanism, and some guys from my company run into similar (but not the same) issues, I guess that the best thing to do is not to use the different class loaders in JBoss, but use a single one for all EAR files.
If you have issues with that, put the shared files inside the lib directory. they shouldn't change much anyway.
IDEA - how about putting the JAR file externally, encapsulate all needed business logic using EJBs, and then deploy just this JAR file?
This way, all EAR files can use this EJB, it is hot deployed, deployed only once.
0
 
LVL 9

Expert Comment

by:vzilka
ID: 9816542
kgilpin, was this helpful?
0
 

Author Comment

by:kgilpin
ID: 9817206
Well, I need to be able to hot deploy everything. The problem with sharing a JAR file across EARs is that if I change something in that JAR file, I may potentially break every application. So I have to test every application before I deploy the change. If each application has its own copy of the shared JAR, I only need to test the one application that I am re-deploying.

I guess I didn't quite catch the meaning of your idea. Do you mean that the shared code would all be in an EAR file, and each application would access the shared code in this EAR file? Or will JBoss deploy a JAR file for me and allow me to hot-deploy that JAR? If the shared code is in an EAR, do I have to access all its functionality through EJB interfaces, or can I simply import classes from it and know that they will be available in the classpath? How are the other applications affected when the shared EAR/JAR is re-loaded? They will still have references to the old classes. Thanks for the follow-up.
0
 
LVL 9

Accepted Solution

by:
vzilka earned 500 total points
ID: 9817917
My idea is to deploy the common EJB as a single JAR file. This will imply of course that you need to check all the applications with the new JAR file.
As for the classpath thing - EAR files deployed in JBoss are not using other EAR files as their classpath.

This problem is so much DLL-hell that it gives me the creeps ;-)
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
removing tomcat 6 completely. 1 1,068
SCCM 2007 update Procedure 4 71
Fisheye tool 2 101
mysql: show engine innodb status 8 147
Convert websphere application server default chained Certificates from 1024 to 2048 keysize or higher size and also you can change signatureAlgorithm . Please make sure Websphere Application Server fixpack 7.0.0.23 or Above. The following steps a…
Meet the world's only “Transparent Cloud™” from Superb Internet Corporation. Now, you can experience firsthand a cloud platform that consistently outperforms Amazon Web Services (AWS), IBM’s Softlayer, and Microsoft’s Azure when it comes to CPU and …
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now