Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / Virtual Machine / June 2005

Tip: Looking for answers? Try searching our database.

Jeode and Jbed ClassLoader differences?

Thread view: 
Kid - 27 Jun 2005 13:02 GMT
Hello,

Has anyone experienced class loading differences between Jeode and JBed
CDC?
This reason I'm asking is because we've used Jeode for 2 years now and
it works fine. Now we're trying to convert to Jbed CDC, but we're
having some problems.

The following (pseudo) code works on Jeode but not on Jbed:

...
test = true;
if (test) {
  new ClassSupportedByCDC();
}
else {
  new ClassNOTSupportedByCDC();
}

The class ClassNOTSupportedByCDC is never instantiated (test is always
true) but Jbed gives a:
java.lang.NoClassDefFoundError:ClassNOTSupportedByCDC

as soon as one enter the method with the code metioned (it doesn't
execute a single line).
Does the runtime for Jbed preload all classes? Is this some kind of
optimization? Is there any way around this?
As I said before, it works great with Jeode.

By the way, anyone know if there are any forums available to discuss
about Jbed/Jeode and java related issues?

Thanks.
Kid
Mike Amling - 27 Jun 2005 20:01 GMT
> Hello,
>
[quoted text clipped - 21 lines]
> as soon as one enter the method with the code metioned (it doesn't
> execute a single line).

  Was your program compiled with the same compiler in both cases? That
is, it's not just a case of one compiler treating if (test) as if it
were if (true), is it?

--Mike Amling
Kid - 28 Jun 2005 08:32 GMT
Same compiler, same class codes.
As I said, Jbed throw the exception immediatly when entering the
method.

/Kid
Mark Bottomley - 29 Jun 2005 01:34 GMT
> Same compiler, same class codes.
> As I said, Jbed throw the exception immediatly when entering the
> method.
>
> /Kid

It would seem that the code you have written is un-verifiable. You could
possibly rewrite the code to use .forName to look for the one missing
class and catch the exception for classNotFoundError and load the other
similarly with .forName in the exception handler block.

It may be that the Jeode VM is not using verification and the Jbed VM is.
You may want to hack a .class file to make it invalid and see if the Jeode
VM rejects it. A verification error can easily be induced by reducing the
max stack depth for a method. There are plenty of public bytecode
assemblers to use if you need and there are many .class file
viewers/disassemblers too. Another test would be to try and run the class
on Sun's VM - as the definition of what is correct, the result there should
be a good indication of the correct action. The Sun JRE is easy to find
and download if you don't have it already.

Mark...
Kid - 29 Jun 2005 10:54 GMT
Thanks for the information Mark & Seungil.

Mark,
> You could possibly rewrite the code to use .forName to look for the one missing
> class and catch the exception for classNotFoundError and load the other
> similarly with .forName in the exception handler block.

I've been thinking of doing this, but that would mean to use the
reflect classes and I'm not sure how much this package is supported.
Also, there are too many places this has to be done! ;)

What does verification mean? That the VM checks if the method is valid
before executing it? Exactly what is checked?

> You may want to hack a .class file to make it invalid and see if the Jeode
> VM rejects it. A verification error can easily be induced by reducing the
> max stack depth for a method. There are plenty of public bytecode
> assemblers to use if you need and there are many .class file
> viewers/disassemblers too.

Sounds interesting. I haven't handled java bytecode before.
Do you have any recommendations for bytecode assembles, viewers?

> Another test would be to try and run the class
> on Sun's VM - as the definition of what is correct, the result there should
> be a good indication of the correct action. The Sun JRE is easy to find
> and download if you don't have it already.

I've tried it on the Sun's 1.5 JRE and it runs without any exceptions.
Haven't tried it on older jre though (1.3 should be equal to JME CDC).

Seungil,
I think it's a performance issue too. But if this is the case, it means
that a lot of "useless" classes are preloaded, and they won't even be
referenced! This is a waste of both time and memory!

I've tried to contact Esmertec but haven't got any replies yet. Seems
like they are very hard contact unless you are a PDA manufacturer and
have alot of cash!
Insignia, who owned Jeode before Esmertec, was much easier to reach.

By the way, anyone know where I can find a "changes" list for
Jeode/Jbed?
Because I've noticed some other significant differences!
I thought that one should be able to run Jeode applications straight
over on Jbed, since Jbed is a superset of Jeode. But this is not, by
far, the case!

Regards,
/Kid
Mark Bottomley - 30 Jun 2005 02:26 GMT
> Thanks for the information Mark & Seungil.
>
[quoted text clipped - 7 lines]
> reflect classes and I'm not sure how much this package is supported.
> Also, there are too many places this has to be done! ;)

I don't think it is a reflection activity - it is part of java/lang/class.
(I could be wrong as I'm a VM programmer, not a Java guru)

> What does verification mean? That the VM checks if the method is valid
> before executing it? Exactly what is checked?

Verification is what makes the Java language safe - it has several parts:

1) take a bag of bytes and see if it smells like a .class file. Things that
are checked include things like CAFEBABE as the first four bytes,
legal access flag combinations, legal constant pool formation, etc. The
bag of bytes must have no left over bytes and must be complete. The
failure of an checks at this stage usually result in a ClassFormatError.

2) take the possible .class file and check the gory details with data flow
analysis of the methods. The stack must never overflow/underflow, the
bytecode data must be of the correct type e.g. iadd must find 2 integers
on the top of the stack and it will leave 1 integer. Failures typically
result
in a VerifyError.

3) load any referenced classes for visibility to check legal method calls,
visibility constraints and availability. Failures could be VerifyErrors or
some other types. This can caused nested verification as parent
classes must be loaded before child classes can complete verification.

4) runtime checks of things like Null pointers, division by 0, and array
bounds violations are checked. These result in the appropriate
exception.

For most of the details, see the JVM spec chapter 4. 4.1 to 4.7
describe a .class file, 4.8 contains most of the things checked for
by verification, 4.9 gives an overview of the verification sequence.
4.10 contains some more verification checks.

Verification can usually be enabled/disabled (depending on the vendor's
default) with command line options like -verify or -noverify. Using an
empty java command line will often give you a subset of the acceptable
options.

>> You may want to hack a .class file to make it invalid and see if the
>> Jeode
[quoted text clipped - 5 lines]
> Sounds interesting. I haven't handled java bytecode before.
> Do you have any recommendations for bytecode assembles, viewers?

Unfortunately, the tools I use are in-house tools, but there are several
public domain java assemblers and javap is Sun's disassembler
available in the JDK.

>> Another test would be to try and run the class
>> on Sun's VM - as the definition of what is correct, the result there
[quoted text clipped - 4 lines]
> I've tried it on the Sun's 1.5 JRE and it runs without any exceptions.
> Haven't tried it on older jre though (1.3 should be equal to JME CDC).

If it is passing through Sun's 1.5 JRE, it is probably valid code.

> Seungil,
> I think it's a performance issue too. But if this is the case, it means
[quoted text clipped - 15 lines]
> Regards,
> /Kid

Mark...
seungil.lee@gmail.com - 29 Jun 2005 01:48 GMT
I think JBed CDC does not support JVM Spec correctly.
It should not reference ClassNOTSupportedByCDC until it is actually
executed.
However, some JVMs does this due to performance issues.
I recommand not using JBed CDC or changing your code.
Chris Uppal - 29 Jun 2005 08:33 GMT
> The following (pseudo) code works on Jeode but not on Jbed:
>
[quoted text clipped - 12 lines]
> as soon as one enter the method with the code metioned (it doesn't
> execute a single line).

It sounds as if Jeode and Jbed differ in when they do class name resolution.
As I read the JVM spec, there is a great deal of variability allowed in this
area, so your pseudo-code could legally be rejected at any time between loading
the class /containing/ the code, through to the first time any code actually
/uses/ the ClassNOTSupportedByCDC class (refers to its static members, creates
an instances, etc.).  In your particular case it looks as if Jeode is resolving
the class reference at the point of first use, whereas Jbed is doing so at the
time when the first method that refers to it is entered.  If I'm reading the
spec correctly then both behaviours are legal.

As to ways around it.  The (conceptually) simplest is to use separate code
bases for the two platforms.  Or you may be able to use reflection (I don't
know whether reflection is supported [efficiently] on either/both platform).
Failing that you /may/ be able to make the test condition into a public static
final boolean, in which case the unreachable code elimination /may/ remove (or
make harmless) the reference to ClassNOTSupportedByCDC.

   -- chris
Kid - 29 Jun 2005 11:05 GMT
Chris,
Thanks for the interesting information about the jvm specs!
What surprise me the most is that Jeode and Jbed come from the same
company! (not sure if they're developed by the same company though.).

As I told Mark, I'm hesitating to use reflection because of the point
you're bringing up. Supported? Efficiency?

> you /may/ be able to make the test condition into a public static
> final boolean, in which case the unreachable code elimination /may/ remove (or
> make harmless) the reference to ClassNOTSupportedByCDC.

Not sure if I'm understanding you correctly.
Do you mean that if the test condition is a public static
final boolean, the compiler "optimizes" away the reference in the
resulting byte code? Is this behavior supported by all compilers? I'm
currently using Sun's 1.4-1.5 compilers.
Pretty cool if the compiler works like that!

Regards,
/Kid
Chris Uppal - 29 Jun 2005 12:40 GMT
> As I told Mark, I'm hesitating to use reflection because of the point
> you're bringing up. Supported? Efficiency?

Whether reflection is supported is something that should be defined somewhere;
it's part of the core java definition, but I don't know whether support for it
is optional for the kinds of devices that you are working with.  But it is
either required (so it should damn-well be provided) or it is optional (so it
should damn-well be documented).

As to efficiency, there shouldn't be a great deal of need for efficiency since
(as a matter of normal software engineering) you should be able to ensure that
you only use reflection a handful of times during program execution.  At those
times you use reflection to create an instance of a concrete class which is
either a wrapper for a ClassNOTSupportedByCDC or for a ClassSupportedByCDC, but
which itself is not used via reflection.  That is to say that there would be an
abstract superclass (or interface) that both concrete wrappers inherited from,
but the code that used those objects would not know (or care) which concrete
class was in use.   Of course, your position /now/ might be such that it would
be difficult to retro-fit that kind of pattern into your existing code base.

> > you /may/ be able to make the test condition into a public static
> > final boolean, in which case the unreachable code elimination /may/
[quoted text clipped - 5 lines]
> resulting byte code? Is this behavior supported by all compilers? I'm
> currently using Sun's 1.4-1.5 compilers.

The compiler is /allowed/ to do that -- the definition of how final
int//float/boolean/etc or String fields are represented in compiled code is
designed specifically to allow that kind of optimisation.  The compiler is
/required/ to inline the statically-known value of the final field rather than
generating a field access instruction.  However the compiler is /not/ required
to eliminate any resultant dead code, although it is legal for it to do so.
Incidentally, the only requirement for this inlining of values is that the
field in question is final, and that it is initialised to a compile-time
constant, it doesn't have to be public.

As it happens, the JDK 1.5.0 version of javac does do that optimisation itself,
so the unused classname should not appear in the classfile at all.  I think
there's a good chance that 1.4.x series compilers do the same, but I haven't
checked.

In any case there are several stages where the dead code can be recognised and
eliminated, not just the compilation from Java source to bytecode -- for
instance the JIT could do it, or a classfile compressor might do it -- what's
important (for your purposes) is that the dead code is eliminated before the
Jbed JVM attempts classname resolution.

   -- chris
Kid - 29 Jun 2005 12:58 GMT
> That is to say that there would be an
> abstract superclass (or interface) that both concrete wrappers inherited from,
> but the code that used those objects would not know (or care) which concrete
> class was in use.

I'm trying to solve the problem by having a common superclass and then
each subclass is specialised, e.g. PPC_Jbed, PPC_Jeode, PC_Sun.

Can you recommend a classfile compressor removing "dead code"?

Thanks again Chris for your knowledge and the interesting info.

/Kid
Chris Uppal - 30 Jun 2005 08:59 GMT
> I'm trying to solve the problem by having a common superclass and then
> each subclass is specialised, e.g. PPC_Jbed, PPC_Jeode, PC_Sun.

Sounds sensible to me.

> Can you recommend a classfile compressor removing "dead code"?

'Fraid not.  I've seen lots of classfile mungers of one sort or another in my
wandering around the Web, but I don't use any of them, so I can't recommend
anything.  I should say that my comment about removing dead code in a
compressor was intended as an illustration of what /could/ be done -- I must
admit that I can't remember whether any of the compressors I've glanced over
actually claimed to be able to /do/ it.  Anyway, if you want to look around,
then I suggest that you search for terms like "classfile compressor" "JAR
packer", and "obfuscator" (many obfuscators also feature ways to remove
unneeded stuff from classfiles).

   -- chris


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.