Bugs item #845157, was opened at 2003-11-19 15:38
Message generated for change (Comment added) made by dobytek
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=376685&aid=845157&group_id=22866
Category: JBossServer
Group: v3.2
Status: Open
Resolution: None
Priority: 7
Submitted By: Kevin Gilpin (kgilpin)
Assigned to: Nobody/Anonymous (nobody)
Summary: ClassCastException with PortableRemoteObject.narrow using jb
Initial Comment:
I have 2 EJB applications which are each deployed with
a jboss-app.xml file so that they will have separate
classloader hierarchies. The reason for this is that
the two applications share some common JAR files such
as some base utilities, Hibernate beans, and 3rd party
ones such as struts.
Both applications have an EJB session bean which
implements the same home and session interfaces. These
beans register themselves in JNDI, and a common UI
finds them in a generic manner and exposes a UI for
invoking them (the session interface is IScriptRemote).
The problem occurs when the first application looks up
the IScriptRemote from the second application in the
following code. A ClassCastException occurs on the last
line you see here. Before I created the jboss-app.xml
files, no exception occurred (but I had other problems
with LinkerErrors).
InitialContext ic = J2EEUtil.getInitialContext(port,
principal, credentials);
try {
NamingEnumeration e = ic.listBindings(JNDI_SCRIPT_ROOT);
while ( e.hasMoreElements() ) {
Binding binding = (Binding)e.next();
Object obj = binding.getObject();
LOG.debug("Got object ", obj, " from binding ", binding);
try {
if ( obj instanceof EJBHome ) {
IScriptRemoteHome home =
(IScriptRemoteHome)PortableRemoteObject.narrow(obj,
IScriptRemoteHome.class);
The reported exception is:
15:24:30,609 WARN [Repository] Exception processing
binding ReloadMetadataScriptHome:
$Proxy44:ikp/script/ReloadMetadataScriptHomeHome
java.lang.ClassCastException
at
com.sun.corba.se.internal.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:293)
at
javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:134)
at com.ipi.script.Repository.findAll(Repository.java:102)
----------------------------------------------------------------------
Comment By: Paul Anderson (dobytek)
Date: 2004-01-12 00:03
Message:
Logged In: YES
user_id=948886
I have a similar scenario - multiple EAR files, configured
with their own class repositories in jboss-app.xml, to avoid
conflicts with library jars.
I also have separate WAR files that I'd like to keep outside
EARs. These have the home and remote interfaces in
WEB-INF/lib. I was using JBoss 3.2.1.
When calling an EJB from a webapp I kept getting
ClassCastExceptions, either with a straight cast or
PortableRemoteObject.narrow of the home interface stub
returned by JNDI. Removing the interfaces from WEB-INF/lib
just caused ClassNotFoundException.
This did not happen when the EARs used the global
repository, but then of course there were library problems..
I checked the ClassLoaders that loaded the stub home
interface and the version in my servlet code. The stub and
its home interface were loaded by a JBoss
UnifiedClassLoader, the servlet version of the home
interface by a Tomcat classloader. Configuring servlet
2.3/Java 2 classloading behaviour or a JBoss
UnifiedClassLoader for WEB-INF/lib didn't change much, as
the EAR dedicated UnifiedClassLoader version of the class
was not accessible anyway.
Upgrading to 3.2.3 made no difference.
This JNDI behaviour for the proxy made no sense for RMI so I
assumed in-VM optimisation was happening for JNDI and the
invocation.
I specifically configured use of jrmp for the EJB with
bean-invoker and home-invoker in the JBoss-specific EJB
deployment descriptor. No effect - presumably automatic
optimisation to 'local' was happening.
I then configured JNDI in conf to force RMI
(jndi.properties, java.naming.provider.url=localhost). This
meant that the stub classes were loaded by the same
classloader as my servlet lib and the ClassCastException
stopped.
However, now there was an InvocationException when invoking
the EJB's create method on the home interface - "check
deployment packaging".
I guessed that because in-VM optimisation required
additional access to the bean implementation class, this
class (and therefore the method) couldn't be loaded by the
webapp. (I put only the EJB interfaces in the webapp).
In the stack trace I could see the local invoker being used,
not jrmp.
Trying to disable the optimisation, I put
container-invoker-conf|Optimized as false into
standardjboss.xml (could have put into jboss.xml) for
stateless session beans. This seemed to be ignored - the
local invoker was still used and the stub was still returned
by reference from JNDI.
I had found many references to this option on the Internet,
so I guessed it had been dropped in recent JBoss versions.
The element had gone from the jboss_3_2.dtd compared with
jboss_3_0.dtd.
So I guessed that a cleaner way had been implemented to
choose the strategy the client invoker would use to find a
transport for the call.
Checking the JBoss source code, I found the jrmp invoker
only knows RMI, and that the invoker interceptor
automatically optimises by choosing the local invoker
instead of the jrmp invoker.
Fortunately a non-optimising invoker interceptor is
available - org.jboss.invocation.ByValueInvokerInterceptor.
This can be put in the interceptor chain for a bean's proxy
by changing standardjboss.xml or jboss.xml:
jboss|invoker-proxy-bindings|invoker-proxy-binding(name=stateless-rmi-invoker)|proxy-factory-config|client-interceptors|home/bean|interceptor
org.jboss.invocation.interceptor becomes
org.jboss.invocation.ByValueInvokerInterceptor
Hope this helps. I still have to find something that uses
RMI for JNDI only here where needed and not globally.
Seems like some documentation is needed, and that JBoss
needs to detect deployment arrangements where an optimised
call is not possible instead of requiring arcane configuration.
----------------------------------------------------------------------
Comment By: Kevin Gilpin (kgilpin)
Date: 2003-12-12 14:40
Message:
Logged In: YES
user_id=44882
Thanks for taking a look at this. Your suggestion does not quite
address the problem, because while there are two EJBs, they
already have different JNDI names. Let me further describe the
situation.
Script.ear contains EJB session and home interfaces, plus an EJB
called TestBean that implements IScriptRemote
IScriptRemoteHome
IScriptRemote
TestBean(IScriptRemote)
Search.ear contains an EJB called ReloadMetadataBean that
implements IScriptRemote. It also contains the EJB interfaces:
IScriptRemoteHome
IScriptRemote
ReloadMetadataBean(IScriptRemote)
TestBean and ReloadMetadataBean are bound to different JNDI
names.
Some code in the Script.ear application attempts to access the
ReloadMetadataBean. When it does so, the ClassCastException
occurs. My educated guess as to why this is happening is that
the Script application is trying to cast the
ReloadMetadataBeanHome to its instance of the
IScriptRemoteHome interface Class, but the object it gets from
JNDI actually implements the IScriptRemoteHome interface that
is loaded by the Search application. This interface is improperly
being handed across EJB applications.
I think that JBoss is trying to optimize the RMI call by handing
the ReloadMetadataBeanHome directly to the Script application,
but this causes the ClassCastException because both applications
have loaded the IScriptRemoteHome interface Class.
I would think that the solution to this problem would involve
something like creating a proxy around ReloadMetadataBean that
implements the right instance of the IScriptRemoteHome
interface (which is probably basically what the non-optimized RMI
implementation would do).
----------------------------------------------------------------------
Comment By: Dario Oliveros (doliveros)
Date: 2003-12-12 13:38
Message:
Logged In: YES
user_id=927266
Hi Kevin,
Try to give different JNDI names to the EJB beans that are
common to both EARs by editing the jboss.xml (use the ant
task to replace the jndi-name at compile time). In that way,
you should be able to do a lookup without a problem.
Let me know if it works.
D�rio
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=376685&aid=845157&group_id=22866
-------------------------------------------------------
This SF.net email is sponsored by: Perforce Software.
Perforce is the Fast Software Configuration Management System offering
advanced branching capabilities and atomic changes on 50+ platforms.
Free Eval! http://www.perforce.com/perforce/loadprog.html
_______________________________________________
JBoss-Development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development