users@glassfish.java.net

Controlling a webservice client through JMX

From: Florian Poulin <florian.poulin_at_lotaris.com>
Date: Mon, 19 Oct 2009 06:55:12 -0700 (PDT)

Hello,


From a JMX client (written in Groovy) I'd like to "tell" a Webservice client
(deployed on Glassfish) to make calls to a Webservice (which is exposed in
another project on the same Glassfish). My goal is to use JMX to pilot
integration tests (trigger a webservice call from one side, then check if it
was processed correctly on the other side, and so on). The thing is, despite
spending a few days trying to make this simple use case work, it does not.
So please, Nabble geniuses, help me find the solution ;-)


Here is my setup, in summary :

The project containing the Webservice client and the one exposing the
Webservice are both deployed on Glassfish 2.1, and the JMX client is
executed in standalone (at the end of a Maven build).


In my project "client Webservice", in the EJB module, I have a session bean
which makes calls to the Webservice, something like :



---------------------------------------------------------------------
@Stateless
public class MySuperManagerBean implements MySuperManagerLocal {
 
   public String callWS(String arg) {
      return callWebService(arg);
   }
 
   private String callWebService (String arg) {
       // do a call to the web service and return the result
   }
}
---------------------------------------------------------------------


Notice that the Webservice client was first generated with JAX-WS out of the
project, and then imported into it. It was tested and works beautifully.


In this same project, in the WAR module I have my MBean (which is subscribed
to the Glassfish's MBean server when at a servlet initialization). My MBean
looks like that :



---------------------------------------------------------------------
public class MySuperMBeanImpl implements MySuperMBean {
 
   private MySuperManagerLocal msml;
 
   public MySuperMBeanImpl (MySuperManagerLocal msml) {
      this.msml = msml;
   }
 
   public String doCallWS(String arg) {
      return msml.callWS(arg);
   }
}
---------------------------------------------------------------------

And now here is where it becomes interesting :

My Groovy code retrieves a proxy on the MBean and invokes
doCallWS("loremipsum"). And BOOM, here is what I get :



---------------------------------------------------------------------
EJB5018 : Une exception a été renvoyée lors d'un appel ejb sur
[MySuperManagerBean].
javax.ejb.EJBException
        at
com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:3894)
        at
com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3794)
        at
com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3596)
        at
com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1379)
        at
com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1316)
        at
com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:205)
        at
com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:83)
        at $Proxy246.callWS(Unknown Source)
        at foo.bar.MySuperManagerBean.callWS(...)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at
com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:93)
        at
com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:27)
        at
com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:208)
        at
com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:120)
        at
com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:262)
        at javax.management.StandardMBean.invoke(StandardMBean.java:391)
        at
com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836)
        at
com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761)
        at
com.sun.enterprise.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:178)
        at
javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1426)
        at
javax.management.remote.rmi.RMIConnectionImpl.access$200(RMIConnectionImpl.java:72)
        at
javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1264)
        at
javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1359)
        at
javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:788)
        at sun.reflect.GeneratedMethodAccessor723.invoke(Unknown Source)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at
sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
        at sun.rmi.transport.Transport$1.run(Transport.java:159)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
        at
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
        at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
        at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:637)
Caused by: com.sun.xml.ws.model.RuntimeModelerException: Erreur du modeleur
d'exécution : La classe de wrapper foo.bar.services.ws.MySuperWrapper est
introuvable. Avez-vous exécuté APT pour la générer ?
        at
com.sun.xml.ws.model.RuntimeModeler.getClass(RuntimeModeler.java:287)
        at
com.sun.xml.ws.model.RuntimeModeler.processDocWrappedMethod(RuntimeModeler.java:596)
        at
com.sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:543)
        at
com.sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:371)
        at
com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:258)
        at
com.sun.xml.ws.client.WSServiceDelegate.addSEI(WSServiceDelegate.java:633)
        at
com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:328)
        at
com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:311)
        at
com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:304)
        at javax.xml.ws.Service.getPort(Service.java:92)
        at foo.bar.services.ws.ServicePortGetter.getServicePort(...)
        at foo.bar.MySuperManagerBean.callWebService(...)
        at foo.bar.MySuperManagerBean.callWS(...)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at
com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011)
        at
com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:175)
        at
com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2920)
        at
com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4011)
        at
com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:197)
        ... 34 more
---------------------------------------------------------------------

(sorry for the french parts, as my Glassfish is configured in my mother
language)


The unknown class is the Wrapper class of my Webservice client generated by
JAX-WS (used to encapsulate the effective parameters of my Webservice call,
and for XML serialzation, I guess). This class does of course exist. The
line which actually causes problem references this class in an annotation
(as a Stringfully qualified name, which implies a class lookup, which does
not work).


And now here is where it becomes silly :

If I define a method on my Session Bean which only returns a String without
dealing with any Webservice (ex: return "HelloWorld";), my Groovy client is
very happy with it, and so is Glassfish. The problem occurs when the content
of my Session Bean method invokes a Webservice method .... looks strange to
me !


Conclusion : Let's say I have two methods in my SessionBean. Both take a
String argument, and return a String. I have a MBean which exposes these two
methods through JMX. The first passes, the second crashes. Why ? Because
internally, inside its Glassfish container, it makes a call to a WebService
(which works perfectly if it is tested inside the container). It looks like
JMX is dependant on how managed beans are implemented ...


Does anyone have a clue why this is happening ? It looks like Classloading
issues (JMS server and Glassfish deployed applications not sharing the same
classloader ?). But if it is, how can it be fixed ?


Thank you for help.

Florian

-- 
View this message in context: http://www.nabble.com/Controlling-a-webservice-client-through-JMX-tp25958655p25958655.html
Sent from the java.net - glassfish users mailing list archive at Nabble.com.