1 2 Previous Next 16 Replies Latest reply on Feb 17, 2003 11:02 AM by jcasp

    mbean -> job trigger -> session bean

    garyg

      I've got a question w/ an implentation which I'm not sure is possible ... having mbeans trigger job classes and then call session beans.

      I've got a custom mbean implemented as my scheduler from which I'm using the quartz API. I have a session bean that submits a schedule to my Scheduler (the MBean) and triggers job classes (which are extended from Object w/ several interfaces). When this job class is run, it's supposed to call another session bean ... which is the problem. My job class is called as scheduled, but I can't get it to call a session bean.

      session bean (invokes) -> mbean (triggers) -> job class (calls) -> session bean

      Anyone have ideas on how this is supposed to work, or could work?

      Any help much appreciated.

        • 1. Re: mbean -> job trigger -> session bean

          >My job class is called as scheduled, but I can't get it >to call a session bean.

          Why not? What error do you see?
          It is not very easy to help you with "It doesn't work".

          Is the session bean secured? You will need to do
          a login. See some earlier threads in this forum.

          Regards,
          Adrian

          • 2. Re: mbean -> job trigger -> session bean
            garyg

            Yeah, I didn't give any details because I was actually wondering if even what I was doing was do-able. Reason being, I couldn't find a way to tie the mbean to the job class that actually did the call to the session bean. In other words, in *-ejb.jar I added in dependencies for beans that depend on other beans. I did nothing of the sort for the mbean. All I did for the mbean was add it's service deployment descriptor file (*-service.xml). Am I supposed to add in the session bean somewhere's in here as a dependency?

            The error I'm seeing is a NamingException ...
            'env not bound'.

            Before when I had these errors I just make adjustments to my deployment descriptors to fix this. But since this is my first mbean ... havn't found it for the above reasons.

            What do you mean "is the session bean secured"? I searched the forums and found hints about making jmx secure from a security standpoint, but no, I'm not securing anything. Security is something I havn't really gotten into yet.

            And why would I need to do a login? None of my other controllers do logins to run session beans. Just a normal lookup and method call.

            Thanks for responding.

            • 3. Re: mbean -> job trigger -> session bean

              Ignore the security if it is not configured,
              you'll understand the login when you try it.

              You are doing a lookup somewhere, probably on
              java:comp/env/... that fails.

              Where? This namespace is configured for each ejb
              by the deployment descriptors, there is no
              equivalent for MBeans.

              Exception stacktraces and code snippets are very
              useful when reporting problems.

              Regards,
              Adrian

              • 4. Re: mbean -> job trigger -> session bean

                If you are trying to use it from an MBean,
                lookup the global jndi name of the ejb.

                If you have problems with dependencies,
                use a {EJB's jmx ObjectName}
                in the MBean descriptor to ensure the MBean does
                not start until after the EJB is deployed.

                You can find the JMX ObjectName of the ejb using
                http://localhost:8080/jmx-console
                It will be something like
                jboss.j2ee:service=ejb,jndi-name=whatever

                Regards,
                Adrian

                • 5. Re: mbean -> job trigger -> session bean
                  garyg

                  No, I'm not trying to it from an mbean, but from a job that's triggered from an mbean ... which means it's being exec'd from a class extended from Object w/ a few interfaces.

                  Threre are no problems from dependencies that I have seen or am aware of. Below is the stack trace.

                  20:22:17,259 ERROR [STDERR] javax.naming.NameNotFoundException: env not bound
                  20:22:17,259 ERROR [STDERR] at org.jnp.server.NamingServer.getBinding(NamingServer.java:495)
                  20:22:17,260 ERROR [STDERR] at org.jnp.server.NamingServer.getBinding(NamingServer.java:503)
                  20:22:17,261 ERROR [STDERR] at org.jnp.server.NamingServer.getObject(NamingServer.java:509)
                  20:22:17,262 ERROR [STDERR] at org.jnp.server.NamingServer.lookup(NamingServer.java:253)
                  20:22:17,262 ERROR [STDERR] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:456)
                  20:22:17,263 ERROR [STDERR] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:569)
                  20:22:17,264 ERROR [STDERR] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:440)
                  20:22:17,265 ERROR [STDERR] at javax.naming.InitialContext.lookup(InitialContext.java:345)
                  20:22:17,265 ERROR [STDERR] at com.neuroquest.cais.objects.BuildObj.execute(Unknown Source)
                  20:22:17,266 ERROR [STDERR] at org.quartz.core.JobRunShell.run(JobRunShell.java:160)
                  20:22:17,267 ERROR [STDERR] at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:268)

                  ---

                  So the calls work like ...

                  session bean (invokes) -> mbean (triggers) -> job class (calls) -> session bean

                  ... except the "job class (calls) -> session bean" is not successful, that's where I get the stack trace above. Below is the Job classes method that throws the naming exception.

                  --- Job class snip

                  ...
                  public void execute(JobExecutionContext context)
                  throws JobExecutionException {

                  try {
                  Context ctx = new InitialContext();

                  Object result = ctx.lookup("java:comp/env/ejb/InitializeField");

                  InitFieldHome home = (InitFieldHome)
                  javax.rmi.PortableRemoteObject.narrow(result, InitFieldHome.class);

                  InitField initField = (InitField) home.create();

                  initField.publishField(this);
                  ...

                  ---

                  The jmx-console shows ...

                  EJBModule=acaiis-ejb.jar,J2EEApplication=acaiis_mgr-0.30b.ear,J2EEServer=Single,j2eeType=StatefulSessionBean,name=ejb/InitializeField

                  This very same code works in servlets making calls to session beans. Any help much appreciated.

                  • 6. Re: mbean -> job trigger -> session bean

                    Servlets and ejbs have a java:comp/env namespace
                    configured at deployment.

                    Anything else does not, you have to use global
                    jndi name of the bean.

                    ejb/InitializeField

                    The MBean you mention is the JSR77 one,
                    look in domain, jboss.j2ee for the real EJB

                    Regards,
                    Adrian

                    • 7. Re: mbean -> job trigger -> session bean
                      jcasp

                      I got this to work, but when I redeploy my session bean, I get a ClassCastException:

                      ERROR [STDERR] java.lang.ClassCastException
                      ERROR [STDERR] at com.sun.corba.se.internal.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:293)
                      ERROR [STDERR] at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:134)


                      ...in my class that calls the session bean. This class is called by the Scheduler MBean (it implements org.jboss.varia.scheduler.Schedulable)

                      the code that fails looks like this:

                      Context ctx = new InitialContext();
                      Object result = ctx.lookup("MyBean");
                      MyBeanHome home = (MyBeanHome)
                      javax.rmi.PortableRemoteObject.narrow(result, MyBeanHome.class);
                      home.create().doWork();


                      it works the first time, when JBoss is started and the beans are deployed and the scheduler started for the first time. I'm assuming this is a classloader issue, since when the bean classes are reloaded with a new classloader, they don't match the type in the code above.

                      My real question is: how do I work around this?

                      thanks in advance
                      Justin

                      • 8. Re: mbean -> job trigger -> session bean
                        jcasp

                        also, I thought that PortableRemoteObject.narrow() was supposed to work around the problem of class type equality when dealing with interfaces for classes loaded in different classloaders.
                        Is there any reason this wouldn't apply to classes (re)loaded in the same JVM?

                        • 9. Re: mbean -> job trigger -> session bean

                          Yes it is supposed to workaround the problem.
                          However, the 1.4 JDK caches classes against the
                          classloader.

                          It seems to want to do this against the classloader
                          of the naming service or the RMI invoker since
                          these are where the RMI stubs live.

                          But these aren't redeployed so it doesn't flush
                          its cache. Hence it uses the old class from before the
                          redeployment.

                          Regards,
                          Adrian

                          • 10. Re: mbean -> job trigger -> session bean
                            jcasp

                            Thanks for your reply, Adrian

                            Is this a known bug in the 1.4 JVM or is this done on purpose?
                            I'm not familiar enough with the JBoss architecture to come up with an easy workaround other than restarting JBoss every time I redeploy my application. I would really like to avoid this. Is there anything you would suggest I try to workaround this situation?
                            thanks again for your help.
                            Justin

                            • 11. Re: mbean -> job trigger -> session bean

                              There is a workaround in 3.0.5+ that
                              caches interfaces against your application classloader.
                              The workaround isn't necessary if you
                              avoid the RMI layer for local beans.

                              Regards,
                              Adrian

                              • 12. Re: mbean -> job trigger -> session bean
                                jcasp

                                Hi Adrian,
                                I tried getting the latest code from Branch 3_0, I am now running 3.0.7RC1, but I still get the ClassCastException when calling the session bean from the Scheduler MBean.

                                I've tried the following two ways of invoking the bean:

                                Context ctx = new InitialContext();
                                Object result = ctx.lookup("MyBean");
                                MyBeanHome beanHome = (MyBeanHome)result;

                                and

                                Context ctx = new InitialContext();
                                Object result = ctx.lookup("MyBean");
                                MyBeanHome beanHome = (MyBeanHome)javax.rmi.PortableRemoteObject.narrow(result, MyBeanHome.class);

                                beanHome.create().evaluate();

                                (both options work fine the first time JBoss is started and the ear is deployed)

                                I'm assuming the first example is what you meant by "avoid the RMI layer for local beans", right?

                                What do I need to do to take advantage of the 3.0.5+ workaround you describe above?

                                thanks again in advance
                                Justin

                                • 13. Re: mbean -> job trigger -> session bean

                                  You have a different problem.

                                  Your Scheduler MBean is holding a direct reference
                                  to the class. You need to recycle the MBean class
                                  when redeploying the ejb so the old class reference
                                  is released.

                                  Add a to scheduler deployment descriptor
                                  jboss.j2ee:service=EJB,jndiName=whatever

                                  Regards,
                                  Adrian

                                  • 14. Re: mbean -> job trigger -> session bean
                                    jcasp

                                    Hi Adrian, thanks again for your help.

                                    I already had that dependency in my Scheduler MBean deployment descriptor:

                                    true
                                    ... (declare class that calls MyWorkBean) ...
                                    0
                                    10000
                                    -1
                                    jboss.j2ee:service=EJB,jndiName=MyWorkBean


                                    I notice that when I undeploy my application, the scheduler stops:
                                    12:34:50,809 INFO [Scheduler] Stopping
                                    12:34:50,809 INFO [Scheduler] Stopped

                                    and when I redeploy my application, it is created and starts again after MyWorkBean is created (so the dependency works)
                                    12:35:32,533 INFO [EjbModule] Creating
                                    12:35:32,608 INFO [EjbModule] Deploying MyWorkBean
                                    12:35:32,742 INFO [Scheduler] Creating
                                    12:35:32,743 INFO [Scheduler] Created
                                    ...
                                    12:35:39,108 INFO [Scheduler] Starting
                                    12:35:39,126 INFO [Scheduler] Started


                                    Then the ClassCastException occurs, so I guess this process isn't causing the bean class reference to be refreshed.

                                    I'm using new JBoss 3.0.7 code. Can you think of anything else I might be missing? Perhaps this is a bug to report?

                                    thanks again
                                    Justin

                                    1 2 Previous Next