Dynamic class manipulation

J

Joe

I'm using BCEL in conjunction with a custom classloader to dynmically
modify the bytecode of a class as it's loaded.

I'm now considering the problems I'm going to face when using such a
mechanism inside an application server such as Tomcat.

I need to do the following on application startup (e.g. in a main
method for command-line, or in a Servlet class when used in a web
app):

1. Load and parse a configuration file, listing a number of classes
2. For each class, load it via a custom class loader and modify the
bytecode
3. Ensure that everywhere in the application that such a class is
reference (e.g. through new MyClass()), my modified version is used.

What's worrying me is that although I initially load and modify the
classes using my Custom ClassLoader, when they are referred later in
the application (eg. in a Servlet call), a different ClassLoader will
be used (ie. the Tomcat webapp thread one), so I'll end up with a
different, unmodified class.

Am I right in thinking that this is what'll happen? If so, what can I
do to avoid it (short of pre-processing the classes and storing the
modified class files)?
 
C

Chris Smith

Joe said:
What's worrying me is that although I initially load and modify the
classes using my Custom ClassLoader, when they are referred later in
the application (eg. in a Servlet call), a different ClassLoader will
be used (ie. the Tomcat webapp thread one), so I'll end up with a
different, unmodified class.

If you make the class available to the web application's context
classloader, then you'll always end up with the unmodified class,
regardless of which classloader you use (assuming that your custom
classloader uses the context classloader as a parent, which it should).

But then you run into another problem: you still need the client code to
be loaded by your custom loader in order to see the modified classes at
all. This problem does exist, and you'll need to solve it. One simple
way would be to write simple proxy servlets that look something like
this:

public class ForwardingServlet implements Servlet
{
private Servlet base;

public ForwardingServlet(Servlet base)
{
this.base = base;
}

public void destroy()
{
base.destroy();
}

...
}

You'd need to subclass this with a few servlets that specifically get
other servlet classes from your classloader, and then delegate. For
example:

public class SomeProxyServlet extends ForwardingServlet
{
public SomeProxyServlet()
{
super(loadServlet());
}

private static Servlet loadServlet()
{
// get your classloader, and load and instantiate the
// SomeServlet class.
}
}

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
W

Will Hartung

Joe said:
I'm using BCEL in conjunction with a custom classloader to dynmically
modify the bytecode of a class as it's loaded.

I'm now considering the problems I'm going to face when using such a
mechanism inside an application server such as Tomcat.

What's worrying me is that although I initially load and modify the
classes using my Custom ClassLoader, when they are referred later in
the application (eg. in a Servlet call), a different ClassLoader will
be used (ie. the Tomcat webapp thread one), so I'll end up with a
different, unmodified class.

Program to generic interfaces, and load the actual classes through a factory
of somekind.

Regards,

Will Hartung
([email protected])
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top