Different compilers = Different byte code?

J

Jaap de Bergen

Hello,

I'm having a very strange problem with a java applet. I couldn't get
any java applet to run in internet explorer (standard 1.1 vm <- very
old). So i went to:

http://java.sun.com/docs/books/tutorial/java/concepts/ClickMeApplets.html

These applets are running fine.

Now i have downloaded the source code of the example applets, compiled
them and put them on my website. And it doesn't run.

I've used exactly the same source code. The only difference is the
compiler. I guess the examples on the above link are compiled with
jdk1.1 and i compile the examples with 1.4.

Is it possible that the compiler is the source of the problem? The
compiled classes differ a couple of bytes in filesize.

I tryed compiling jdk 1.1.8, but that didn't help. Does anybody know a
place where i can download jdk1.1? (it's not on suns archive page)

Cheers!

Jaap
 
M

Matt Humphrey

Jaap de Bergen said:
Hello,

I'm having a very strange problem with a java applet. I couldn't get
any java applet to run in internet explorer (standard 1.1 vm <- very
old). So i went to:

http://java.sun.com/docs/books/tutorial/java/concepts/ClickMeApplets.html

These applets are running fine.

Now i have downloaded the source code of the example applets, compiled
them and put them on my website. And it doesn't run.

I've used exactly the same source code. The only difference is the
compiler. I guess the examples on the above link are compiled with
jdk1.1 and i compile the examples with 1.4.

Is it possible that the compiler is the source of the problem? The
compiled classes differ a couple of bytes in filesize.

I tryed compiling jdk 1.1.8, but that didn't help. Does anybody know a
place where i can download jdk1.1? (it's not on suns archive page)

What message do you get in the Java Console when they fail to run?

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
J

Jaap de Bergen

What message do you get in the Java Console when they fail to run?

I'm getting the following output:
------------------------------------------------------------------------
Microsoft (R) VM for Java, 5.0 Release 5.0.0.3810
==============================================
? help
c wissen
f finalize-methode uitvoeren
g garbage verzamelen
m geheugengebruik
q afsluiten
t thread-lijst
==============================================
Error loading class: MyApplet
java.lang.NoClassDefFoundError
java.lang.ClassNotFoundException: MyApplet
at com/ms/vm/loader/URLClassLoader.loadClass
at com/ms/vm/loader/URLClassLoader.loadClass
at com/ms/applet/AppletPanel.securedClassLoad
at com/ms/applet/AppletPanel.processSentEvent
at com/ms/applet/AppletPanel.processSentEvent
at com/ms/applet/AppletPanel.run
at java/lang/Thread.run
 
M

Matt Humphrey

==============================================
Error loading class: MyApplet
java.lang.NoClassDefFoundError
java.lang.ClassNotFoundException: MyApplet
at com/ms/vm/loader/URLClassLoader.loadClass
at com/ms/vm/loader/URLClassLoader.loadClass
at com/ms/applet/AppletPanel.securedClassLoad
at com/ms/applet/AppletPanel.processSentEvent
at com/ms/applet/AppletPanel.processSentEvent
at com/ms/applet/AppletPanel.run
at java/lang/Thread.run
------------------------------------------------------------------------

The "NoClassDefFoundError" means the JVM in the browser isn't even seeing
your applet. Are you sure you put it in the right place? Is your html
configured correctly? See Roedy's site
http://mindprod.com/jgloss/applet.html to make sure you've correctly
installed your applet.

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
J

Jaap de Bergen

The "NoClassDefFoundError" means the JVM in the browser isn't even seeing
your applet. Are you sure you put it in the right place? Is your html
configured correctly? See Roedy's site
http://mindprod.com/jgloss/applet.html to make sure you've correctly
installed your applet.

I think i've installed/configured it correctly. After a bit of
searching through jbuilder (my IDE) i've discovered a option "Target
VM":
------------------------------------------------------------------------
Target VM
Restricts the class files to work only on a specific VM version.

All Java SDKs Generates the class files to work with versions 1.1 and
all VMs in the Java 2 SDK. When you select this as the target VM, your
class files can be loaded by any VM. If you select this target VM, you
need to enter the following VM Parameter on the Run page of the
Runtime Configurations dialog box in order for the Smart Swap debugger
feature (JBuilder Developer and Enterprise) to work properly:
-Xverify:noneFor more information see "Modifying code while
debugging."

Java 2 SDK, v 1.2 And Later Generates the class files to run only on
VMs in the Java 2 SDK, v 1.2 and later, but won't run on 1.1 VMs. This
is the default.

Java 2 SDK, v 1.3 And Later Generates the class files to run only on
VMs in the Java 2 SDK, v 1.3 and later, but won't run on 1.1 or 1.2
VMs.

Java 2 SDK, v 1.4 And Later Generates the class files to run only on
VMs in the Java 2 SDK, v 1.4 and later, but won't run on 1.1, 1.2, or
1.3 VMs.
------------------------------------------------------------------------

"Java 2 SDK, v 1.2" was selected by default, when i choose "All Java
SDKs" everything goes oke and i can run any applet without any
problems in internet explorer.

I find this really strange, but i'm happy :)

Cheers!

Jaap
 
M

Michael Borgwardt

Jaap said:
I find this really strange, but i'm happy :)

Nothing strange about it. The Java class file format was changed a few times,
and some of the changes lead to incompatibilities with older JVMs.

Sun's javac compiler adresses this with the -target command line option.
 
C

Chris Uppal

Michael said:
Nothing strange about it. The Java class file format was changed a few
times, and some of the changes lead to incompatibilities with older JVMs.

Not that the format actually /did/ change -- just the version numbers. E.g. a
class file produced with target = 1.4, would run perfectly well on a 1.1 JVM if
the version numbers hadn't changed. I think Sun screwed up and confused the
library with the JVM.

-- chris
 
M

Michael Borgwardt

Chris said:
Not that the format actually /did/ change -- just the version numbers.

Are you sure that the introduction of assertions did not require a
true incompatibility?
 
C

Chris Uppal

Michael said:
Not that the [class file] format actually /did/ change -- just the version
numbers.

Are you sure that the introduction of assertions did not require a
true incompatibility?

Hmm, good point. I had completely forgotten about assertions -- I never use
them and have never really thought much about them.

<pause, checks... />

I think it's more what I'd call a library issue: the assertions are compiled
into normal bytecodes in normal classfile format. For instance, code like:

private static void
method1(int i)
{
assert i > 0;
}

is compiled into:

private static method1 (I)V
getstatic Test/$assertionsDisabled Z
ifne 9
iload_0
ifgt 9
new java/lang/AssertionError
dup
invokespecial java/lang/AssertionError/<init> ()V
athrow
9: return

I.e, for those who don't like reading bytecodes (and who does ?):

private static void
method1(int i)
{
if (!$assertionsDisabled && i <= 0)
throw new AssertionError();
}

And there is code in the class's <cinit> that does the equivalent of:

static
{
$assertionsDisabled = !Test.class.desiredAssertionStatus();
}

to initialise the synthetic static field:

static final boolean $assertionsDisabled;

None of the bytecodes are in any way (that I can see) abnormal, and do not
require any co-operation from the JVM to execute properly (turning assertions
/on/ would require co-operation, but that's not a issue for the format of the
class file).

Of course, it's clear that these code snippets wouldn't work against a class
library where java.lang.Class didn't have a desiredAssertionStatus() method, or
where class java.lang.AssertionError didn't exist, so you can't actually /use/
classfiles with assertions in a (vanilla) 1.2 JVM (say). And that is certainly
the practical point that will interest most people -- no question. However,
I'd still call it a library issue, not a problem caused by the classfile format
as such (or by changes to the JVM spec). Indeed, classfiles with assertions
would load perfectly well into an earlier JVM (ignoring the "version" number),
and fail in a perfectly well-defined way as part of the /normal/ correct
operation of valid classfiles that happen refer to non-existent classes, or to
non-existent members of classes.

Admittedly, that's all more interesting than actually very useful ;-) Still,
at least I now know what assertions "really mean".

-- chris
 
A

Andrew Thompson

Not that the format actually /did/ change -- just the version numbers.

Nu-uh. AFAIU the spec for 1.1 was that there
might be extraneous bytes at the end of
a class (not that Sun's compiler ever did it),
but that was tightened down in 1.2+.

Thus a 1.1 class with extraneous bytes at the
end was entirely valid in that context.
 
C

Chris Uppal

Andrew said:
Not that the format actually /did/ change -- just the version numbers.
[...]
Thus a 1.1 class with extraneous bytes at the
end was entirely valid in that context.

Good point.

<mutters>Smartarse<mutters/>

;-)

-- chris
 
A

Andrew Thompson

Andrew said:
Not that the format actually /did/ change -- just the version numbers.
[...]
Thus a 1.1 class with extraneous bytes at the
end was entirely valid in that context.

Good point.

(muses) I wonder if the ability to add
bytes to the end of a file might somehow
add to it's 'compressibility' according to
the .cab format?

I am having trouble figuring why a compiler
would add 'extraneous bytes' in the first place.
...And the 'compiler writers are idiots'
explanation, does not cut it..
<mutters>Smartarse<mutters/>

;-)

LOL..

I was just glad I managed to spot what
must be one of the few errors you
would make ..where I had any chance of
*knowing* you were wrong, at least!

One of the few good things about
'having too much time on your hands',
you get to examine posts *very* carefully. ;)
 
C

Chris Uppal

Andrew said:
(muses) I wonder if the ability to add
bytes to the end of a file might somehow
add to it's 'compressibility' according to
the .cab format?

I can't see it. The extra bytes /have/ to make it compress to a larger size
(under any reasonable assumptions).

Here's a few speculations about why extra bytes might have been allowed:

[charitable speculation 1]
It would allow third parties to add extra data to classfiles that would not
interfere with their use in a vanilla JVM. This would be handy for data that
could not easily/feasibly be added as a custom class attribute in the middle of
the file. E.g. checksums and digital signatures, or -- at the other extreme --
different representations of the class, compiled x86 code, say.

[charitable speculation 2]
It would allow scope for future enhancements to the standard to add new data at
the end of the file without breaking backwards compatibility.

[charitable speculation 3]
It might help with storage/transmission media that didn't naturally handle
arbitrarily-sized content (working in fixed-size chunks, perhaps). E.g. maybe
they were considering trasmitting classfiles as N-byte blocks mixed in with the
video signal for Oak (OK, that's a very /speculative/ speculation).

[uncharitable speculation]
Maybe an early version of the compiler /did/ in fact add garbage at the end of
the classfile. It's pretty obvious that the classfile spec is written to match
what their compilers and JVMs actually did rather than being designed ab initio
(e.g. the padding in tableswitch and lookupswitch, the odd 'count' parameter to
invokeinterface). Idiots or not, that kind of thing can happen -- especially
under time pressure.

Personally, and just for once, I'm more inclined to the charitable
speculations. In fact it's not clear why they removed the feature. Possibly
because [cs1], [cs2], and [cs3] are all in conflict. Or maybe they decided
that the self-delimiting nature of the classfile format was valuable for
something. I can't think of anything really convincing, though.

One of the few good things about
'having too much time on your hands',
you get to examine posts *very* carefully. ;)

And to "touch your inner pedant"...

-- chris
 
A

Andrew Thompson

The extra bytes /have/ to make it compress to a larger size
(under any reasonable assumptions).

What if they contain information for (what
was it you called it) 'pre-training' of the
compression algorithm? After all, nobody
(to my recollection) said they were *blank*
bytes, just 'extraneous'...

Mickey Segal swears the MS .cab files are
smaller than the equivalent .zip's, I thought
(maybe) they were doing some clever things
for compression. As people point out though,
zip format is not that wasteful over some of
the best algorithms, so how could MS pull it
off in a .cab file?

Pre-training using information stored in those
extraneous bytes might be a way to explain it..
+ (and this is an important point) if the
standard 'jar' format is used on the *same*
class files, whith the relatively uncompressible
extraneous bytes that do not do anything useful
for the Sun VM's.. those together might add up
to the difference..

Of course I am assuming two things..
a) you cannot make a .cab file from classes
without the extraneous bytes, or if you can,
that the MSVM made special provision to cater for it..
b) ..and the difference in that case is either
much smaller or completely gone.

OK.. I think I've finished musing on obsolete
VM's.. time to get back to writing applet's
that will work in all 1.1+ VM's...

....D'oh!
 
C

Chris Uppal

Andrew said:
What if they contain information for (what
was it you called it) 'pre-training' of the
compression algorithm?

Normally a (LZ-style) compressor starts in a "blank" state, and it only starts
to achieve compression once it has seen enough input data to recognise
exploitable repetitions. So it can't provide any compression until at least
the second time it sees, say, the string "java/lang/Object". The idea of
pre-training is that if you warm up the compressor by giving it some typical
text to process before the real data, then it will hit the ground running as
far as its real work is concerned. The problem is that the training data has
to be known to both the compressor and decompressor in advance; if not then
you'll have to transmit that data /as well/ and there'll be a nett increase in
the size of the transmission. The exception to that is if you are sending
several (independently) compressed files which have "similar" contents. In
that case, it might be worthwhile to send the training data /once/, followed by
the compressed (with identical training) data for the N real files.

E.g. a modified JAR file format might allow a "TRAINING.DAT" file somewhere at
the start of the JAR (just after the manifest, say) which would be used to
pre-train all the [de]compressors used for the contained .class files. Of
course, that would not then be a valid ZIP format file, since it would be using
non-standard compression. (And, as I pointed out in the post you are
referring to, it doesn't seem to be a worthwhile technique for .class files --
the gains are too small to justify the effort.)

Anyway, the point of this is that it wouldn't help to add data to each of the
classfiles. Of course, you /could/ split up the training data and share it out
amongst several of them, but that seems a little, um, perverse ;-)

Mickey Segal swears the MS .cab files are
smaller than the equivalent .zip's, I thought
(maybe) they were doing some clever things
for compression. As people point out though,
zip format is not that wasteful over some of
the best algorithms, so how could MS pull it
off in a .cab file?

I know /very/ little about how CAB files work. The only description I've seen
suggests that MS are using a compression scheme (LZX) that is algorithmically
similar to the one used in ZIP files, but which has a significantly tighter
(and /much/ more intricate) way of encoding the repetitions that it has
discovered. I get the impression too that the encoding can be tuned
(statically) to include something analogous to training (CAB format is not
intended to be general-purpose, so MS can use knowledge of what the typical CAB
file will contain, and can choose the details of the encoding appropriately).
But, to be honest, I don't really understand the description, so I could easily
be wrong...

The bottom line seems to be that CAB just has a "better" compressor than ZIP
(at least for some sorts of files). Which is not unexpected -- it was designed
about a decade later, and can assume larger memories and faster machines, so it
/ought/ to be better even without any extra cleverness.

Pre-training using information stored in those
extraneous bytes might be a way to explain it..
+ (and this is an important point) if the
standard 'jar' format is used on the *same*
class files, whith the relatively uncompressible
extraneous bytes that do not do anything useful
for the Sun VM's.. those together might add up
to the difference..

So Sun designed their format so that M$ could compress it better than they
themselves could ? Unlikely, I fear ;-)

OK.. I think I've finished musing on obsolete
VM's.. time to get back to writing applet's
that will work in all 1.1+ VM's...

An unusual and challenging vocation you have chosen, Mr Thompson. You might
find digging ditches more pleasant...

-- chris
 
A

Andrew Thompson

The bottom line seems to be that CAB just has a "better" compressor than ZIP
(at least for some sorts of files). Which is not unexpected -- it was designed
about a decade later, and can assume larger memories and faster machines, so it
/ought/ to be better even without any extra cleverness.

I'll take that as the 'reasonable explanation'
that I alway lacked. Thanks.
...
An unusual and challenging vocation you have chosen, Mr Thompson. You might
find digging ditches more pleasant...

Oh (chuckles) I'm just working on a suite
of tools that will ensure that a minimum
Java version is installed for Java applets
and that showDocument() can be made to either
work reliably, or fail and make a lot of noise,
...then there are also some tweaks to adjust
page 'focus'.

Then it is straight back into the 1.4+
applets, screensavers, server side magic.. :)
 

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

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top