debugging java AbstractMethodError

B

Bin Xin

Hi,

I am doing a little CORBA java programming lately, using JacORB
implementation. And when I am testing my implementation of the
EventChannel service , I get the following puzzling message(which
might appear to be very simple):

java.lang.AbstractMethodError: EventConfig/ProxyPullSupplierBase_bt.try_pull
at EventChannelAdmin.ProxyPullSupplierPOATie.connect_pull_consumer(Unknown Source)
at EventChannelAdmin.ProxyPullSupplierPOA._invoke(Unknown Source)
at org.jacorb.poa.RequestProcessor.invokeOperation(RequestProcessor.java:247)
at org.jacorb.poa.RequestProcessor.process(RequestProcessor.java:477)
at org.jacorb.poa.RequestProcessor.run(RequestProcessor.java:604)
java.lang.InterruptedException: operation interrupted
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:420)
at org.jacorb.orb.ORB.run(ORB.java:1115)

I use the Tie approach here, so the POATie class delegate the call, connect_
pull_consumer, to another implementation class, A. And A is concrete and
inherits the abstract ...Base_bt class in the error message. And try pull
is just another
method in the same interface that A implements, and is surely not called
from with the body of connect_pull_consumer.

So, my question is: 1) how an AbstractMethodError can be thrown without
actually been called at runtime?(The Java Spec. seems to say it will not
happen at loading or verifying stage.) 2). Any other suggestions/tools to
debug a distributed object system, like something that I can hook to the
servant thread and get a detailed log message when a call comes in from the
orb.

Thanks,

-B
 
J

John C. Bollinger

Bin said:
Hi,

I am doing a little CORBA java programming lately, using JacORB
implementation. And when I am testing my implementation of the
EventChannel service , I get the following puzzling message(which
might appear to be very simple):

java.lang.AbstractMethodError: EventConfig/ProxyPullSupplierBase_bt.try_pull
at EventChannelAdmin.ProxyPullSupplierPOATie.connect_pull_consumer(Unknown Source)
at EventChannelAdmin.ProxyPullSupplierPOA._invoke(Unknown Source)
at org.jacorb.poa.RequestProcessor.invokeOperation(RequestProcessor.java:247)
at org.jacorb.poa.RequestProcessor.process(RequestProcessor.java:477)
at org.jacorb.poa.RequestProcessor.run(RequestProcessor.java:604)
java.lang.InterruptedException: operation interrupted
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:420)
at org.jacorb.orb.ORB.run(ORB.java:1115)

I use the Tie approach here, so the POATie class delegate the call, connect_
pull_consumer, to another implementation class, A. And A is concrete and
inherits the abstract ...Base_bt class in the error message. And try pull
is just another
method in the same interface that A implements, and is surely not called
from with the body of connect_pull_consumer.

Either your VM is broken or at least one of those statements is false.
The likely case is that even though A is intended to be concrete, it is not.

It may be that you are a victim of class version skew. The first thing
you should do is a complete clean build. Then make sure that the class
libraries in your build environment correspond to those in your
deployment environment. Finally, make sure that the cleanly built
classes are deployed, and that there are no old versions floating around
where they might be loaded in preference to the new ones. In a
distributed environment that means ensuring compatible class versions
across the whole network.

Very likely either you will discover the problem in the process of
performing those steps, or it will disappear.
So, my question is: 1) how an AbstractMethodError can be thrown without
actually been called at runtime?(The Java Spec. seems to say it will not
happen at loading or verifying stage.) 2). Any other suggestions/tools to
debug a distributed object system, like something that I can hook to the
servant thread and get a detailed log message when a call comes in from the
orb.

An AbstractMethodError can be thrown during linking if the VM exercises
its option to resolve some or all symbolic method references at link
time. Linking occurs before class initialization, so an
AbstractMethodError could occur on the first use of a class by your
application even if the abstract method is never invoked anywhere in the
application.

Sorry, no suggestions specific to ORB debugging.


John Bollinger
(e-mail address removed)
 
B

Bin Xin

Thanks for your reply.
Either your VM is broken or at least one of those statements is false.
The likely case is that even though A is intended to be concrete, it is not.

The class A is, indeed, concrete. That is the sort of thing you want to
make sure at the first sight of the error. The VM may really have some
problem. I am using JDK1.3.1 on a FreeBSD box. And I am using some
third party jar files built on different platforms and JDK versions(with
some even be built by JDK1.5 in the newer version of GJ).

[On a side note, this experience almost makes me think the platform
independency, and compatibility brought by Java is not as simple as it
may have sounded.]
It may be that you are a victim of class version skew. The first thing
you should do is a complete clean build. Then make sure that the class
libraries in your build environment correspond to those in your
deployment environment. Finally, make sure that the cleanly built
classes are deployed, and that there are no old versions floating around
where they might be loaded in preference to the new ones. In a
distributed environment that means ensuring compatible class versions
across the whole network.

I will keep that in mind. Although I have taken some measure against this,
like check out a fresh CVS copy and rebuild, rerun the test.
An AbstractMethodError can be thrown during linking if the VM exercises
its option to resolve some or all symbolic method references at link
time. Linking occurs before class initialization, so an
AbstractMethodError could occur on the first use of a class by your
application even if the abstract method is never invoked anywhere in the
application.

Can this "option" be turned off? Since binary compatibility seems to
dictate that AbstractMethodError be a pure runtime error.

Thanks again,

-B
 
J

John C. Bollinger

Bin said:
[...]
Either your VM is broken or at least one of those statements is false.
The likely case is that even though A is intended to be concrete, it is not.


The class A is, indeed, concrete. That is the sort of thing you want to
make sure at the first sight of the error. The VM may really have some
problem. I am using JDK1.3.1 on a FreeBSD box. And I am using some
third party jar files built on different platforms and JDK versions(with
some even be built by JDK1.5 in the newer version of GJ).

[On a side note, this experience almost makes me think the platform
independency, and compatibility brought by Java is not as simple as it
may have sounded.]

It is quite possible to introduce platform dependency into a Java
program. On the other hand, it is much easier to write
platform-independant code in Java than it is in many other languages.
You just have to pay attention to what you're doing if platform
independence is what you want.
I will keep that in mind. Although I have taken some measure against this,
like check out a fresh CVS copy and rebuild, rerun the test.

If that doesn't solve your problem then you might continue by capturing
the problematic class file that is (presumably) delivered over the
network, writing the bytes to disk, and decompiling the class. You may
also want to look at the relevant superclasses.
Can this "option" be turned off? Since binary compatibility seems to
dictate that AbstractMethodError be a pure runtime error.

This is an option provided to VM implementors by the JVM specification.
It is conceivable that some VMs might offer an switch to toggle the
behavior. I am not aware that any VMs do offer such a switch, but I
cannot positively say that any particular one doesn't.

Also, although I didn't say so in my previous message, another
possibility is that static initialization code, instance initialization
code, or a constructor is actually invoking the abstract method. If you
have all the sources then you should in fact look into whether instance
initialization code or a constructor might be invoking a virtual method
that is abstract in the relevant class and only defined in the concrete
subclass. That is generally considered a poor practice, and it can
cause problems, albeit not normally this particular problem.

As for timing of the error, I used "linking" in the Java Virtual Machine
sense. The VM specification contains a detailed description of exactly
what this entails, but in any case it _is_ a runtime operation because
Java uses dynamic class loading and linking. VMs typically do not load
or link classes until they need to, which may be well into the execution
of a program. In any case, I'm not sure I understand why you argue that
binary compatibility considerations dictate that such a problem must be
a "pure" (whatever that means) runtime error in the first place.

More importantly, you have a fundamental problem here that would not be
adequately addressed by changing the timing of symbolic method reference
resolution. Hiding or deferring the problem will not make it disappear,
and very likely the same problem or a close cousin would manifest elsewhere.


Good luck,

John Bollinger
(e-mail address removed)
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top