We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › Strange NullPointerException
Page Index Toggle Pages: 1
Strange NullPointerException (Read 1270 times)
Strange NullPointerException
Nov 23rd, 2005, 1:42pm
 

The code below causes a NullPointerException for some reason.

int test[]={1,2,3,4};

class TestClass
{
 TestClass()
 {
   evaluate();
 }
 void evaluate()
 {
   if (test!=null) println("zero");
 }
}

class TestClass2 extends TestClass
{
 TestClass2()
 {
   if (test!=null) println("one");
 }
 void evaluate()
 {
   if (test!=null) println("two");
 }
}

void setup()
{
//  TestClass c=new TestClass(); // this works fine
 TestClass2 c=new TestClass2(); // this breaks
}
Re: Strange NullPointerException
Reply #1 - Nov 23rd, 2005, 10:16pm
 
Hm..

that IS odd.

To me... evaluate() shouldn't even run at all in TestClass2 constructor. For some reason TestClass() is being run first, then TestClass2.

Additionally... the int[] should not be null since it is global...
Re: Strange NullPointerException
Reply #2 - Nov 24th, 2005, 12:38pm
 
Since TestClass2 extends TestClass, making a new TestClass2 object will call the constructor of the parent automatically. That's not the problem. It's the bizarre behavior of the global that concerns me.

according to the bug report people, 'it's just how java works'. Right.
Re: Strange NullPointerException
Reply #3 - Nov 24th, 2005, 7:38pm
 
I'm not sure about this - being more of a C++ person than Java - but it's generally not safe to call an overridden function from a constructor.

Before TestClass2 is constructed, its base class constructor is called as you correctly said. This invokes a call to evaluate(). This will attempt to call your overridden TestClass2 version of evaluate(). However, because your new instance of TestClass2 won't be in a fully-constructed state until its constructor returns, it blows up.

The workaround if you really need to have overridden initialization is usually to do two-stage construction.
Something like:
TestClass2 myTestClass2 = new TestClass2();
myTestClass2.initialize();

Call your overidden functions from initialize() not from the constructor. It's not as neat though so check that you really need to do overridden initialization first.

Robin


Re: Strange NullPointerException
Reply #4 - Nov 25th, 2005, 4:03pm
 
Zaratustra wrote on Nov 24th, 2005, 12:38pm:
according to the bug report people, 'it's just how java works'. Right.


right, and then the "bug person" went on to explain that:

this is a sort of textbook case on why you don't want to initialize global
variables that way, because there's no way of ensuring when they're going
to be available.
Re: Strange NullPointerException
Reply #5 - Nov 25th, 2005, 5:41pm
 
I thought Java had no 'undefined behaviors'.
Re: Strange NullPointerException
Reply #6 - Nov 25th, 2005, 7:48pm
 
Ok, being much confused myself, I did a bit of research on this.

It turns out to be a bug in how Processing compiles, not in Java or anything else.

Try compiling this code with Sun's Java compiler (I used jdk 1.5.0_05):
Code:

public class sketch_051125a {

int test[]={1,2,3,4};

class TestClass
{
TestClass()
{
if (test!=null) System.out.println("TestClass()");
evaluate();
}
public void evaluate()
{
if (test!=null) System.out.println("TestClass.evaluate()");
}
}

class TestClass2 extends TestClass
{
int i = 10;
TestClass2()
{
i = 45;
if (test!=null) System.out.println("TestClass2()");
}
public void evaluate()
{
if (test!=null)
System.out.println("TestClass2.evaluate()");
System.out.println("i="+i);
}
}
void setup()
{
// TestClass c=new TestClass(); // this works fine
TestClass2 c2=new TestClass2(); // this breaks
}

public static void main(String args[])
{
(new sketch_051125a()).setup();
}

}


Try this in Processing v0095-expert and you get a NullPointerException.  The reason is because Jikes isn't setting the inner class instance TestClass2's pointer to its enclosing class until some time after TestClass's constructor finishes (and presumably before TestClass2's constructor starts).

On a side note, Java seems to perform perfectly fine with running overridden methods from super class constructors.  You'll notice i=0 is output by the above code (before it has been initialized to 10 or 45).

So no, this is not "how java works" but a bug related specifically to Processing's Java compiler.

Marcello
Re: Strange NullPointerException
Reply #7 - Nov 25th, 2005, 9:08pm
 
Marcello,
If it's not a java thing, why do I get the NullPointerException error running code below in Java (OS X, v. 1.4.2_09 )? If I don't override, error dissappears.
ira

public class CNTRL {
int test[]={1,2,3,4};
public CNTRL(){
TestClass2 c=new TestClass2();
}

public static void main(String[]args){
new CNTRL();
}



class TestClass {
 TestClass() {
evaluate();
 }
 void evaluate() {
if (test!=null) System.out.println("zero");
 }
 

}

class TestClass2 extends TestClass {
 TestClass2() {
if (test!=null) System.out.println("one");
 }
 void evaluate() {
if (test!=null) System.out.println("two");
 }
}

}
Re: Strange NullPointerException
Reply #8 - Nov 26th, 2005, 5:55pm
 
Did you compile that with Sun's javac command or jikes?  The issue appears to do with compilation, not execution.  (So theoretically the class I compiled here on 1.5 should run on your mac.)

edit: I just tried your code, compiled on 1.5, and run on 1.5, and it works fine:
Quote:
two
one


Marcello
Re: Strange NullPointerException
Reply #9 - Nov 26th, 2005, 6:48pm
 
Well, this is getting more interstesting.

OS X (10.4.3)

java version "1.4.2_09"
compiled fine with javac
nullPointer error when run

java version "1.5.0_05"
compiled fine with javac
runs fine

Not really sure we can blame Processing for this. I also don't have time to research if this was an intentional fix by Sun(or Apple) between versions.

Curious the situation on other platforms?
Although, maybe we've spent to much time on this already(now that my curioousity is piqued.)

Re: Strange NullPointerException
Reply #10 - Nov 26th, 2005, 8:50pm
 
Fortunately what is being done is rare and odd enough that it should be avoided anyway.  For example, if you make the "global" array static, there is no issue.

I'm curious though, if you compile on javac 1.5, and run that class on java 1.4, does it get a null pointer exception?  If that's the case, it's no big deal at all, just use a modern compiler and it'll work backwards with old vms?

Marcello
Re: Strange NullPointerException
Reply #11 - Nov 26th, 2005, 9:18pm
 
I did try that, but the 1.4 vm didn't seem too pleased:

java.lang.UnsupportedClassVersionError: CNTRL (Unsupported major.minor version 49.0)
       at java.lang.ClassLoader.defineClass0(Native Method)
       at java.lang.ClassLoader.defineClass(ClassLoader.java:539)
       at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
       at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
       at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
       at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
       at java.security.AccessController.doPrivileged(Native Method)
       at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
       at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
       at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)
Re: Strange NullPointerException
Reply #12 - Nov 26th, 2005, 10:48pm
 
Try -target 1.3 ?

Marcello
Re: Strange NullPointerException
Reply #13 - Nov 27th, 2005, 12:43am
 
tried compiling/running: 1.3, 1.3.1, 1.4, 1.4.2, 1.5

Only works in 1.5.
Page Index Toggle Pages: 1