intercept new

B

Brian P. Bailey

I need to write a utility that intercepts an instruction to create a new
object and replace that object with something else during __runtime__
without access to the raw Java code. For example, if a bytecode instruction
desires to create a new Widget like so...

Widget widget = new Widget();

....then I would like to replace that bytecode instruction with...

Widget widget = new MyReplacementWidget();

I'm thinking that I need to do this at the classloader level, but am not
certain. Have any of you smart people run across any resources that might
clue me in?

TIA,

Brian P. Bailey
 
A

Andrew Thompson

Brian said:
I need to write a utility that intercepts an instruction to create a new
object and replace that object with something else during __runtime__
without access to the raw Java code.

Why? What does this tool bring to its end user?

Andrew T.
 
B

Brian P. Bailey

It brings what I said...the ability to replace an object with a different
object during runtime without accessing the raw Java code. Think of it as
retrofitting an application with a new capability at runtime without
modifying the existing code base. More specifically, I would like to replace
the next three calls to "new Widget()" with "new ReplacementWidget()".

I think that I would need to introspect the bytecode, but I'm not certain.
Would the proper place to do this be in a classloader? I'm not replacing the
entire class, just certain calls to create new instances of a class.
 
H

hiwa

Brian said:
It brings what I said...the ability to replace an object with a different
object during runtime without accessing the raw Java code. Think of it as
retrofitting an application with a new capability at runtime without
modifying the existing code base. More specifically, I would like to replace
the next three calls to "new Widget()" with "new ReplacementWidget()".

I think that I would need to introspect the bytecode, but I'm not certain.
Would the proper place to do this be in a classloader? I'm not replacing the
entire class, just certain calls to create new instances of a class.
Tell me, what should be the uer interface for that functionality?
Command line arguments? A kinda cofiguration file? Or?
And, another thing:
Does the original application use an interface-base design?
Or does it simply call concrete classes?
 
C

Chris Uppal

Brian said:
I need to write a utility that intercepts an instruction to create a new
object and replace that object with something else during __runtime__
without access to the raw Java code. [...]
I'm thinking that I need to do this at the classloader level, but am not
certain.

Yes, that's one of the two ways you can do it; define your own kind of
classloader which will modify the bytecode before passing it to defineClass().
The other way is to use the stuff in package java.lang.instrument to "hook"
class creation (or you could do the same thing in 'C' or C++ by providing a
JVMTI "agent", but Java is probably easier ;-) Which you use depends on your
own application -- either could be appropriate.

There are several packages available on the Web which claim to make it easier
to modify class files. Offhand I can't remember any of their names, but you
should be able to find them with Google[*]. If you can't find any, or don't
like what you find, then a package like ASM or BCEL will provide the necessary
tools for raw bytecode-manipulation.

-- chris

[*] Try:
"bytecode manipulation" Java

Also worth looking into the technology used to implement the runtime part of
"AOP"
 
P

Patricia Shanahan

Brian said:
I need to write a utility that intercepts an instruction to create a new
object and replace that object with something else during __runtime__
without access to the raw Java code. For example, if a bytecode instruction
desires to create a new Widget like so...

Widget widget = new Widget();

...then I would like to replace that bytecode instruction with...

Widget widget = new MyReplacementWidget();

I'm thinking that I need to do this at the classloader level, but am not
certain. Have any of you smart people run across any resources that might
clue me in?

TIA,

Brian P. Bailey

In addition to the advice you already have, consider writing it in
AspectJ, instead of pure Java.

Patricia
 
B

Brian P. Bailey

Thanks Chris. I'm needing to use Java specifically because I am
investigating creating a unit test capability that can operate at the byte
code level and intercept calls to new rather than force the programmer to
pass in factories as method arguments.

Why would someone want to do this? Because it's cool. Why are factories bad?
They aren't. I'm just investigating a different approach. There's a mocking
framework for .NET called typeMock that does something similar, but I've
never found one for Java that works this way. So I thought I'd see if it can
be done.

After all, at some point, SOME method has to call new. And you can't mock at
this point. And if the object being created uses an external resource (e.g.,
new Socket) then the method can't normally be unit tested. But intercepting
new and replacing with a different object (e.g., a mock object) might allow
the method to be unit tested.

Anyway, enough with the rambling. Thanks again for the help.
 
B

Brian P. Bailey

Patricia,

I've never looked into AspectJ before, and just looked it up in wikipedia.
I'm thinking that pointcuts are what you were referring to. Wikipedia's
description showst hat this looks very promising. Thanks for the tip!
 
C

Chris Uppal

Brian said:
[...] I am
investigating creating a unit test capability that can operate at the byte
code level and intercept calls to new rather than force the programmer to
pass in factories as method arguments.

If you are creating a general purpose feature, then the approach based on
java.lang.instrument is probably your better bet, since that won't interfere
with whatever use the target code itself makes of classloaders (or assumptions
it makes about them). The downside (which I forgot to mention) is that the
instrumentation stuff only became conveniently[*] available in Java 1.5.

-- chris
 

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
474,266
Messages
2,571,087
Members
48,773
Latest member
Kaybee

Latest Threads

Top