Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"Small" Program Challenge.

77 views
Skip to first unread message

Daniel Pitts

unread,
Jun 13, 2012, 4:45:18 PM6/13/12
to
I saw a challenge Roedy posted on cljh, and I thought I might have a
slightly more interesting one.

Write a Java program which outputs "Hello World" followed by a new line
(and nothing else).

Now, do it using as few characters in the .java source code as possible.

I've got mine down to 61 characters. See if you can match that.

Daniel Pitts

unread,
Jun 13, 2012, 4:52:31 PM6/13/12
to
Hint, the following is 82 characters, if you remove line wrapping. Where
do I trim the 21 characters?

"class M{public static void main(String[]args){System.out.println("Hello
World");}}"
Message has been deleted
Message has been deleted

Daniel Pitts

unread,
Jun 13, 2012, 7:17:01 PM6/13/12
to
On 6/13/12 2:06 PM, Stefan Ram wrote:
> Daniel Pitts<newsgrou...@virtualinfinity.net> writes:
>>> Write a Java program which outputs "Hello World" followed by a new line
> (...)
>> "class M{public static void main(String[]args){System.out.println("Hello World");}}"
>
> �System.out.println("Hello World");� does not output "Hello
> World" followed by a new line, but "Hello World" followed by
> the line separator string. The line separator string is
> defined by the system property line.separator, and is not
> necessarily a single newline character ('\n').
>
I didn't say a "new line" character. However, print("Hello World\n") is
the same length. My intent was line separator, however if you choose to
interpret it the other way, there is no benefit or penalty.

Daniel Pitts

unread,
Jun 13, 2012, 7:19:35 PM6/13/12
to
On 6/13/12 2:29 PM, Stefan Ram wrote:
> Daniel Pitts<newsgrou...@virtualinfinity.net> writes:
>> Where do I trim the 21 characters?
>
> You can trim the »args« to »a«.
Ah, yes. That was just habit on my part.

> Possibly, some earlier JDKs allowed
> omission of the main method, but a recent JDK seems to require it.
>

The JDK doesn't require anything of a class. java on the other hand
goes through a specific sequence when asked to "run" a Java program.

My smallest program is still 61 characters long, the example I posted,
after replacing args with a, is 79.

Daniel Pitts

unread,
Jun 13, 2012, 7:24:37 PM6/13/12
to
On 6/13/12 4:19 PM, Daniel Pitts wrote:
> On 6/13/12 2:29 PM, Stefan Ram wrote:
>> Daniel Pitts<newsgrou...@virtualinfinity.net> writes:
>>> Where do I trim the 21 characters?
>>
>> You can trim the �args� to �a�.
> Ah, yes. That was just habit on my part.
>
>> Possibly, some earlier JDKs allowed
>> omission of the main method, but a recent JDK seems to require it.
>>
>
> The JDK doesn't require anything of a class. java on the other hand goes
> through a specific sequence when asked to "run" a Java program.
Ah, although now I see reports that Java 7 does some validation before
some of that sequence. So, my 61 character source compiles fine, but
won't run on Java 7.

I wonder why they bothered.

glen herrmannsfeldt

unread,
Jun 13, 2012, 8:16:13 PM6/13/12
to
Daniel Pitts <newsgrou...@virtualinfinity.net> wrote:

(snip)
> I didn't say a "new line" character. However, print("Hello World\n") is
> the same length. My intent was line separator, however if you choose to
> interpret it the other way, there is no benefit or penalty.

Note that there is no requirement that the host system even use
a newline character. There are systems that keep track of lines
by length.

Now, the C tradition of using '\n' as a line terminator, even
on systems that don't store files that way, isn't completely gone
in Java. Writing a "\n" will likely generate a new line even on
systems that don't use a newline character.

-- glen

markspace

unread,
Jun 13, 2012, 8:40:17 PM6/13/12
to
This is a good one, although the options for really trimming things down
in surprising ways is absent in Java.

Another good one is to write a Java program that prints its own source
text. No fair using an external file, of course.


javax.swing.JSnarker

unread,
Jun 13, 2012, 9:28:27 PM6/13/12
to
class X{static{System.out.println("Hello World");for(;;);}}

is 59 characters.

Hey, you didn't say it has to actually *terminate*! ;)

--
public final class JSnarker
extends JComponent
A JSnarker is an NNTP-aware component that asynchronously provides
snarky output when the Ego.needsPuncturing() event is fired in cljp.

Roedy Green

unread,
Jun 13, 2012, 11:52:04 PM6/13/12
to
On Wed, 13 Jun 2012 13:45:18 -0700, Daniel Pitts
<newsgrou...@virtualinfinity.net> wrote, quoted or indirectly
quoted someone who said :

>
>I've got mine down to 61 characters. See if you can match that.

here's the obvious solution at 88 chars:

public class C{public static void main(String[]
a){System.out.println("Hello World");}}

--
Roedy Green Canadian Mind Products
http://mindprod.com
Controlling complexity is the essence of computer programming.
~ Brian W. Kernighan 1942-01-01
.

Paul Cager

unread,
Jun 14, 2012, 5:32:46 AM6/14/12
to
On Jun 13, 9:45 pm, Daniel Pitts
You may also find some of the challenges on http://codegolf.stackexchange.com/
interesting.

Bent C Dalager

unread,
Jun 14, 2012, 7:29:32 AM6/14/12
to
On 2012-06-13, Daniel Pitts <newsgrou...@virtualinfinity.net> wrote:
> I saw a challenge Roedy posted on cljh, and I thought I might have a
> slightly more interesting one.
>
> Write a Java program which outputs "Hello World" followed by a new line
> (and nothing else).
>
> Now, do it using as few characters in the .java source code as possible.

How much are you permitted to offload to the launcher?

Trivial example of offloading:

class A{public static void main(String[] a){System.out.print(a[0]);}}
(69 chars)

with launch instructions:

run like this (bash command line example shown, other launch
environments will have other ways of expressing the newline)

$ java A "Hello World
> "
$


And how much can you offload to a hypothetical "library" function that
just happens to do exactly what you want?

class B{public static void main(String[] a){L.f();}}
(52 chars)

Cheers,

Bent.
--
Bent Dalager - b...@pvv.org - http://www.pvv.org/~bcd
powered by emacs

Hiram Hunt

unread,
Jun 14, 2012, 8:23:59 AM6/14/12
to

"Roedy Green" <see_w...@mindprod.com.invalid> wrote in message
news:jqnit7pv9phoig3t2...@4ax.com...
> On Wed, 13 Jun 2012 13:45:18 -0700, Daniel Pitts
> <newsgrou...@virtualinfinity.net> wrote, quoted or indirectly
> quoted someone who said :
>
>>
>>I've got mine down to 61 characters. See if you can match that.
>
> here's the obvious solution at 88 chars:
>
> public class C{public static void main(String[]
> a){System.out.println("Hello World");}}

No need for public on class.

-- Hiram Hunt (hira...@verizon.net)


Hiram Hunt

unread,
Jun 14, 2012, 8:30:09 AM6/14/12
to

"Hiram Hunt" <hira...@verizon.net> wrote in message
news:4fd9d7d1$0$1727$c3e8da3$aae7...@news.astraweb.com...
Sorry, I think I missed your point that this was just the obvious
solution. Other posts are already public-less on class.

-- Hiram Hunt (hira...@verizon.net)


Message has been deleted
Message has been deleted

Daniel Pitts

unread,
Jun 14, 2012, 3:50:29 PM6/14/12
to
On 6/14/12 11:04 AM, Stefan Ram wrote:
> Daniel Pitts<newsgrou...@virtualinfinity.net> writes:
>> I've got mine down to 61 characters. See if you can match that.
>
> Here is a new variant of the above challenge:
>
> Write a java program (source code) with less than 4000
> characters and a java command line with less than 1000
> characters that writes »Hello World« followed by a newline
> character and nothing else, but does so in a somewhat
> surprising or unusual way.
>
> My entry:
>
> public class Main
> { public static void main( final java.lang.String[] args )
> { System.out.println(); System.out.print( '\n' ); }}
>
> java -Dline.separator="Hello World" Main
>

A slightly obfuscated program which illustrates a few surprising things.

public class Hello {
static Object left = "Top", right = "Bottom";
static Object top = "Left";
static Object bottom = "Right";

public static void main(String[] args) throws Exception {
for (int i = 0; i < 2; ++i) {
s.out.print(new Hello());
y(left, right, top, bottom);
}
}

public String toString() {
try {
top = "value";
bottom = "count";
return "enumeration" + top + bottom;
} finally {
return getClass().getName();
}
}

static <T extends java.lang.reflect.AccessibleObject> T t(T t) {
t.setAccessible(true); return t;}

static <T> void y(T l, T r, T... os) throws Exception {
for (Object o : os) {
x(l, o).set(l, x(l, o).get(r));
}
}

private static java.lang.reflect.Field x(Object l, Object o) throws
NoSuchFieldException {
return t(l.getClass().getDeclaredField(o.toString()));
}

{
left = toString();
right = " W" + b + 'r' + a + "d\n";
}

static Object a = "l";
static Object b = "o";
static System s;
}

Leif Roar Moldskred

unread,
Jun 14, 2012, 4:49:01 PM6/14/12
to
Stefan Ram <r...@zedat.fu-berlin.de> wrote:
> Daniel Pitts <newsgrou...@virtualinfinity.net> writes:
>>I've got mine down to 61 characters. See if you can match that.
>
> Here is a new variant of the above challenge:
>
> Write a java program (source code) with less than 4000
> characters and a java command line with less than 1000
> characters that writes »Hello World« followed by a newline
> character and nothing else, but does so in a somewhat
> surprising or unusual way.
>
> My entry:
>
> public class Main
> { public static void main( final java.lang.String[] args )
> { System.out.println(); System.out.print( '\n' ); }}
>
> java -Dline.separator="Hello World" Main
>

Well, mine doesn't have the same compactness, but here goes.
Run with plain "java HW":


import java.io.PrintStream;
import java.math.BigInteger;

public class HW {
static boolean debug = false;
final static Long l_44 = 044L;

public static void main(String[] args) {
if( debug&doDebugLogging() ) {
System.out.println( "World hello!" );
}

long ll1 = 42068934;
long ll2 = 12834282;

System.out.print(ll1++-ll2);
System.out.print( " " );
System.out.println(ll1+++ll2);
}

private static boolean doDebugLogging( ) {
System.setOut( new PrintStream( System.out ) {
public void print( long l ) {
print( BigInteger.valueOf( l ).toString(l_44.intValue()) );
}
public void print( String s ) {
super.print( s.toUpperCase().charAt(0) + s.substring(1) );
} });
return false;
}
}

--
Leif Roar Moldskred

Gene Wirchenko

unread,
Jun 14, 2012, 5:56:09 PM6/14/12
to
On 14 Jun 2012 18:04:46 GMT, r...@zedat.fu-berlin.de (Stefan Ram)
wrote:

>Daniel Pitts <newsgrou...@virtualinfinity.net> writes:
>>I've got mine down to 61 characters. See if you can match that.
>
> Here is a new variant of the above challenge:
>
> Write a java program (source code) with less than 4000
> characters and a java command line with less than 1000
> characters that writes »Hello World« followed by a newline
> character and nothing else, but does so in a somewhat
> surprising or unusual way.
>
> My entry:
>
>public class Main
>{ public static void main( final java.lang.String[] args )
> { System.out.println(); System.out.print( '\n' ); }}
>
>java -Dline.separator="Hello World" Main

The IOCCC (International Obfuscated C Code Contest) has been
running yearly for twenty years. Is someone trying to start an IOJJJ
(International Obfuscated Java Jungle of Junk?)?

Sincerely,

Gene Wirchenko

Daniel Pitts

unread,
Jun 14, 2012, 8:02:22 PM6/14/12
to
On 6/14/12 11:04 AM, Stefan Ram wrote:
> Daniel Pitts<newsgrou...@virtualinfinity.net> writes:
>> I've got mine down to 61 characters. See if you can match that.
>
> Here is a new variant of the above challenge:
>
> Write a java program (source code) with less than 4000
> characters and a java command line with less than 1000
> characters that writes »Hello World« followed by a newline
> character and nothing else, but does so in a somewhat
> surprising or unusual way.
>
> My entry:
>
> public class Main
> { public static void main( final java.lang.String[] args )
> { System.out.println(); System.out.print( '\n' ); }}
>
> java -Dline.separator="Hello World" Main
>
Another lesson: Exceptions, and the deprecated (and highly dangerous)
Thread.stop(Throwable) method.

import java.awt.EventQueue;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;

public class Hello extends Exception {
public static void main(String[] args) throws Exception {
Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
e.printStackTrace(System.out);
}
});
final Thread thread = Thread.currentThread();
EventQueue.invokeAndWait(new Runnable() {
public void run() {
thread.stop(new Hello());
}
});
}

public void printStackTrace(PrintStream s) {
s.print("Hello World");
}
}

Daniel Pitts

unread,
Jun 14, 2012, 8:09:07 PM6/14/12
to
On 6/14/12 11:04 AM, Stefan Ram wrote:
> Daniel Pitts<newsgrou...@virtualinfinity.net> writes:
>> I've got mine down to 61 characters. See if you can match that.
>
> Here is a new variant of the above challenge:
>
> Write a java program (source code) with less than 4000
> characters and a java command line with less than 1000
> characters that writes »Hello World« followed by a newline
> character and nothing else, but does so in a somewhat
> surprising or unusual way.
>
> My entry:
>
> public class Main
> { public static void main( final java.lang.String[] args )
> { System.out.println(); System.out.print( '\n' ); }}
>
> java -Dline.separator="Hello World" Main
>
Any one more:
enum Hello{Hello,World;public static void
main(String[]a){System.out.println(String.valueOf(java.util.Arrays.asList(values())).replaceAll("\\p{Punct}",""));}}

Kevin McMurtrie

unread,
Jun 16, 2012, 1:13:38 AM6/16/12
to
In article <zZ6Cr.4514$v14...@newsfe06.iad>,
Without putting "Hello World" in the environment or using assembly:

class A{static{System.out.println("Hello World");System.exit(0);}}
--
I will not see posts from Google because I must filter them as spam

Daniel Pitts

unread,
Jun 16, 2012, 3:11:34 PM6/16/12
to
On 6/15/12 10:13 PM, Kevin McMurtrie wrote:
> In article<zZ6Cr.4514$v14...@newsfe06.iad>,
> Daniel Pitts<newsgrou...@virtualinfinity.net> wrote:
>
>> I saw a challenge Roedy posted on cljh, and I thought I might have a
>> slightly more interesting one.
>>
>> Write a Java program which outputs "Hello World" followed by a new line
>> (and nothing else).
>>
>> Now, do it using as few characters in the .java source code as possible.
>>
>> I've got mine down to 61 characters. See if you can match that.
>
> Without putting "Hello World" in the environment or using assembly:
>
> class A{static{System.out.println("Hello World");System.exit(0);}}
Note, that doesn't work on Java 7.

You can get rid of the static with a few other tricks. You can also trim
the usage of System. to something shorter.

Wanja Gayk

unread,
Jun 17, 2012, 9:22:18 AM6/17/12
to
In article <zZ6Cr.4514$v14...@newsfe06.iad>,
newsgrou...@virtualinfinity.net says...

> Write a Java program which outputs "Hello World" followed by a new
> line (and nothing else).
>
> Now, do it using as few characters in the .java source code as possible.
>
> I've got mine down to 61 characters. See if you can match that.

Yoda says:
claim everything you can, prove you must.

Gruß,
-Wanja-

--
..Alesi's problem was that the back of the car was jumping up and down
dangerously - and I can assure you from having been teammate to
Jean Alesi and knowing what kind of cars that he can pull up with,
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

--- Posted via news://freenews.netfront.net/ - Complaints to ne...@netfront.net ---

Daniel Pitts

unread,
Jun 17, 2012, 6:24:23 PM6/17/12
to
On 6/17/12 6:22 AM, Wanja Gayk wrote:
> In article<zZ6Cr.4514$v14...@newsfe06.iad>,
> newsgrou...@virtualinfinity.net says...
>
>> Write a Java program which outputs "Hello World" followed by a new
>> line (and nothing else).
>>
>> Now, do it using as few characters in the .java source code as possible.
>>
>> I've got mine down to 61 characters. See if you can match that.
>
> Yoda says:
> claim everything you can, prove you must.
I will post my solution, once everyone else has had a chance to attempt
the problem.


javax.swing.JSnarker

unread,
Jun 17, 2012, 6:25:38 PM6/17/12
to
"Everyone else"? As in, all seven billion of us?!

Arne Vajhøj

unread,
Jun 17, 2012, 8:31:10 PM6/17/12
to
On 6/17/2012 6:25 PM, javax.swing.JSnarker wrote:
> On 17/06/2012 6:24 PM, Daniel Pitts wrote:
>> On 6/17/12 6:22 AM, Wanja Gayk wrote:
>>> In article<zZ6Cr.4514$v14...@newsfe06.iad>,
>>> newsgrou...@virtualinfinity.net says...
>>>
>>>> Write a Java program which outputs "Hello World" followed by a new
>>>> line (and nothing else).
>>>>
>>>> Now, do it using as few characters in the .java source code as
>>>> possible.
>>>>
>>>> I've got mine down to 61 characters. See if you can match that.
>>>
>>> Yoda says:
>>> claim everything you can, prove you must.
>> I will post my solution, once everyone else has had a chance to attempt
>> the problem.
>
> "Everyone else"? As in, all seven billion of us?!

In theory if he wait X days, then a good chunk of those 7 B would
have had a chance to go on the internet, read and reply.

In practice it will be a very small subset, but ...

Arne



javax.swing.JSnarker

unread,
Jun 17, 2012, 8:55:06 PM6/17/12
to
The problem is, he said "everyone else" rather than "almost everyone
else". So "a good chunk" won't cut it.

Arne Vajhøj

unread,
Jun 17, 2012, 9:17:02 PM6/17/12
to
On 6/13/2012 11:52 PM, Roedy Green wrote:
> On Wed, 13 Jun 2012 13:45:18 -0700, Daniel Pitts
> <newsgrou...@virtualinfinity.net> wrote, quoted or indirectly
> quoted someone who said :
>
>>
>> I've got mine down to 61 characters. See if you can match that.
>
> here's the obvious solution at 88 chars:
>
> public class C{public static void main(String[]
> a){System.out.println("Hello World");}}

Daniel already posted the obvious solution.

Arne




Daniel Pitts

unread,
Jun 17, 2012, 11:40:23 PM6/17/12
to
On 6/17/12 5:55 PM, javax.swing.JSnarker wrote:
> On 17/06/2012 8:31 PM, Arne Vajhøj wrote:
>> On 6/17/2012 6:25 PM, javax.swing.JSnarker wrote:
>>> On 17/06/2012 6:24 PM, Daniel Pitts wrote:
>>>> I will post my solution, once everyone else has had a chance to attempt
>>>> the problem.
>>>
>>> "Everyone else"? As in, all seven billion of us?!
>>
>> In theory if he wait X days, then a good chunk of those 7 B would
>> have had a chance to go on the internet, read and reply.
>>
>> In practice it will be a very small subset, but ...
>
> The problem is, he said "everyone else" rather than "almost everyone
> else". So "a good chunk" won't cut it.
>
Well, while you took me literally, my intent was to wait "for enough
people that wished to contribute to this conversation to do so."

Or for someone to find the same (or better) solution.

I suppose that a date deadline would have been more appropriate.

In any case, I think the other challenge was more interesting. My
solution to the "shortest" source is 60 characters long. The first two
lines are simply a ruler, and not part of the source code.

1 2 3 4 4 6
123456789012345678901234567890123456789012345678901234567890
enum H{W;System s;{s.out.println("Hello World");s.exit(0);}}

You would compile whatever file H was in (it needn't be in H.java since
it isn't public). Then execute with "java H"

Note, this no longer works in Java 7. It appears a method with the
signature "public static void main(String[])" is now required, where it
could have been omitted in the past (as in my example).

javax.swing.JSnarker

unread,
Jun 17, 2012, 11:43:23 PM6/17/12
to
On 17/06/2012 11:40 PM, Daniel Pitts wrote:
> In any case, I think the other challenge was more interesting. My
> solution to the "shortest" source is 60 characters long. The first two
> lines are simply a ruler, and not part of the source code.
>
> 1 2 3 4 4 6
> 123456789012345678901234567890123456789012345678901234567890
> enum H{W;System s;{s.out.println("Hello World");s.exit(0);}}
>
> You would compile whatever file H was in (it needn't be in H.java since
> it isn't public). Then execute with "java H"
>
> Note, this no longer works in Java 7. It appears a method with the
> signature "public static void main(String[])" is now required, where it
> could have been omitted in the past (as in my example).

That's pretty silly.

Of course, if you don't require it to terminate, only to not print
anything else after "Hello World", you can use

> 1 2 3 4 5
> 123456789012345678901234567890123456789012345678901234
> enum H{W;{System.out.println("Hello World");for(;;);}}

;)

Lew

unread,
Jun 18, 2012, 12:25:39 AM6/18/12
to
You aren't supposed to rely on a bug.

The JLS 3rd ed., which covers Java 5 and Java 6, says,
"A Java virtual machine starts up by loading a specified class and then
invoking the method main in this specified class."
<http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html>

and
"A Java virtual machine starts execution by invoking the method main of some
specified class, passing it a single argument, which is an array of strings."
<http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#44444>

If you got it to start a different way, that was unreliable behavior and not
actually correct.

Since your proposed solution is in contravention of the Java spec, it cannot
be accepted.

Java 7 might not be the only version it fails on. How many Java systems did
you try it on? IBM's? Oracle mainframe? HP? Oracle on Solaris? IBM on Z
System? Can you be sure that Oracle's Java 6u34 will support this
non-compliant bug?

You simply cannot legitimately propose a non-compliant "solution".

--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

javax.swing.JSnarker

unread,
Jun 18, 2012, 12:45:34 AM6/18/12
to
On 18/06/2012 12:25 AM, Lew wrote:
> You aren't supposed to rely on a bug.

It's not a bug.

> The JLS 3rd ed., which covers Java 5 and Java 6, says,
> "A Java virtual machine starts up by loading a specified class and then
> invoking the method main in this specified class."

Exactly. It loads the specified class, as part of which that class's
static initializer runs. And if it's an enum, the enum elements'
initializers run too.

If one of those calls System.exit(0) you could argue, theoretically,
that there's an ambiguity in what the spec says should be the behavior.
On the one hand, System.exit(0) should terminate the running VM instance
when invoked. On the other hand, that precludes "and then invoking the
method main in this specified class".

However, the observed behavior seems to be out of spec. The main
method's absence should prompt an error upon the attempt to invoke it,
and did. The error being generated before the main method should be
being invoked is dissimilar from any other JVM behavior. For example, if
you create code that attempts to invoke Foo.quux() by reflection, and
there's no quux static method in class Foo, there won't be any error
until the reflection attempt, which will throw an exception when it occurs.

More generally, "and then invoking the method main" can mean one of two
things, given that main itself is static: the call to main is statically
compiled in, in which case javac should complain when compiling the call
site, or the call to main is reflective, in which case the error should
not occur until runtime and should not occur until the running code
reaches the location of the reflective invocation. We're now seeing an
error later than compile time and earlier than the running code reaches
the location of the reflective invocation, which behavior is
inconsistent with *each* static-method call semantic.

Daniel Pitts

unread,
Jun 18, 2012, 12:04:15 PM6/18/12
to
My program wasn't a bug, it relied on loading the specified class, which
has the (documented) side-effect of initializing the class, which causes
the initializers to run.
>
> and
> "A Java virtual machine starts execution by invoking the method main of
> some specified class, passing it a single argument, which is an array of
> strings."
> <http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#44444>
>
> If you got it to start a different way, that was unreliable behavior and
> not actually correct.
The wording in the 3rd edition is different enough to explain the
difference in behavior, and so Java 6 in fact has the required behavior
of loading the class. Java 7 doesn't require the class be loaded before
invoking the method.
>
> Since your proposed solution is in contravention of the Java spec, it
> cannot be accepted.
For Java 7, I agree. Java 6 it meets the spec.
>
> Java 7 might not be the only version it fails on. How many Java systems
> did you try it on? IBM's? Oracle mainframe? HP? Oracle on Solaris? IBM
> on Z System? Can you be sure that Oracle's Java 6u34 will support this
> non-compliant bug?
Those wouldn't be compliant to JLS 2nd edition then.
>
> You simply cannot legitimately propose a non-compliant "solution".
>
The idea of this "Challenge" was to think outside the box. If it works,
its a solution.

javax.swing.JSnarker

unread,
Jun 18, 2012, 1:09:25 PM6/18/12
to
On 18/06/2012 12:04 PM, Daniel Pitts wrote:
> The wording in the 3rd edition is different enough to explain the
> difference in behavior, and so Java 6 in fact has the required behavior
> of loading the class. Java 7 doesn't require the class be loaded before
> invoking the method.

Sounds like a bug in the spec, to me. How can invoking a method *ever*
not require the class containing that method be loaded first?

markspace

unread,
Jun 18, 2012, 2:06:59 PM6/18/12
to
On 6/18/2012 10:09 AM, javax.swing.JSnarker wrote:
> On 18/06/2012 12:04 PM, Daniel Pitts wrote:
>> The wording in the 3rd edition is different enough to explain the
>> difference in behavior, and so Java 6 in fact has the required behavior
>> of loading the class. Java 7 doesn't require the class be loaded before
>> invoking the method.
>
> Sounds like a bug in the spec, to me. How can invoking a method *ever*
> not require the class containing that method be loaded first?
>


It's just the order that things are done by default.

Before the code was:

1. Load class with initialization.
2. Run 'main' method.

Now, they do the special step of loading without initialization:

1. Load class without initialization.
2. Verify 'main' method, throw error if not present
3. Initialize class
4. Run 'main' method.

You can see how the new method takes more effort.



javax.swing.JSnarker

unread,
Jun 18, 2012, 2:46:11 PM6/18/12
to
On 18/06/2012 2:06 PM, markspace wrote:
> Before the code was:
>
> 1. Load class with initialization.
> 2. Run 'main' method.
>
> Now, they do the special step of loading without initialization:
>
> 1. Load class without initialization.
> 2. Verify 'main' method, throw error if not present
> 3. Initialize class
> 4. Run 'main' method.
>
> You can see how the new method takes more effort.

What was the purpose of such a change? It now is a special case
dissimilar to all other instances of JVM classloading.

Lew

unread,
Jun 18, 2012, 3:44:28 PM6/18/12
to
Not true.

> > and
> > "A Java virtual machine starts execution by invoking the method main of
> > some specified class, passing it a single argument, which is an array of
> > strings."
> > <http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#44444>
> >
> > If you got it to start a different way, that was unreliable behavior and
> > not actually correct.
> The wording in the 3rd edition is different enough to explain the

How, exactly?

> difference in behavior, and so Java 6 in fact has the required behavior
> of loading the class. Java 7 doesn't require the class be loaded before
> invoking the method.

Java never required initialization upon load, and in fact was very specific about
the circumstances under which a class initializes.

<http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#12.4.1>
"A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

- T is a class and an instance of T is created.
- T is a class and a static method declared by T is invoked.
- A static field declared by T is assigned.
- A static field declared by T is used and the field is not a constant variable (§4.12.4).
- T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.

Invocation of certain reflective methods in class Class and in package java.lang.reflect also
causes class or interface initialization. A class or interface will not be initialized under any
other circumstance."

You are saying that the first case applies, an instance is created because of
the third case, a static field is assigned. But that assignment shouldn't happen
yet because nothing has invoked the class legally, i.e., the sequence to invoke
'main()' didn't happen. It is, in fact, the invocation of 'main()' that is supposed to
trigger the initialization.

Historically Sun's JVMs have had bugs in this area, by their own admission.

I read the JLS 3rd edition as not allowing the behavior you claim as a solution.
There has been no change in the language regarding how a JVM starts.

So if the trick violates Java 7, and the language hasn't changed, it must also violate
Java 6, and that it worked was a bug.

Perhaps if you could quote the exact differences in wording to which you refer?

--
Lew

Lew

unread,
Jun 18, 2012, 3:47:50 PM6/18/12
to
On Sunday, June 17, 2012 9:45:34 PM UTC-7, javax.swing.JSnarker wrote:
> On 18/06/2012 12:25 AM, Lew wrote:
> > You aren't supposed to rely on a bug.
>
> It's not a bug.
>
> > The JLS 3rd ed., which covers Java 5 and Java 6, says,
> > "A Java virtual machine starts up by loading a specified class and then
> > invoking the method main in this specified class."
>
> Exactly. It loads the specified class, as part of which that class's
> static initializer runs. And if it's an enum, the enum elements'
> initializers run too.

Loading does not imply initialization, and in fact cannot.

The JVM is forbidden to initialize a class except under specific
circumstances, a
On Sunday, June 17, 2012 9:45:34 PM UTC-7, javax.swing.JSnarker wrote:
> On 18/06/2012 12:25 AM, Lew wrote:
> > You aren't supposed to rely on a bug.
>
> It's not a bug.
>
> > The JLS 3rd ed., which covers Java 5 and Java 6, says,
> > "A Java virtual machine starts up by loading a specified class and then
> > invoking the method main in this specified class."
>
> Exactly. It loads the specified class, as part of which that class's
> static initializer runs. And if it's an enum, the enum elements'
> initializers run too.

Not true. Loading does not imply initialization, and in fact is forbidden to.

The initializers only run under specific circumstances, separately from
loading.

I have cited the relevant JLS sections.

> If one of those calls System.exit(0) you could argue, theoretically,
> that there's an ambiguity in what the spec says should be the behavior.
> On the one hand, System.exit(0) should terminate the running VM instance
> when invoked. On the other hand, that precludes "and then invoking the
> method main in this specified class".

False premise, unreliable conclusion. Loading does not imply initialization.

> However, the observed behavior seems to be out of spec. The main
> method's absence should prompt an error upon the attempt to invoke it,

Indeed.

--
Lew

javax.swing.JSnarker

unread,
Jun 18, 2012, 3:57:53 PM6/18/12
to
On 18/06/2012 3:47 PM, Lew wrote:
> Loading does not imply initialization, and in fact cannot.

Wrong. Loading and initialization go hand-in-hand.

> The JVM is forbidden to initialize a class except under specific
> circumstances, a

What?

>> Exactly. It loads the specified class, as part of which that class's
>> static initializer runs. And if it's an enum, the enum elements'
>> initializers run too.
>
> Not true. Loading does not imply initialization, and in fact is forbidden to.

Wrong. Loading and initialization go hand-in-hand.

> The initializers only run under specific circumstances, separately from
> loading.
>
> I have cited the relevant JLS sections.

You haven't cited anything except my own post, and your quotation of
*that* was a jumbled mess with some sections repeated for some reason.

> False premise, unreliable conclusion.

On your part, Lew.

> Loading does not imply initialization.

Wrong. Loading and initialization go hand-in-hand.

>> However, the observed behavior seems to be out of spec. The main
>> method's absence should prompt an error upon the attempt to invoke it,
>
> Indeed.

And not before.

When invoking a static method of a non-loaded class, the standard
procedure always has been:

Load the class.
Initialize the class.
Invoke the method.

In particular, the spec requires that in this:

class A {
static int x;

static { x = 100; }

static int foo () { return x; }
}

a call to A.foo() should return 100, not 0. If it can attempt to invoke
foo before the static initializer has executed that would be violated.

On the other hand, it complaining that a reflective call to A.bar()
can't be resolved sooner than the loading and initializing of A as part
of trying to resolve bar is equally anomalous. If it hasn't loaded and
initialized A yet, how can it be sure whether or not it has a method
bar? On the other hand, if it's a non-reflective call the code calling
bar won't even compile.

javax.swing.JSnarker

unread,
Jun 18, 2012, 4:01:41 PM6/18/12
to
On 18/06/2012 3:44 PM, Lew wrote:
> "A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
>
> - T is a class and a static method declared by T is invoked.

This is the case that seems to be applicable here. It should not be
erroring out trying to invoke main until after initialization, because
the initialization must occur immediately *before* the invocation
attempt (since it must have occurred if that attempt succeeds or again
the spec is violated).

> You are saying that the first case applies, an instance is created because of
> the third case, a static field is assigned. But that assignment shouldn't happen
> yet because nothing has invoked the class legally, i.e., the sequence to invoke
> 'main()' didn't happen. It is, in fact, the invocation of 'main()' that is supposed to
> trigger the initialization.

That's backwards. Initialization must *precede* the invocation, not
*follow* it. The JVM is required to initialize the class just *before*
attempting to invoke the main method, and indeed up through Java 6 that
is precisely what it did.

markspace

unread,
Jun 18, 2012, 4:22:10 PM6/18/12
to
On 6/18/2012 11:46 AM, javax.swing.JSnarker wrote:
> What was the purpose of such a change? It now is a special case
> dissimilar to all other instances of JVM classloading.
>


Well no, you have the option to load a class without initializing it.

I assume that the change was to prevent bugs. If parts of a real
working application start up in a class initialization (not best
practice, but still possible) which allocate resources and then those
resources are not cleaned up when the whole app abruptly terminates, I
could see how it could be considered a bug in the JVM's start-up
procedure rather than the app itself. I'm not sure I'd agree, but I
could see someone making that case.

Lew

unread,
Jun 18, 2012, 4:31:47 PM6/18/12
to
On Monday, June 18, 2012 12:57:53 PM UTC-7, javax.swing.JSnarker wrote:
> On 18/06/2012 3:47 PM, Lew wrote:
> > Loading does not imply initialization, and in fact cannot.
>
> Wrong. Loading and initialization go hand-in-hand.
>
> > The JVM is forbidden to initialize a class except under specific
> > circumstances, a
>
> What?

See JLS 12.4, which I cited upthread:
<http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4>
"A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

- T is a class and an instance of T is created.

- T is a class and a static method declared by T is invoked.

- A static field declared by T is assigned.

- A static field declared by T is used and the field is not a constant variable (§4.12.4).

- T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

A reference to a static field (§8.3.1.1) causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.

Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization.

A class or interface will not be initialized under any other circumstance."

>
> >> Exactly. It loads the specified class, as part of which that class's
> >> static initializer runs. And if it's an enum, the enum elements'
> >> initializers run too.
> >
> > Not true. Loading does not imply initialization, and in fact is forbidden to.
>
> Wrong. Loading and initialization go hand-in-hand.

Not according to the JLS. What authority are you using?

> > The initializers only run under specific circumstances, separately from
> > loading.
> >
> > I have cited the relevant JLS sections.
>
> You haven't cited anything except my own post, and your quotation of
> *that* was a jumbled mess with some sections repeated for some reason.

Again, I quoted the section I re-quoted in this post. I provided the link
*and* quoted the relevant content. How can you say I didn't?

> > False premise, unreliable conclusion.
>
> On your part, Lew.
>
> > Loading does not imply initialization.
>
> Wrong. Loading and initialization go hand-in-hand.

Except according to the JLS.

> >> However, the observed behavior seems to be out of spec. The main
> >> method's absence should prompt an error upon the attempt to invoke it,
> >
> > Indeed.
>
> And not before.
>
> When invoking a static method of a non-loaded class, the standard
> procedure always has been:
>
> Load the class.
> Initialize the class.

Note - that is two steps, not one.

> Invoke the method.
>
> In particular, the spec requires that in this:
>
> class A {
> static int x;
>
> static { x = 100; }
>
> static int foo () { return x; }
> }
>
> a call to A.foo() should return 100, not 0. If it can attempt to invoke
> foo before the static initializer has executed that would be violated.

It can attempt to call 'foo()' before the initializer has executed. This is
exactly one of the circumstances that causes the initializers to execute.

Read the JLS! I have referenced and quoted the relevant section twice now.

> On the other hand, it complaining that a reflective call to A.bar()
> can't be resolved sooner than the loading and initializing of A as part
> of trying to resolve bar is equally anomalous. If it hasn't loaded and

I haven't seen any examples of reflection in this thread. Regardless,
"certain reflective methods" invoked will cause initialization.

> initialized A yet, how can it be sure whether or not it has a method
> bar? On the other hand, if it's a non-reflective call the code calling
> bar won't even compile.

--
Lew

Lew

unread,
Jun 18, 2012, 4:36:01 PM6/18/12
to
On Monday, June 18, 2012 1:01:41 PM UTC-7, javax.swing.JSnarker wrote:
> On 18/06/2012 3:44 PM, Lew wrote:
> > "A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
> >
> > - T is a class and a static method declared by T is invoked.
>
> This is the case that seems to be applicable here. It should not be
> erroring out trying to invoke main until after initialization, because
> the initialization must occur immediately *before* the invocation
> attempt (since it must have occurred if that attempt succeeds or again
> the spec is violated).
>
> > You are saying that the first case applies, an instance is created because of
> > the third case, a static field is assigned. But that assignment shouldn't happen
> > yet because nothing has invoked the class legally, i.e., the sequence to invoke
> > 'main()' didn't happen. It is, in fact, the invocation of 'main()' that is supposed to
> > trigger the initialization.
>
> That's backwards. Initialization must *precede* the invocation, not

Invocation precedes initialization, in that it is one of the triggers for
initialization, as described in the JLS.

The attempt to invoke causes initialization before invocation completes.

I've provided a link and citation of the relevant JLS section. Twice.
Read it.

> *follow* it. The JVM is required to initialize the class just *before*
> attempting to invoke the main method, and indeed up through Java 6 that
> is precisely what it did.

No, it is initialized just before the method is invoked. The attempt is what
triggers the initialization.

And initialization doesn't occur until such an attempt or one of the other
triggering events. In particular, the class is not automatically initialized
when loaded.

Read the JLS.

--
Lew

Leif Roar Moldskred

unread,
Jun 18, 2012, 5:05:19 PM6/18/12
to
Lew <lewb...@gmail.com> wrote:


> "Invocation of certain reflective methods in class Class and in
> package java.lang.reflect also causes class or interface
> initialization."

Might this be what is happening? The JLS doesn't seem to specify _how_
the main method should be invoked, so might not a Java implementation
do so through reflection and thus trigger the initialization of the
class?

--
Leif Roar Moldskred

Lew

unread,
Jun 18, 2012, 5:18:54 PM6/18/12
to
Leif Roar Moldskred wrote:
> Lew wrote:
> > "Invocation of certain reflective methods in class Class and in
> > package java.lang.reflect also causes class or interface
> > initialization."
>
> Might this be what is happening? The JLS doesn't seem to specify _how_
> the main method should be invoked, so might not a Java implementation
> do so through reflection and thus trigger the initialization of the
> class?

There was no 'main()' method in the example under discussion.

The JLS says that the JVM is started by invocation of a 'main()' method.

Without such an invocation, nothing should have been able to call any of the
static methods of the 'enum' or otherwise triggered initialization of that class.

The class initialized anyway.

Ergo the process didn't follow the JLS.

--
Lew

javax.swing.JSnarker

unread,
Jun 18, 2012, 7:48:39 PM6/18/12
to
On 18/06/2012 4:31 PM, Lew wrote:
> On Monday, June 18, 2012 12:57:53 PM UTC-7, javax.swing.JSnarker wrote:
>> On 18/06/2012 3:47 PM, Lew wrote:
>>> Loading does not imply initialization, and in fact cannot.
>>
>> Wrong. Loading and initialization go hand-in-hand.
>>
>>> The JVM is forbidden to initialize a class except under specific
>>> circumstances, a
>>
>> What?
>
> See JLS 12.4, which I cited upthread:

Why did you write half a sentence and end it in mid-word, though?

>> Wrong. Loading and initialization go hand-in-hand.
>
> Not according to the JLS. What authority are you using?

The fact that initialization is required before use of a class
(instantiation, invocation of a static method, whatever), and that
loading is not required until the circumstances that permit and require
initialization. Thus, loading will tend not to occur until right before
use, and initialization will thus tend to occur right after loading.

>> You haven't cited anything except my own post, and your quotation of
>> *that* was a jumbled mess with some sections repeated for some reason.
>
> Again, I quoted the section I re-quoted in this post. I provided the link
> *and* quoted the relevant content. How can you say I didn't?

You didn't provide any link and you quoted some stuff from my post
*twice*, for some reason. There seems to be a partial quote of it and a
bit of inline commentary from you (criticisms, natch), followed by a
second attribution line and then a quote of the entirety of my post,
including the parts already quoted earlier.

>> Wrong. Loading and initialization go hand-in-hand.
>
> Except according to the JLS.

The fact that initialization is required before use of a class
(instantiation, invocation of a static method, whatever), and that
loading is not required until the circumstances that permit and require
initialization. Thus, loading will tend not to occur until right before
use, and initialization will thus tend to occur right after loading.

>> Load the class.
>> Initialize the class.
>
> Note - that is two steps, not one.

However, there is little point in doing the first step until right
before the second step, so in practice they should occur back-to-back.

>> a call to A.foo() should return 100, not 0. If it can attempt to invoke
>> foo before the static initializer has executed that would be violated.
>
> It can attempt to call 'foo()' before the initializer has executed.

No, it generally can't. If the attempt succeeds and, as a consequence,
foo() executes before the initializer has executed, then foo will
incorrectly return 0. Therefore the attempt must not be made until the
initializer has executed, except in the peculiar case that the attempt
is known in advance to be guaranteed to fail. In which case there should
have been a compile-time error earlier still.

> This is exactly one of the circumstances that causes the initializers
> to execute.

You are confused. You seem to be thinking the order is

Load class
Attempt to call foo
Initialize class

But this can only be guaranteed not to violate the semantic requirements
if the attempt is known to be sure to fail. If the attempt to call foo
might succeed, then the order MUST be

Load class
Initialize class
Attempt to call foo

so that if the third step succeeds and foo begins executing, foo does
not encounter things still in an uninitialized state that the spec
guarantees must have been initialized before foo begins executing!

> Read the JLS! I have referenced and quoted the relevant section twice now.

And I've replied to it once, and it clearly states that initialization
must occur *before* any invocation of a static method. Your suggestion
that it can invoke it first and *then* initialize the class simply
cannot fly.

> I haven't seen any examples of reflection in this thread.

How is the main method invoked? It obviously isn't a statically-compiled
call from another class, and the only other invocation mechanism is
reflection; therefore it is called reflectively, by something that
behaves analogously to
Class.forName(argv[1]).getMethod("main",ARRAY_OF_JUST_THE_STRING_ARRAY_CLASS).invoke(null,convertRestOfArgv);.

>> initialized A yet, how can it be sure whether or not it has a method
>> bar? On the other hand, if it's a non-reflective call the code calling
>> bar won't even compile.
>

Why is the above quoted, but not responded to?

javax.swing.JSnarker

unread,
Jun 18, 2012, 7:50:35 PM6/18/12
to
There is such an invocation, though -- albeit an unsuccessful one, if no
method of that name can be resolved by the reflection code.

> The class initialized anyway.

Because the two alternatives are:

initialize, then try to invoke method; and
try to invoke method, then initialize.

But in the second case, if the invocation succeeds the method runs and
then the initializer instead of the other way around, and that's
obviously wrong.

javax.swing.JSnarker

unread,
Jun 18, 2012, 7:51:33 PM6/18/12
to
If resources allocated by an app are not cleaned up when "the whole app
abruptly terminates", then the bug is in the operating system, not the
app OR the JVM.

javax.swing.JSnarker

unread,
Jun 18, 2012, 8:01:20 PM6/18/12
to
On 18/06/2012 4:36 PM, Lew wrote:
> On Monday, June 18, 2012 1:01:41 PM UTC-7, javax.swing.JSnarker wrote:
>> On 18/06/2012 3:44 PM, Lew wrote:
>>> "A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
>>>
>>> - T is a class and a static method declared by T is invoked.
>>
>> This is the case that seems to be applicable here. It should not be
>> erroring out trying to invoke main until after initialization, because
>> the initialization must occur immediately *before* the invocation
>> attempt (since it must have occurred if that attempt succeeds or again
>> the spec is violated).
>>
>>> You are saying that the first case applies, an instance is created because of
>>> the third case, a static field is assigned. But that assignment shouldn't happen
>>> yet because nothing has invoked the class legally, i.e., the sequence to invoke
>>> 'main()' didn't happen. It is, in fact, the invocation of 'main()' that is supposed to
>>> trigger the initialization.
>>
>> That's backwards. Initialization must *precede* the invocation, not
>
> Invocation precedes initialization, in that it is one of the triggers for
> initialization, as described in the JLS.

That's confused thinking. Invocation *cannot* precede initialization if
initialization must have been done before the method's code starts
running. It can't run the method *before* initialization.

The language of the spec does not say, however, that invocation will be
followed by initialization. As you quoted it above, it clearly says that
initialization will occur *immediately before invocation* in these
cases. Initialization first, THEN invocation.

The trigger is not invocation itself, as it can't be as initialization
would then happen one invocation too late. The trigger is that that
invocation (attempt) is imminent, but has not yet already happened.

> The attempt to invoke causes initialization before invocation completes.

That also doesn't make sense. The attempt to invoke and the execution,
if the attempt is successful, of the method are all one single thing.
Initialization either happens before or after it -- and it cannot happen
after. Therefore it happens before.

If I attempt to catch a ball and then put on my baseball glove, then the
ball will land in my bare hand if the attempt succeeds. If I put on my
baseball glove and then attempt to catch a ball, the ball will land in
my gloved hand if the attempt succeeds. The spec says the ball should
land in my gloved hand. So, I can wait until immediately before
attempting to catch the ball to put the glove on, but I cannot wait
until after the attempt. (And if the analogy with the JLS spec is
continued, I mustn't put the glove on until immediately before the first
such attempt.)

> I've provided a link and citation of the relevant JLS section. Twice.
> Read it.

I did. If anyone didn't read it it was you. It clearly said
initialization *precedes* the first of any of a number of things done to
a class, including method invocation. Your notion that method invocation
can happen first and initialization later is based on nothing in the
written text of the spec, and, furthermore, simply does not make sense.

>> *follow* it. The JVM is required to initialize the class just *before*
>> attempting to invoke the main method, and indeed up through Java 6 that
>> is precisely what it did.
>
> No, it is initialized just before the method is invoked.

There you are, then. *Before* the method is invoked. Not after. And
certainly not during. (None of this stuff is thread-safe!) Initialize,
then (attempt to) invoke method. Cannot be the other way around, or the
ball will land in an ungloved hand if the attempt succeeds.

> And initialization doesn't occur until such an attempt or one of the other
> triggering events.

But then it occurs immediately *before*.

> In particular, the class is not automatically initialized when loaded.

No, but in practice it's not loaded until right before it would be
initialized, because it would just be wasting memory during the interim.

> Read the JLS.

You read it. Or reread it. Obviously you missed something or got confused.

Lew

unread,
Jun 18, 2012, 9:25:13 PM6/18/12
to
javax.swing.JSnarker wrote:
> Lew wrote:
>> Read the JLS.
>
> You read it. Or reread it. Obviously you missed something or got confused.

Not only did I not miss something nor am confused, I've encountered this in
practice.

You argue that usually loading immediately precedes initialization. This is
true. But not always.

You argue that loading must precede initialization. This is true, but it is
not true that initialization must immediately follow loading.

For example, a reference to 'Foo.class' will load 'Foo', but not initialize it,
if 'Foo' had not previously been loaded or initialized.

The big gaping flaw in your reasoning is that you leave out what triggers the
cycle of load/initialize. Classes are loaded and initialized on demand in Java.
That means the loading and initialization does not happen until there is
a qualifying reference to the class.

I've encountered bugs in code that depended on initialization to occur
immediately upon loading. What a surprise when that doesn't happen,
as in fact does happen.

Unless of course you understand the JLS.

I keep quoting and requoting the JLS, section 12.4.1. You should read it.
You obviously missed something or got confused.

--
Lew

javax.swing.JSnarker

unread,
Jun 18, 2012, 10:01:21 PM6/18/12
to
On 18/06/2012 9:25 PM, Lew wrote:
> javax.swing.JSnarker wrote:
>> Lew wrote:
>>> Read the JLS.
>>
>> You read it. Or reread it. Obviously you missed something or got confused.
>
> Not only did I not miss something nor am confused, I've encountered this in
> practice.
>
> You argue that usually loading immediately precedes initialization. This is
> true. But not always.

Why would it ever be done earlier? The class would just be taking up
space in main memory but not accomplishing anything useful by being
there right up until it was about to be used, at which time it would
need to be initialized.

> The big gaping flaw in your reasoning is

nonexistent.

> I keep quoting and requoting the JLS, section 12.4.1. You should read it.
> You obviously missed something or got confused.

I did not. It is you that did. You seem to think it's possible for
someone to wait until after they attempt to catch a ball to put their
ball glove on, and yet have the ball land in a gloved hand if the catch
is successful. That, right there, is all the evidence we need of your
confused state.

Gene Wirchenko

unread,
Jun 18, 2012, 10:04:40 PM6/18/12
to
On Mon, 18 Jun 2012 18:25:13 -0700 (PDT), Lew <lewb...@gmail.com>
wrote:

[snip]

>I keep quoting and requoting the JLS, section 12.4.1. You should read it.
>You obviously missed something or got confused.

javax.swing.JSnarker:

Either Lew is correct here, or he is not.

If he is correct, then you should listen to him.

If he is not and since he is a fairly on-the-ball sort, then it
is a confusing area, and you would be better off to not code in such a
way as to depend on such a confusing area.

The C equivalent of your argument is someone arguing that void
main() works on his system. (main() is defined in the C standard as
returning int on a hosted system (i.e. running under an OS).)

Sincerely,

Gene Wirchenko

javax.swing.JSnarker

unread,
Jun 18, 2012, 10:12:50 PM6/18/12
to
Void main() is not supported by the C specification. However, the quoted
section of the JLS clearly states that initialization precedes
invocation (which is also just plain common sense).

David Lamb

unread,
Jun 19, 2012, 8:07:42 AM6/19/12
to
On 18/06/2012 7:48 PM, javax.swing.JSnarker wrote:
> You are confused. You seem to be thinking the order is

Lew quoted the JLS. You ought to be arguing with its words, not his. I
don't pretend to have dug into the issue far enough to argue it one way
or another, but what matters isn't what any specific implementation
does, nor what you or Lew or I thinks the semantics *ought* to be. What
matters is what the JLS says.

If you start addressing the spec instead of Lew, I'll keep reading.



Andreas Leitgeb

unread,
Jun 19, 2012, 8:36:30 AM6/19/12
to
javax.swing.JSnarker <ghar...@boojum.mit.edu> wrote:
> However, the quoted
> section of the JLS clearly states that initialization precedes
> invocation (which is also just plain common sense).

Obviously, the JVM can determine availability of a static method
in a class that is loaded, but not yet initialized. Thus, during
bootstrapping the application, it *can* load the specified class,
notice lack of an appropriate main method, and skip initialization,
as it would be obviously futile for the resulting task of throwing
an exception.

Your parable about catching a ball with or without gloves falls
flat, because the JVM can freeze the ball mid-air, while calculating
its chances to catch it and then put the gloves on only in positive
case.

I must admit, I liked the old behaviour for the sake of really simple
almost boilerplate-lean way of testing some trivial bits of code.
class Test { static { /* code */ } }
(admittedly, the enum-approach never occurred to me)
I wouldn't even care for the method-lookup exception in those cases.

Otoh, I can also understand that this doesn't win over the bare fact
that non-existence of a static method can be detected without initia-
lizing the class, and thus still doing so is against the spirit of
lazy initialization.

Gene Wirchenko

unread,
Jun 19, 2012, 12:12:34 PM6/19/12
to
On Mon, 18 Jun 2012 22:12:50 -0400, "javax.swing.JSnarker"
<ghar...@boojum.mit.edu> wrote:

[snip]

>Void main() is not supported by the C specification. However, the quoted
>section of the JLS clearly states that initialization precedes
>invocation (which is also just plain common sense).

1) It is "void", not "Void", and

2) more importantly, "void main()" is legal C, just not in a hosted
implementation. Since the usual use of C is under a hosted
implementation, "void main()" is something to avoid in general, but
only in general.

Why not just read the JLS instead using "common sense" and
baseball gloves?

Sincerely,

Gene Wirchenko

javax.swing.JSnarker

unread,
Jun 19, 2012, 3:26:09 PM6/19/12
to
On 19/06/2012 8:07 AM, David Lamb wrote:
> On 18/06/2012 7:48 PM, javax.swing.JSnarker wrote:
>> You are confused. You seem to be thinking the order is
>
> Lew quoted the JLS. You ought to be arguing with its words, not his. I
> don't pretend to have dug into the issue far enough to argue it one way
> or another, but what matters isn't what any specific implementation
> does, nor what you or Lew or I thinks the semantics *ought* to be. What
> matters is what the JLS says.

And the JLS *clearly* says that initialization *precedes* invocation.

javax.swing.JSnarker

unread,
Jun 19, 2012, 3:28:42 PM6/19/12
to
On 19/06/2012 8:36 AM, Andreas Leitgeb wrote:
> javax.swing.JSnarker <ghar...@boojum.mit.edu> wrote:
>> However, the quoted
>> section of the JLS clearly states that initialization precedes
>> invocation (which is also just plain common sense).
>
> Obviously, the JVM can determine availability of a static method
> in a class that is loaded, but not yet initialized.

Not relevant.

> Thus, during bootstrapping the application, it *can* load the
> specified class, notice lack of an appropriate main method, and skip
> initialization, as it would be obviously futile for the resulting
> task of throwing an exception.

The spec doesn't specify any such behavior. Checking for existence of a
method is part of invoking a method (when the invocation is reflective
rather than compiled), and invoking a method follows initialization.

> Your parable about catching a ball with or without gloves falls
> flat,

You are incorrect.

> Otoh, I can also understand that this doesn't win over the bare fact
> that non-existence of a static method can be detected without initia-
> lizing the class, and thus still doing so is against the spirit of
> lazy initialization.

Even were the spec to allow it, optimizing for the rare case (main
method not found) rather than for the common case is always premature
optimization, and premature optimization is the root of all evil.

javax.swing.JSnarker

unread,
Jun 19, 2012, 3:30:33 PM6/19/12
to
On 19/06/2012 12:12 PM, Gene Wirchenko wrote:
> On Mon, 18 Jun 2012 22:12:50 -0400, "javax.swing.JSnarker"
> <ghar...@boojum.mit.edu> wrote:
>
> [snip]
>
>> Void main() is not supported by the C specification. However, the quoted
>> section of the JLS clearly states that initialization precedes
>> invocation (which is also just plain common sense).
>
> 1) It is "void", not "Void", and

Yes, I know, however it was at the start of a sentence and part of
English prose rather than compilable code.

> 2) more importantly, "void main()" is legal C,

Not according to any of the books I've read, and there have been many.

> Why not just read the JLS instead using "common sense" and
> baseball gloves?

I read the JLS *as well*. The JLS clearly stated that initialization
*precedes* invocation. It does not follow it and it certainly does not
happen *during* it, as some recent posts to this thread seem to have
suggested.

Gene Wirchenko

unread,
Jun 19, 2012, 6:04:46 PM6/19/12
to
On Tue, 19 Jun 2012 15:30:33 -0400, "javax.swing.JSnarker"
<ghar...@boojum.mit.edu> wrote:

>On 19/06/2012 12:12 PM, Gene Wirchenko wrote:
>> On Mon, 18 Jun 2012 22:12:50 -0400, "javax.swing.JSnarker"
>> <ghar...@boojum.mit.edu> wrote:
>>
>> [snip]
>>
>>> Void main() is not supported by the C specification. However, the quoted
>>> section of the JLS clearly states that initialization precedes
>>> invocation (which is also just plain common sense).
>>
>> 1) It is "void", not "Void", and
>
>Yes, I know, however it was at the start of a sentence and part of
>English prose rather than compilable code.

Since it is a code example, English grammar does not apply.

>> 2) more importantly, "void main()" is legal C,
>
>Not according to any of the books I've read, and there have been many.

What about the C standard? You have snipped my qualifying
phrase. "void main()" is valid under a non-hosted implementation. I
expect that most C programmers are not using it that way, and that is
why your books do not cover it. The C standard does though.

You have missed the fine point of the argument I have given. This
leads me to believe you have likely missed it in the Java argument of
this thread.

>> Why not just read the JLS instead using "common sense" and
>> baseball gloves?
>
>I read the JLS *as well*. The JLS clearly stated that initialization
>*precedes* invocation. It does not follow it and it certainly does not
>happen *during* it, as some recent posts to this thread seem to have
>suggested.

Why would people argue over something that is clearly stated?
Although Lew is somewhat abrasive, he has established credibility. You
do not. I know how I would bet.

Sincerely,

Gene Wirchenko

javax.swing.JSnarker

unread,
Jun 19, 2012, 6:23:33 PM6/19/12
to
On 19/06/2012 6:04 PM, Gene Wirchenko wrote:
> On Tue, 19 Jun 2012 15:30:33 -0400, "javax.swing.JSnarker"
> <ghar...@boojum.mit.edu> wrote:
>
>> On 19/06/2012 12:12 PM, Gene Wirchenko wrote:
>>> On Mon, 18 Jun 2012 22:12:50 -0400, "javax.swing.JSnarker"
>>> <ghar...@boojum.mit.edu> wrote:
>>>
>>> [snip]
>>>
>>>> Void main() is not supported by the C specification. However, the quoted
>>>> section of the JLS clearly states that initialization precedes
>>>> invocation (which is also just plain common sense).
>>>
>>> 1) It is "void", not "Void", and
>>
>> Yes, I know, however it was at the start of a sentence and part of
>> English prose rather than compilable code.
>
> Since it is a code example, English grammar does not apply.

"Void main() is not supported by the C specification." is English prose,
not a code example.

>> Not according to any of the books I've read, and there have been many.
>
> What about the C standard?

I assume that the books follow the C standard, or at least the vast
majority of them do. As for the standard itself, for some peculiar
reason it doesn't seem to be available anywhere by simple point, click,
download free of charge, unlike the JLS.

> You have missed the fine point of the argument I have given.

I have done nothing of the sort, or anything wrong at all, and I will
thank you to stop publicly smearing me by claiming or suggesting
otherwise in news posts.

>> I read the JLS *as well*. The JLS clearly stated that initialization
>> *precedes* invocation. It does not follow it and it certainly does not
>> happen *during* it, as some recent posts to this thread seem to have
>> suggested.
>
> Why would people argue over something that is clearly stated?

I do not know why Lew is arguing over something that is clearly stated.
I have a guess (that he's throwing up a smokescreen rather than admit
he's wrong) but no proof that it's correct.

Gene Wirchenko

unread,
Jun 19, 2012, 6:32:26 PM6/19/12
to
On Tue, 19 Jun 2012 18:23:33 -0400, "javax.swing.JSnarker"
<ghar...@boojum.mit.edu> wrote:

>On 19/06/2012 6:04 PM, Gene Wirchenko wrote:
>> On Tue, 19 Jun 2012 15:30:33 -0400, "javax.swing.JSnarker"
>> <ghar...@boojum.mit.edu> wrote:
>>
>>> On 19/06/2012 12:12 PM, Gene Wirchenko wrote:
>>>> On Mon, 18 Jun 2012 22:12:50 -0400, "javax.swing.JSnarker"
>>>> <ghar...@boojum.mit.edu> wrote:
>>>>
>>>> [snip]
>>>>
>>>>> Void main() is not supported by the C specification. However, the quoted
>>>>> section of the JLS clearly states that initialization precedes
>>>>> invocation (which is also just plain common sense).
>>>>
>>>> 1) It is "void", not "Void", and
>>>
>>> Yes, I know, however it was at the start of a sentence and part of
>>> English prose rather than compilable code.
>>
>> Since it is a code example, English grammar does not apply.
>
>"Void main() is not supported by the C specification." is English prose,
>not a code example.

Oh, but it is. It is only prohibited in a hosted implementation.

CLUE: There is a reason why I keep qualifying my statement with
"hosted" or "non-hosted".

>>> Not according to any of the books I've read, and there have been many.
>>
>> What about the C standard?
>
>I assume that the books follow the C standard, or at least the vast
>majority of them do. As for the standard itself, for some peculiar
>reason it doesn't seem to be available anywhere by simple point, click,
>download free of charge, unlike the JLS.

I have seen plenty that suggest "void main()" in a hosted
implementation. It is the first thing that I look for in evaluating
quality.

>> You have missed the fine point of the argument I have given.
>
>I have done nothing of the sort, or anything wrong at all, and I will
>thank you to stop publicly smearing me by claiming or suggesting
>otherwise in news posts.

You keep missing the distinction that I keep making about hosted
and non-hosted implementations.

I am not smearing you; I am making a point that you keep ignoring
while claiming to understand.

>>> I read the JLS *as well*. The JLS clearly stated that initialization
>>> *precedes* invocation. It does not follow it and it certainly does not
>>> happen *during* it, as some recent posts to this thread seem to have
>>> suggested.
>>
>> Why would people argue over something that is clearly stated?
>
>I do not know why Lew is arguing over something that is clearly stated.
>I have a guess (that he's throwing up a smokescreen rather than admit
>he's wrong) but no proof that it's correct.

I think it more likely that it is you who is wrong. I await your
next smokescreen post.

Sincerely,

Gene Wirchenko
Message has been deleted

javax.swing.JSnarker

unread,
Jun 19, 2012, 7:09:42 PM6/19/12
to
On 19/06/2012 6:32 PM, Gene Wirchenko wrote:
> <ghar...@boojum.mit.edu> wrote:
>> On 19/06/2012 6:04 PM, Gene Wirchenko wrote:
>>> <ghar...@boojum.mit.edu> wrote:
>>>> On 19/06/2012 12:12 PM, Gene Wirchenko wrote:
>>>>> <ghar...@boojum.mit.edu> wrote:
>>>>>> Void main() is not supported by the C specification. However, the quoted
>>>>>> section of the JLS clearly states that initialization precedes
>>>>>> invocation (which is also just plain common sense).
>>>>> 1) It is "void", not "Void", and
>>>> Yes, I know, however it was at the start of a sentence and part of
>>>> English prose rather than compilable code.
>>> Since it is a code example, English grammar does not apply.
>> "Void main() is not supported by the C specification." is English prose,
>> not a code example.
> Oh, but it is.

It is, indeed, English prose; glad you realize that now.

>>>> Not according to any of the books I've read, and there have been many.
>>> What about the C standard?
>> I assume that the books follow the C standard, or at least the vast
>> majority of them do. As for the standard itself, for some peculiar
>> reason it doesn't seem to be available anywhere by simple point, click,
>> download free of charge, unlike the JLS.
> I have seen plenty that suggest "void main()" in a hosted
> implementation. It is the first thing that I look for in evaluating
> quality.

To then reject the ones that suggest it, I hope.

>> I have done nothing of the sort, or anything wrong at all, and I will
>> thank you to stop publicly smearing me by claiming or suggesting
>> otherwise in news posts.
> You keep missing

I have done nothing of the sort, or anything wrong at all, and I will
thank you to stop publicly smearing me by claiming or suggesting
otherwise in news posts.

>> I do not know why Lew is arguing over something that is clearly stated.
>> I have a guess (that he's throwing up a smokescreen rather than admit
>> he's wrong) but no proof that it's correct.
> I think it more likely that it is you who is wrong.

Then you think wrong. The spec clearly says that initialization precedes
invocation.

> I await your next smokescreen post.

Then you will be waiting a very long time.

javax.swing.JSnarker

unread,
Jun 19, 2012, 7:10:26 PM6/19/12
to
On 19/06/2012 7:02 PM, Stefan Ram wrote:
> "javax.swing.JSnarker" <ghar...@boojum.mit.edu> writes:
>> "Void main() is not supported by the C specification." is English prose,
>> not a code example.
>
> The text with in the quotes misses inner quotes.

What?

[rest deleted as a non sequitur]

Lew

unread,
Jun 19, 2012, 8:19:21 PM6/19/12
to
javax.swing.JSnarker wrote:
> Gene Wirchenko wrote:
> > javax.swing.JSnarker wrote:
> >
> > [snip]
> >
> >> Void main() is not supported by the C specification. However, the quoted
> >> section of the JLS clearly states that initialization precedes
> >> invocation (which is also just plain common sense).
> >
> > 1) It is "void", not "Void", and
>
> Yes, I know, however it was at the start of a sentence and part of
> English prose rather than compilable code.
>
> > 2) more importantly, "void main()" is legal C,
>
> Not according to any of the books I've read, and there have been many.
>
> > Why not just read the JLS instead using "common sense" and
> > baseball gloves?
>
> I read the JLS *as well*. The JLS clearly stated that initialization
> *precedes* invocation. It does not follow it and it certainly does not
> happen *during* it, as some recent posts to this thread seem to have
> suggested.

It precedes invocation, but not the attempt to invoke.

You are wrong. I have seen in real code where classes were loaded and
not initialized, causing a bug in code written by the wrong idea you're promoting.

Reality wins.

The JLS clearly states when initialization MUST NOT happen after loading,
therefore if you read the JLS you will see that the two do not
happen together automatically, and you will correct your misapprehension.

You are mistaken.

--
Lew

javax.swing.JSnarker

unread,
Jun 19, 2012, 8:42:05 PM6/19/12
to
On 19/06/2012 8:19 PM, Lew wrote:
> It precedes invocation, but not the attempt to invoke.

That doesn't make sense. "It precedes catching the ball, but not the
attempt to catch" likewise doesn't make sense.

> You are wrong.

No, I'm not.

> I have seen in real code where classes were loaded and not initialized,

Not relevant here, unless you're claiming you've seen in real code where
a static method began to be invoked and the class was *still* not
initialized.

> Reality wins.

And you lose.

The rest of your post is redundant with other parts of it and as such
has been ignored as asked-and-answered already.

Leif Roar Moldskred

unread,
Jun 19, 2012, 9:01:22 PM6/19/12
to
javax.swing.JSnarker <ghar...@boojum.mit.edu> wrote:
>
> Not relevant here, unless you're claiming you've seen in real code where
> a static method began to be invoked and the class was *still* not
> initialized.

As has been pointed out earlier in the thread, that's exactly what
happens when, with Java 7, you try to start a Java program with a
class that does not contain a valid main method.

--
Leif Roar Moldskred

javax.swing.JSnarker

unread,
Jun 19, 2012, 9:12:17 PM6/19/12
to
And as has been pointed out earlier in the thread, that contravenes the
spec, which says initialization occurs *before* invocation.

Leif Roar Moldskred

unread,
Jun 19, 2012, 9:32:42 PM6/19/12
to
javax.swing.JSnarker <ghar...@boojum.mit.edu> wrote:
> On 19/06/2012 9:01 PM, Leif Roar Moldskred wrote:
>>
>> As has been pointed out earlier in the thread, that's exactly what
>> happens when, with Java 7, you try to start a Java program with a
>> class that does not contain a valid main method.
>
> And as has been pointed out earlier in the thread, that contravenes the
> spec, which says initialization occurs *before* invocation.

I disagree that it contravenes the spec, but regardless it is an
example of "real code where a static method began to be invoked and
the class was still not initialized." Of course, that's assuming that
we consider Java 7 to have "begun to invoke" the missing main method,
but if not, the rest of your argument falls through.

--
Leif Roar Moldskred

Lew

unread,
Jun 20, 2012, 1:01:39 AM6/20/12
to
Leif Roar Moldskred wrote:
> javax.swing.JSnarker wrote:
>> Leif Roar Moldskred wrote:
>>>
>>> As has been pointed out earlier in the thread, that's exactly what
>>> happens when, with Java 7, you try to start a Java program with a
>>> class that does not contain a valid main method.
>>
>> And as has been pointed out earlier in the thread, that contravenes the
>> spec, which says initialization occurs *before* invocation.

No, it doesn't contravene the spec. Initialization *does* occur before
invocation, but not before the attempt to invoke. As the spec explains.

> I disagree that it contravenes the spec, but regardless it is an
> example of "real code where a static method began to be invoked and
> the class was still not initialized." Of course, that's assuming that
> we consider Java 7 to have "begun to invoke" the missing main method,
> but if not, the rest of your argument falls through.

The same thing happens in Java 5 (and should have happened in 1.2 through
1.4), if you refer to the 'class' literal of a class before any action that
triggers intialization, the class will be loaded but not initialized.

As required by the JLS. Since before Java 5. Admittedly (in that Sun admitted
it) there was a bug in Sun's Java 1.4 whereby reference to the 'class' literal
did cause class initialization, but they fixed that in Java 5.

These are facts which completely undercut "JSnarker"'s claim. As does the JLS:

<http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2>
"The procedure assumes that the Class object has already been verified and
prepared, and that the Class object contains state that indicates one of four
situations:

"- This Class object is verified and prepared but not initialized.
..."

See?

There is a point at which a class has been loaded, verified and prepared, but
not initialized.

That state can exist at any of the initialization points mentioned in §
12.4.1, e.g., "immediately before the first occurrence of ... T is a class and
a static method declared by T is invoked."

Prior to that, the class may have already been loaded but not initialized,
e.g., by a reference to its 'class' literal or by an invocation of
'Class#forName()' with the 'intialize' parameter set to 'false'.

As for the process happening upon an attempt to invoke, here's language from
12.1.1:

"The initial attempt to execute the method main of class Test discovers that
the class Test is not loaded ..."

Where's your temporal sequence now, O Snarky One? As I have stated and you
have obstinately rejected repeatedly, the loading (if not yet done) and
initialization occurs upon the attempt to invoke, i.e., the attempt happens
first, conceptually.

Read the JLS and understand.

--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

Lew

unread,
Jun 20, 2012, 1:15:42 AM6/20/12
to
Leif Roar Moldskred wrote:
> javax.swing.JSnarker wrote:
>>
>> Not relevant here, unless you're claiming you've seen in real code where
>> a static method began to be invoked and the class was *still* not
>> initialized.

Here we go. "No true Scotsman". This plus /ad hominem/ attacks.

It is relevant because the argument was over whether initialization always
occurs together with loading, as you claimed upthread. It does not, as I have
stated all along. I never made the claim that invocation of a static method
did not cause (despite following) initialization.

And doesn't your statemtn - "a static method began to be invoked and the class
was *still* not initialized" - reveal a sequence of "begin to invoke" followed
by "initialize", just as I've been saying right along?

Do you mean to say you've been arguing against something that you actually
agree with?

All this time?

If I hadn't been responding via a Web interface I'd've remembered why I
plonked you a long time ago, snark.

> As has been pointed out earlier in the thread, that's exactly what
> happens when, with Java 7, you try to start a Java program with a
> class that does not contain a valid main method.

As is required by the JLS, and has been since before Java 7.

Andreas Leitgeb

unread,
Jun 20, 2012, 6:34:04 AM6/20/12
to
Lew <no...@lewscanon.com> wrote:
> Leif Roar Moldskred wrote:
>> javax.swing.JSnarker wrote:
>>> Not relevant here, unless you're claiming you've seen in real code where
>>> a static method began to be invoked and the class was *still* not
>>> initialized.

It all boils down to the true definition of "invocation".

Is it the moment when the instruction pointer hits the bytecode for
invokestatic and starts doing it, or is it just before it hits the
first instruction of the callee (iff existing)?

JVM7-behaviour implies the latter. I admit having difficulties myself
to actually read it unambiguously from JLS §12.4.1. Probably this
is defined elsewhere.

Anyway, between these two moments, there's plenty time for the JVM
to load the class, check availability of the method, and only if ok
then initialize the class and proceed with the callee's code,
otherwise skip initialization and just throw some exception.
And for a certain definition of "invocation", initialization
would still always precede it.

Lew

unread,
Jun 20, 2012, 1:45:22 PM6/20/12
to
Andreas Leitgeb wrote:
The gap "between these two moments" is the gap between the attempt to
invoke, and the invocation proper.

JLS §12.4.1 lives in a context, one that include JLS §12.4.2,
op. cit. upthread.

Even so,
"A class or interface type T will be initialized immediately before the first
occurrence of any one of the following:
"T is a class and an instance of T is created.
"T is a class and a static method declared by T is invoked. ..."

is pretty clear. Whatever the definition of "invocation", initialization occurs
just before it. This means that the system identifies "immediately before".
That moment of "immediately before" can only be at the point of the attempt
to invoke, right before the invocation proper. I call "immediately before",
therefore, the "attempt to invoke". This distinguishes it from the invocation,
which occurs after initialization.

Note that this passage does not say that the class is loaded at that point.
That's because the class may have been loaded considerably earlier, but
not initialized.

--
Lew

javax.swing.JSnarker

unread,
Jun 20, 2012, 9:05:32 PM6/20/12
to
On 19/06/2012 9:32 PM, Leif Roar Moldskred wrote:
> javax.swing.JSnarker <ghar...@boojum.mit.edu> wrote:
>> On 19/06/2012 9:01 PM, Leif Roar Moldskred wrote:
>>>
>>> As has been pointed out earlier in the thread, that's exactly what
>>> happens when, with Java 7, you try to start a Java program with a
>>> class that does not contain a valid main method.
>>
>> And as has been pointed out earlier in the thread, that contravenes the
>> spec, which says initialization occurs *before* invocation.
>
> I disagree that it contravenes the spec, but regardless it is an
> example of "real code where a static method began to be invoked and
> the class was still not initialized."

Which would contravene the spec, since the spec clearly says that
initialization must *precede* invocation.

> Of course, that's assuming that we consider Java 7 to have "begun to
> invoke" the missing main method, but if not, the rest of your argument
> falls through.

Lew considers it to have "begun to invoke" the missing main method, as
is apparent when he says it attempts to invoke the missing method first.
So if Lew is correct, then the behavior is out of spec. On the other
hand, if Lew is wrong, then the argument I made for why if Lew was
correct the behavior is out of spec falls through, but was moot anyway.

javax.swing.JSnarker

unread,
Jun 20, 2012, 9:15:23 PM6/20/12
to
On 20/06/2012 1:01 AM, Lew wrote:
> Leif Roar Moldskred wrote:
>> javax.swing.JSnarker wrote:
>>> Leif Roar Moldskred wrote:
>>>>
>>>> As has been pointed out earlier in the thread, that's exactly what
>>>> happens when, with Java 7, you try to start a Java program with a
>>>> class that does not contain a valid main method.
>>>
>>> And as has been pointed out earlier in the thread, that contravenes the
>>> spec, which says initialization occurs *before* invocation.
>
> No, it doesn't contravene the spec. Initialization *does* occur before
> invocation, but not before the attempt to invoke. As the spec explains.

The spec explains no such thing -- fortunately, because it doesn't make
sense. You cannot separate "the attempt to invoke" from "invocation".
The two go hand in hand like the attempt to catch a ball and the
successful catch. How can they not? Until the first byte of the main
method's bytecode is executing the attempt may or may not be successful;
success is defined by the main method's bytecode being entered and
starting to execute! How *else* could one sensibly define the attempt to
invoke said bytecode? But then initialization *must* precede the attempt
to not violate the spec, because otherwise it occurs after at least the
first byte of the main method begins executing. And by then it's too
late. The main method will see stuff uninitialized that the spec
requires it never see uninitialized, and there goes your claim to have a
conformant implementation. And until that moment, the "attempt to
invoke" is not guaranteed to succeed and is therefore still an attempt
and not an invocation by your own peculiar worldview in which you regard
the two as somehow separate.

> The same thing happens in Java 5 (and should have happened in 1.2
> through 1.4), if you refer to the 'class' literal of a class before any
> action that triggers intialization, the class will be loaded but not
> initialized.

How does loading it right away in such cases accomplish anything useful?
The class literal might as well evaluate to a memory-cheap stub-object
that is transparently replaced with the real class object when, and only
when, something is done with it that goes beyond bandying it about,
printing it, using its monitor, getting its hashcode, or comparing it
for equality. And the things that would then trigger actual loading also
are the ones that trigger initialization. Such a scheme would be *much*
more in what you previously called the "spirit of lazy initialization".

> These are facts which completely undercut "JSnarker"'s claim.

In a pig's eye.

> As does the JLS:

Only by your twisted and, shall we say "unique", interpretation of it.

> See?
>
> There is a point at which a class has been loaded, verified and
> prepared, but not initialized.

Nothing in that says that that circumstance should be anything but very
brief, and it's clear that it must exist *at least* very briefly as
loading obviously must precede initialization.

> As for the process happening upon an attempt to invoke, here's language
> from 12.1.1:
>
> "The initial attempt to execute the method main of class Test discovers
> that the class Test is not loaded ..."
>
> Where's your temporal sequence now, O Snarky One? As I have stated and
> you have obstinately rejected repeatedly, the loading (if not yet done)
> and initialization occurs upon the attempt to invoke, i.e., the attempt
> happens first, conceptually.

What it says is that an attempt is made and fails because the class is
not both loaded and initialized. It is loaded, if necessary, and
initialized, and then a fresh attempt is automatically made. THAT
attempt may then succeed, or fail for other reasons, such as the method
doesn't exist.

> Read the JLS and understand.

Already did that. Still waiting for you to practice what you preach, thoguh.

javax.swing.JSnarker

unread,
Jun 20, 2012, 9:19:11 PM6/20/12
to
On 20/06/2012 1:15 AM, Lew wrote:
> Leif Roar Moldskred wrote:
>> javax.swing.JSnarker wrote:
>>>
>>> Not relevant here, unless you're claiming you've seen in real code where
>>> a static method began to be invoked and the class was *still* not
>>> initialized.
>
> Here we go. "No true Scotsman". This plus /ad hominem/ attacks.

From you people, perhaps.

> It is relevant because the argument was over whether initialization
> always occurs together with loading

The argument is over whether attempting to invoke the main method is
allowed to precede initialization.

> And doesn't your statemtn - "a static method began to be invoked and the
> class was *still* not initialized" - reveal a sequence of "begin to
> invoke" followed by "initialize", just as I've been saying right along?

That statement was a rephrasing of *your* claims intended to make it
clear that they contravene the spec.

> If I hadn't been responding via a Web interface I'd've remembered why I
> plonked you a long time ago, snark.

Ah. These must be the promised /ad hominem/ attacks.

>> As has been pointed out earlier in the thread, that's exactly what
>> happens when, with Java 7, you try to start a Java program with a
>> class that does not contain a valid main method.
>
> As is required by the JLS, and has been since before Java 7.

The JLS requires that initialization precede the invocation, and
therefore precede the exception thrown when invocation fails due to lack
of the needed method.

javax.swing.JSnarker

unread,
Jun 20, 2012, 9:22:30 PM6/20/12
to
On 20/06/2012 6:34 AM, Andreas Leitgeb wrote:
> Lew <no...@lewscanon.com> wrote:
>> Leif Roar Moldskred wrote:
>>> javax.swing.JSnarker wrote:
>>>> Not relevant here, unless you're claiming you've seen in real code where
>>>> a static method began to be invoked and the class was *still* not
>>>> initialized.
>
> It all boils down to the true definition of "invocation".
>
> Is it the moment when the instruction pointer hits the bytecode for
> invokestatic and starts doing it,

Obviously, and more or less by definition of "invokestatic".

> JVM7-behaviour implies the latter.

The spec implies the former, though with sufficient ambiguity as to have
confused the hell out of Leif and Lew. And the name of the opcode
"invokestatic" also implies the former, as does the behavior of JVM6,
JVM5, ...

> Anyway, between these two moments, there's plenty time for the JVM
> to load the class, check availability of the method, and only if ok
> then initialize the class and proceed with the callee's code,
> otherwise skip initialization and just throw some exception.
> And for a certain definition of "invocation", initialization
> would still always precede it.

A kooky definition.

Andreas Leitgeb

unread,
Jun 21, 2012, 4:13:36 AM6/21/12
to
Lew <lewb...@gmail.com> wrote:
> Andreas Leitgeb wrote:
>> It all boils down to the true definition of "invocation".
> Even so,
> "A class or interface type T will be initialized immediately before the first
> occurrence of any one of the following:
> "T is a class and an instance of T is created.
> "T is a class and a static method declared by T is invoked. ..."

It's interesting, how some aspect gets through only after reading
it the umpty+1st time.

The mention is actually clearly about a "a static method declared by T",
which obviously doesn't cover calls to methods, that are *not* declared
by that class.

PS: some example for Java 6
A.java:
class A {
static { System.out.println("A static init"); }
static void foo() { System.out.println("A static foo"); }
}
B.java:
class B {
static { System.out.println("B static init"); }
public static void main(String[]args) {
System.out.println("B static main");
A.foo();
}
}
compile both (with Java 6), run B:
B static init
B static main
A static init
A static foo
Then comment out the method "foo()" from A,
recompile only A, run B:
B static init
B static main
Exception in thread "main" java.lang.NoSuchMethodError: A.foo()V
at B.main(B.java:4)
Note: no initialization of A, even with Java 6.

Anyone care to try this with other (older) versions and report results?

javax.swing.JSnarker

unread,
Jun 21, 2012, 5:18:21 PM6/21/12
to
On 21/06/2012 4:13 AM, Andreas Leitgeb wrote:
> compile both (with Java 6), run B:
> B static init
> B static main
> A static init
> A static foo
> Then comment out the method "foo()" from A,
> recompile only A, run B:
> B static init
> B static main
> Exception in thread "main" java.lang.NoSuchMethodError: A.foo()V
> at B.main(B.java:4)
> Note: no initialization of A, even with Java 6.

So, even Java 6 has a version of the bug. Interesting. I don't see how
the remark about "declared by T" is relevant here, since foo clearly is
declared by A in your example that reproduces the bug.

Lew

unread,
Jun 21, 2012, 6:30:31 PM6/21/12
to
javax.swing.JSnarker wrote:
> Andreas Leitgeb wrote:
> > compile both (with Java 6), run B:
> > B static init
> > B static main
> > A static init
> > A static foo
> > Then comment out the method "foo()" from A,
> > recompile only A, run B:
> > B static init
> > B static main
> > Exception in thread "main" java.lang.NoSuchMethodError: A.foo()V
> > at B.main(B.java:4)
> > Note: no initialization of A, even with Java 6.
>
> So, even Java 6 has a version of the bug. Interesting. I don't see how
> the remark about "declared by T" is relevant here, since foo clearly is
> declared by A in your example that reproduces the bug.

Of what bug do you speak?

Since no static method of 'A' was called in the second run, the condition
to initialize the class was not met.

--
Lew

javax.swing.JSnarker

unread,
Jun 21, 2012, 8:28:50 PM6/21/12
to
There was a call to A.foo(). That the call did not *succeed* doesn't
mean that it didn't *exist*. If the call didn't exist, what threw the
exception, and why?

Wanja Gayk

unread,
Jun 20, 2012, 7:11:17 AM6/20/12
to
In article <jrnqo5$l2o$1...@dont-email.me>, -@. says...

> It's just the order that things are done by default.
>
> Before the code was:
>
> 1. Load class with initialization.
> 2. Run 'main' method.
>
> Now, they do the special step of loading without initialization:
>
> 1. Load class without initialization.
> 2. Verify 'main' method, throw error if not present
> 3. Initialize class
> 4. Run 'main' method.
>
> You can see how the new method takes more effort.

I'd rather see it as an extension of the bytecode validation mechanism,
that has to exist anyway:

1. Load bytecode
2. Validate bytecode
(exits if there is no 'main' method for the main class)
3. Initialize class
4. Run 'main' method.

Kind regards,
Wanja

--
..Alesi's problem was that the back of the car was jumping up and down
dangerously - and I can assure you from having been teammate to
Jean Alesi and knowing what kind of cars that he can pull up with,
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

--- Posted via news://freenews.netfront.net/ - Complaints to ne...@netfront.net ---

Daniel Pitts

unread,
Jun 22, 2012, 3:54:47 PM6/22/12
to
On 6/20/12 4:11 AM, Wanja Gayk wrote:
> In article<jrnqo5$l2o$1...@dont-email.me>, -@. says...
>
>> It's just the order that things are done by default.
>>
>> Before the code was:
>>
>> 1. Load class with initialization.
>> 2. Run 'main' method.
>>
>> Now, they do the special step of loading without initialization:
>>
>> 1. Load class without initialization.
>> 2. Verify 'main' method, throw error if not present
>> 3. Initialize class
>> 4. Run 'main' method.
>>
>> You can see how the new method takes more effort.
>
> I'd rather see it as an extension of the bytecode validation mechanism,
> that has to exist anyway:
>
> 1. Load bytecode
> 2. Validate bytecode
> (exits if there is no 'main' method for the main class)
> 3. Initialize class
> 4. Run 'main' method.
Actually, the way I understand it is that Loading is immediately
followed by verification.

How I would expect this to work in reality.

1. Load class
2. get a reference to the static method "void main(String[])"
3. Attempt to execute that reference
3.1 Causes class initialization before execution.
3.2 actual execution occurs.



javax.swing.JSnarker

unread,
Jun 22, 2012, 6:30:19 PM6/22/12
to
On 22/06/2012 3:54 PM, Daniel Pitts wrote:
> How I would expect this to work in reality.
>
> 1. Load class
> 2. get a reference to the static method "void main(String[])"
> 3. Attempt to execute that reference
> 3.1 Causes class initialization before execution.
> 3.2 actual execution occurs.

That has a problem, though, in that class initialization will happen on
every method call, resulting in multiple initializations, if it's part
of "attempt to execute the reference" rather than (as the spec says)
something the JVM does immediately *before* the first such attempt (or
other action that requires an initialized class for the action to begin).

I suppose you could change 3.1 to "see if the class is initialized, and
if not, initialize it", but even that would add to *every method call*
the overhead of a test-and-branch, and would still be dodgy at best on
spec-adherence grounds.

Wanja Gayk

unread,
Jun 23, 2012, 7:42:59 AM6/23/12
to
In article <jrts0t$55e$1...@speranza.aioe.org>, ghar...@boojum.mit.edu
says...

> Which would contravene the spec, since the spec clearly says that
> initialization must *precede* invocation.

Between loading and initialization theres still verification, isn't it?

javax.swing.JSnarker

unread,
Jun 23, 2012, 12:12:10 PM6/23/12
to
On 23/06/2012 7:42 AM, Wanja Gayk wrote:
> In article <jrts0t$55e$1...@speranza.aioe.org>, ghar...@boojum.mit.edu
> says...
>
>> Which would contravene the spec, since the spec clearly says that
>> initialization must *precede* invocation.
>
> Between loading and initialization theres still verification, isn't it?

Verification is a part of loading, rather than coming after it.

--
public final class JSnarker
extends JComponent
The JSnarker is an NNTP-aware component that asynchronously provides

Wanja Gayk

unread,
Jun 23, 2012, 5:10:11 PM6/23/12
to
In article <js4psp$59p$1...@speranza.aioe.org>, ghar...@boojum.mit.edu
says...
>
> On 23/06/2012 7:42 AM, Wanja Gayk wrote:
> > In article <jrts0t$55e$1...@speranza.aioe.org>, ghar...@boojum.mit.edu
> > says...
> >
> >> Which would contravene the spec, since the spec clearly says that
> >> initialization must *precede* invocation.
> >
> > Between loading and initialization theres still verification, isn't it?
>
> Verification is a part of loading, rather than coming after it.

I'm curious: How do you want to verify something that you haven't loaded
yet?

javax.swing.JSnarker

unread,
Jun 23, 2012, 5:14:21 PM6/23/12
to
On 23/06/2012 5:10 PM, Wanja Gayk wrote:
> In article <js4psp$59p$1...@speranza.aioe.org>, ghar...@boojum.mit.edu
> says...
>>
>> On 23/06/2012 7:42 AM, Wanja Gayk wrote:
>>> In article <jrts0t$55e$1...@speranza.aioe.org>, ghar...@boojum.mit.edu
>>> says...
>>>
>>>> Which would contravene the spec, since the spec clearly says that
>>>> initialization must *precede* invocation.
>>>
>>> Between loading and initialization theres still verification, isn't it?
>>
>> Verification is a part of loading, rather than coming after it.
>
> I'm curious: How do you want to verify something that you haven't loaded
> yet?

I don't. Neither do I want a loaded class hanging around unverified
afterward, though. So the two belong back-to-back. Essentially,
obtaining the byte code from wherever into main memory is step 1 of
loading, and verifying it is step 2.

--
public final class JSnarker
extends JComponent
A JSnarker is an NNTP-aware component that asynchronously provides

Lew

unread,
Jun 25, 2012, 3:59:13 PM6/25/12
to
javax.swing.JSnarker wrote:
> Daniel Pitts wrote:
>> How I would expect this to work in reality.
>>
>> 1. Load class
>> 2. get a reference to the static method "void main(String[])"
>> 3. Attempt to execute that reference
>> 3.1 Causes class initialization before execution.
>> 3.2 actual execution occurs.
>
> That has a problem, though, in that class initialization will happen on
> every method call, resulting in multiple initializations, if it's part

That's not what happens.

> of "attempt to execute the reference" rather than (as the spec says)
> something the JVM does immediately *before* the first such attempt (or
> other action that requires an initialized class for the action to begin).

As the spec says, it happens upon the first attempt to execute a static method
(if the class has not already been initialized).

> I suppose you could change 3.1 to "see if the class is initialized, and
> if not, initialize it", but even that would add to *every method call*

That is what the spec says to do. As previously linked.

> the overhead of a test-and-branch, and would still be dodgy at best on
> spec-adherence grounds.

No, it does what it does and adheres to the spec.

See the previously linked references for the details.

--
Lew

javax.swing.JSnarker

unread,
Jun 25, 2012, 4:49:11 PM6/25/12
to
On 25/06/2012 3:59 PM, Lew wrote:
> javax.swing.JSnarker wrote:
>> Daniel Pitts wrote:
>>> How I would expect this to work in reality.
>>>
>>> 1. Load class
>>> 2. get a reference to the static method "void main(String[])"
>>> 3. Attempt to execute that reference
>>> 3.1 Causes class initialization before execution.
>>> 3.2 actual execution occurs.
>>
>> That has a problem, though, in that class initialization will happen on
>> every method call, resulting in multiple initializations, if it's part
>
> That's not what happens.

I'm not finished. Class initialization will happen on every method call,
resulting in multiple initializations, *if it's part* of "attempt to
execute the reference" rather than (as the spec says) something the JVM
does immediately *before* the first such attempt (or other action that
requires an initialized class for the action to begin).

> As the spec says, it happens upon the first attempt to execute a static method
> (if the class has not already been initialized).

No, the spec does not say "upon" it says "immediately before".

>> I suppose you could change 3.1 to "see if the class is initialized, and
>> if not, initialize it", but even that would add to *every method call*
>
> That is what the spec says to do. As previously linked.
>
>> the overhead of a test-and-branch, and would still be dodgy at best on
>> spec-adherence grounds.
>
> No, it does what it does and adheres to the spec.

No, what the spec says to do is to implement a statically-compiled call
this way:

Class is loaded and initialized by statically-compiled code.
Method invocation is simply a bare invokestatic instruction

And a reflective/otherwise non-static call this way:

Check if class is loaded and if not load and verify it.
Check if class is initialized and if not initialize it.
Check if method exists and if not throw an exception, otherwise invoke it.

And this is apparently what earlier versions did.

Surely you aren't suggesting there's a whole raft of if
(class_is_loaded), if (class_is_initialized), etc. tests before every
method call in Java 7? Because that would make method calls much slower
than before, unless you've got some cleverness in place to remove those
tests from the code once the class is loaded. In other words, something
more like expanding each call into

load_and_initialize_if_needed(X.class);
invokestatic...

where load_and_initialize_if_needed(X.class) strips out all instances of
load_and_initialize_if_needed(X.class) from all loaded bytecode as part
of its own behavior. But that would have all kinds of difficulties of
its own. At least the JIT might be able to skip over it if X is already
loaded and an instance is in code it's JITting.
0 new messages