Troubleshooting your WebLogic EJB application
- Contents
- Using debuggers
- Using Jikes
- System.out.println()
- Other debugging tips
- Running client and bean in server
- isModified()
- Beans and the new classloader
Using debuggers
Using Jikes
IBM's Jikes,
currently available for free from IBM's
alphaWorks site,
is a graphical user interface for the JavaSoft
JDB (Java Language Debugger).
Jikes is easy and quick to use:
- It has a minimal amount of setup
- It doesn't require setting up of projects,
makefiles, etc.
- Just identify the class in your application that contains the
main() method, which for a
WebLogic EJB application is weblogic.Server.
- It displays variable values by calling
toString() on them, so
you can get the "value" of a data structure even if you have not
compiled that file with "-g".
- For classes that do have debug info,
Jikes can display individual attributes and local variables.
It is compatible with any VM supporting JavaSoft's debugging interface.
Compile your classes with "-g -debug"
if you'd like local variables to show up
while in the debugger.
- Unfortunately, Jikes' user interface is limited.
It doesn't remember breakpoints and other settings between sessions,
and all actions are mouse-driven.
Using System.out.println()
For thread and concurrency related issues, using
System.out.println() is the least intrusive
in terms of how it side-affects scheduling.
The context given to a bean supports the toString()
method, so the contents of the bean can be printed out to get an idea of the transactional state of a bean instance.
Other debugging tips
Running client and bean in server
When you have System.out.println()statements
in your client and bean code, you may want to merge the
two streams of output to see cause and effect.
To do this, you need to run the client code in the server
so that the calls to the System.out.println()
method get serialized.
One easy way to do this is to invoke the client application's
main() method from an http servlet's
execute() method, and then invoke the servlet
from a browser to invoke the client code.
You can see examples of this in the servlet clients included in the
beanManaged
and
containerManaged
examples.
Setting isModified()
When debugging, change the
isModified()
flag to always return true,
to ensure that incorrect handling of this flag is not the reason for your troubles.
This is slower, but by always going to the database whenever the bean is touched,
there should not be any mismatch between the database and the bean.
See also the Developers Guide
Designing
a WebLogic EJB application: isModified() and persistence.
As we noted in "Setting isModified(),"
passivation can cause trouble if the bean
instance is reused and the bean or the EJB framework has a bug
that does not take this aspect into account.
If you suspect passivation of a bean is causing a problem,
try setting the maxBeansInCache
and the idleTimeoutSeconds properties
in the deployment descriptor to large numbers.
The beans will not be passivated by the scrub timer,
or pushed out of the cache to make room for a new entrant.
Beans and the new classloader
Beginning in version 4.5, the WebLogic Server loads EJBeans in a separate classloader for each
.jar file that's used. This change was made to allow hot deployment of EJBeans in a
running WebLogic Server. This can require changes in how you design, build and deploy beans on a Server.
- Each .jar is an individual deployment unit, and is loaded into a separate classloader.
- When a bean is deployed, all the classes that are Java interfaces or part of the
bean's interface signature (bean interface, home interface, including return types, arguments
and exceptions) are exported from the bean's classloader to the parent classloader
that loaded the Server. This makes these classes available to other EJBeans (deployed
separately) and other server-side classes.
- All the beans that are dependent (i.e., that directly extend another bean's classes)
must be in the same .jar in order for the classes to be accessible to each other.
- A manifest that lists all the beans in the .jar must be used to jar the beans together.
- When you redeploy beans through the WebLogic Console,
all the beans in the .jar file are redeployed as a unit.
- The EJB examples scripts have been modified to
build the EJBeans into .jar files that contain only the server-side code. If you are using
Microsoft's SDK for Java, you will need to install a SDK from Sun and use its jar tool to
package your EJBeans.
- Examples (such as subclass child)
that use more than one bean by subclassing include the other bean
in the same .jar.
- If you have existing EJBeans, you will need to recompile them with
ejbc
before running them. You may need to adjust any build scripts that you use to package
related beans together into single jars so that classes can be found when they are loaded.
- If you have been deploying beans using .ser files, these will not work correctly,
as each .ser is loaded in a separate classloader and is not redeployable. You will
need to package those beans into .jars.
-
If you are redeploying beans on a Server, clients (either Java clients or
servlets that are using a bean) must catch a
weblogic.ejb.common.RedeploymentException
that's thrown when redeployment occurs, and take proper action, as shown in these
code fragments, as there is no failover on redeployment:
Stateless session bean:
String beanHome = "mybean.BeanHome";
myBeanHome home = (myBeanHome)ctx.lookup(beanHome);
System.out.println("home: " + home.getClass().getName());
myBean bean = home.create();
System.out.println("bean: " + bean.getClass().getName());
while (true) {
try {
System.out.println("bean method result: " + bean.myMethod());
Thread.currentThread().sleep(2000);
break;
} catch (weblogic.ejb.common.RedeploymentException e) {
System.err.println("Detected redeployment");
home = (myBeanHome)ctx.lookup(beanHome);
bean = home.create();
}
}
Entity session bean:
String myBeanHome = "mybean.AccountHome";
AccountHome home = (AccountHome)ctx.lookup(myBeanHome);
String id = "my account id";
AccountPK pk = new AccountPK();
pk.accountId = id;
System.out.println("home: " + home.getClass().getName());
Account bean = home.create(id);
System.out.println("bean: " + bean.getClass().getName());
while (true) {
try {
System.err.println("bean method result: " + bean.myMethod());
break;
} catch (weblogic.ejb.common.RedeploymentException e) {
e.printStackTrace();
System.err.println("detected redeployment");
home = (AccountHome)ctx.lookup(myBeanHome);
bean = home.findByPrimaryKey(pk);
}
}

|