1 2 Previous Next 16 Replies Latest reply on Jan 9, 2004 11:31 AM by birwin

    Programatic EJB cache flush

    n_ton

      Hi,

      I am using JUnit to do some unit testing. I have an EJB which needs to have different values for different tests.

      The problem I'm having is that since the EJB is already loaded from the db, the EJB is cached and any updates I do to the db don't show up in the EJB.

      Is there a way that I can flush the EJB cache programatically? A code snippet will be very helpful.

      Thank you for your help.

      Norton

        • 1. Re: Programatic EJB cache flush
          jamesstrachan

          There is no programmatic way to clear the cache (subject to correction from the jboss gurus).


          But you can either :-

          use commit-option C in jboss.xml to force reload from the database when an EJB is accessed

          or :-

          Use the setup() method in each test case to directly set the desired values in the EJB.

          • 2. Re: Programatic EJB cache flush
            raja05

            Havent tried this but it should work!!

            Try getting the MBean for the EJB u are interested in and do a flushCache() on that object.
            You can get the objectname for ur managed object from http://localhost:8080/jmx-console.

            -Raj

            • 3. Re: Programatic EJB cache flush
              raja05

              Try this code snippet from ur junit setup

              InitialContext ic = new InitialContext();
              RMIAdaptor server = (RMIAdaptor) context.lookup("jmx/rmi/RMIAdaptor");

              ObjectName name = new ObjectName("jboss.j2ee:<ur ejb>");
              server.invoke(name, "flushCache", null, null);

              • 4. Re: Programatic EJB cache flush
                n_ton

                Thanx for your code snippet. I'm getting an exception because I don't think I have the ObjectName lookup name right.

                I looked in my jmx-console and went to the MBean View of the EJB I wanted to flush:

                MBean Name: Domain Name: jboss.j2ee
                        service: EJB
                        jndiName: Affiliate
                MBean Java Class: org.jboss.ejb.EntityContainer


                So in my code, I put:

                ObjectName name = new ObjectName("jboss.j2ee:Affiliate");


                But when the code gets run, I get the exception:

                javax.management.MalformedObjectNameException: malformed key/value pair: Affiliate

                Is there something else I'm missing?

                Thanx again for your help.

                Norton

                • 5. Re: Programatic EJB cache flush
                  n_ton

                  Got it! I looked up the ObjectName API doc and figured out that the constructor call should look like this:

                    ObjectName name = new ObjectName("jboss.j2ee:jndiName=Affiliate,service=EJB");

                  The EJB was found, the EJB was flushed, and all my tests worked like a charm.

                  Thanx a lot for your help raja05.

                  The JBoss community is awesome.

                  Norton

                  • 6. Re: Programatic EJB cache flush
                    auswalk

                    I tried the following and got this:

                    Caused by: java.rmi.UnmarshalException: error unmarshalling arguments;
                    nested exception is:
                    java.io.InvalidClassException: javax.management.ObjectName; local class incompatible: stream classdesc serialVersionUID = -5467795090068647408, local class serialVersionUID = 1081892073854801359
                    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:249)
                    at sun.rmi.transport.Transport$1.run(Transport.java:148)
                    at java.security.AccessController.doPrivileged(Native Method)
                    at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
                    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
                    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
                    ... 1 more
                    Caused by: java.io.InvalidClassException: javax.management.ObjectName;
                    local class incompatible: stream classdesc serialVersionUID = -5467795090068647408,
                    local class serialVersionUID = 1081892073854801359
                    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:459)
                    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1521)
                    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1435)
                    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1626)
                    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
                    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
                    at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:297)
                    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:246)
                    ... 6 more

                    • 7. Re: Programatic EJB cache flush
                      raja05

                      Are you using a different version of JRE in server and client? Any chances of different versions of JMX Package?

                      • 8. Re: Programatic EJB cache flush
                        auswalk

                        Yes unforunately I appear to be. Resin is my client program. I tried reordering the classpath so that the jboss jar come first, still get the error. I can't get rid of the resin jmx.jar b/c it has some classes required by resin. Not sure what to do here..

                        • 9. Re: Programatic EJB cache flush
                          raja05

                          Did you try substituting the jboss-jmx.jar package for resin jmx. jboss-jmx.jar has jmx classes as well as jboss specific ones.

                          • 10. Re: Programatic EJB cache flush
                            auswalk

                            I ended up sticking it all in a session bean method... thereby circumventing the client problem. One question though, assuming a non-clustered jboss environment, the beans will only be flushed on the server it happens to invoke the flushCache operation on?

                            I assume this to be the case. I would also assume in a clustered environment this issue would be resolved.

                            • 11. Re: Programatic EJB cache flush
                              raja05

                              How about this?
                              You could call any method using a URL like

                              http://localhost:8080/jmx-console/HtmlAdaptor?action=invokeOpByName&name=jboss.j2ee:jndiName=com.yoyo.AddressJNDI,service=EJB&methodName=flushCache

                              In this case, it will call my EJB with Object name of
                              jboss.j2ee:jndiName=com.yoyo.AddressJNDI,service=EJB
                              and invoke flushcache on it. and it works!!!

                              So all you have to do is open a URLConnection to it from ur client.

                              -Raj

                              • 12. Re: Programatic EJB cache flush
                                birwin

                                When I attempt to use this code, I get a "No Such Method" exception. I am using JBoss 3.2. Attached is my code.

                                Properties p = new Properties();
                                p.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
                                p.put("java.naming.provider.url", "localhost:1099");
                                InitialContext jndiContext = new InitialContext(p);
                                RMIAdaptor server = (RMIAdaptor) jndiContext.lookup("jmx/rmi/RMIAdaptor");
                                javax.management.ObjectName name = new javax.management.ObjectName("jboss.j2ee:jndiName=ejb/PropertySettingsEJB,service=EJB");
                                server.invoke(name, "flushCache", null, null);

                                I have changed the jndiName to not include "ejb/", but the ObjectName returns null in that case.

                                Is there a JBoss specific ObjectName class I am supposed to use?

                                • 13. Re: Programatic EJB cache flush
                                  raja05

                                  Lookup the name from JMX-Console and use it.
                                  http://localhost:8080/jmx-console
                                  All the EJBs would be listed in the jboss.j2ee space. Look for ur EJB and get the ObjectName and use that in the ObjectName constructor.

                                  • 14. Re: Programatic EJB cache flush
                                    birwin

                                    I attempted to implement this code, but my code throws an error and complains that the ObjectName class does not have a flushCache method. The fully qualified name of my ObjectName is javax.management.ObjectName. Does JBoss subclass ObjectName? If not, why might I be getting this error?

                                    1 2 Previous Next