Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
Posts: 24
Registered: ‎01-21-2010
My Device: Curve 8310
My Carrier: Orange

Strange java behaviour on Blackberry JVM

Hi.

 

Maybe it is the right way it should work on J2ME but I'm on a strange thing taht I can't understand.

 

Here is a simple code Snippet :

 

package test;

public class SimpleTestClass {
	
	public SimpleTestClass() {
		
		System.err.println("********** From parent contructor : "+getValue());
		InnerTestClass i = new InnerTestClass() {
			public String getInnerValue() {
				return getValue();
			}
		};
		i.fromMethod();
	}
	
	public String getValue() {
		return "Ok";
	}
	
	public abstract static class InnerTestClass {
		public InnerTestClass() {
			try {
				String s = getInnerValue();
				System.err.println("********** From inner constructor : "+s);
			} catch (Throwable t) {
				System.err.println("********** Exception in inner constructor : "+t.getClass()+" / "+t.getMessage());
			}
		}
		public void fromMethod() {
			System.err.println("********** From inner method : "+getInnerValue());
		}
		public abstract String getInnerValue();
	}

}

 

 

 

 

1/ first test : compile and run with Sun jdk 1.5. Output is :

********** From parent contructor : Ok
**********From inner constructor : Ok
**********From inner method : Ok

 

=> that's what I expect this code to do.

 

2/ second test :compile and run on the main of a Blackberry Application :

********** From parent contructor : Ok
********** Exception in inner constructor : class java.lang.NullPointerException / null
********** From inner method : Ok

 

the NullPointerException is in method "getInnerValue()" but I don't understand why : it is just impossible there is any npe here.

 

3/ third test : run blackberry generatd class files with Sun jdk :

********** From parent contructor : Ok
********** Exception in inner constructor : class java.lang.NullPointerException / null
********** From inner method : Ok

 

==> same error. the problem is not on runtime but on .class files.

 

4/ test : using jad to decompile Blackberry's generated class files I see no difference with my original source.

 

5/ last test : compile and run the decompiled class files with Sun's jdk.

********** From parent contructor : Ok
**********From inner constructor : Ok
**********From inner method : Ok

 => this confirm that decompiled source code is exactly the same than my original source file.

 

So the problem, if there is any problem, is on the generated bytecode.

But I can't figure if this is a "feature" or a bug.

I tried on Blackberry OS v4.5 and 5.0 and had the same result.

 

I encounter this problem when I tried to display a Screen which is an Inner class.

I found a workaround for this but I would be happy to know what I made wrong.

 

If somebody know what I am missing, I would really be happy ...

 

Thanks ...

 

Mike

 

 

 

 

 

Highlighted
Developer
Posts: 723
Registered: ‎03-12-2009
My Device: Playbook

Re: Strange java behaviour on Blackberry JVM

[ Edited ]

Are you doing any sort of work on a process that is not your own?

 

Blackberry has a funny way of implementing static classes, they are not really singletons.

 

Different processes re-instantiate the static initializers.

 

Not sure if this is related, but there is a post on these boards by peter_strange which goes into good details of that issue.   Search for static initializer.

 

edit:

 

I didn't delve into your code, so I maybe 100% off base here.

Developer
Posts: 516
Registered: ‎07-23-2010
My Device: 9900

Re: Strange java behaviour on Blackberry JVM

try removing abstract from the inner class.

Developer
Posts: 24
Registered: ‎01-21-2010
My Device: Curve 8310
My Carrier: Orange

Re: Strange java behaviour on Blackberry JVM

 

Thanks for this info. I'm happy to hear that a singleton isn't uniq (sic) !

 

Any way, that is not my problem because I did not have any static field.

 

Or, what do you mean by

"Are you doing any sort of work on a process that is not your own?"

I don't reaaly understanf ...

 

Thanks.

 

Mike

Developer
Posts: 24
Registered: ‎01-21-2010
My Device: Curve 8310
My Carrier: Orange

Re: Strange java behaviour on Blackberry JVM

 

I tried removing the "abstract" part, but it did not change anything ...

 

Thanks for your help.

 

Mike

Developer
Posts: 1,415
Registered: ‎07-30-2008
My Device: Not Specified

Re: Strange java behaviour on Blackberry JVM

You can step through bytecodes on JDE if you view them. I always get confused on ctor

order as I had been doing more c++ but sure it sounds like vft is confused or string

pool empty. I guess you could see if it would load inline literals or make getValue more

complicated and instrument that- is it even being called.

 

This could be an issue with the multiple statics and class loader.

Startup is also precarious, maybe you could see if you are instartup as everything

may not have loaded yet.

Developer
Posts: 24
Registered: ‎01-21-2010
My Device: Curve 8310
My Carrier: Orange

Re: Strange java behaviour on Blackberry JVM

Weel, I hoped that sombody already knew what happend ... if not, I'll try to look at bycode but I'm not really familiar with that sort of operations. I'll try ...

Thanks for your reply.

Developer
Posts: 24
Registered: ‎01-21-2010
My Device: Curve 8310
My Carrier: Orange

Re: Strange java behaviour on Blackberry JVM

 

I decompiled blackberry's version and Sun's jdk version.

 

 

The main différence is on the inner class contructor bytecode.

 

Sun's version :

 

 

  Code:
   0:   aload_0
   1:   aload_1
   2:   putfield        #1; //Field this$0:Ltest/SimpleTestClass;
   5:   aload_0
   6:   invokespecial   #2; //Method test/SimpleTestClass$InnerTestClass."<init>":()V
   9:   return

 

 

Blackberry's version :

 

 

  Code:
   0:   aload_0
   1:   invokespecial   #11; //Method test/SimpleTestClass$InnerTestClass."<init>":()V
   4:   aload_0
   5:   aload_1
   6:   putfield        #14; //Field this$0:Ltest/SimpleTestClass;
   9:   return

 

 

I'm not realy sure of what each line does, but it seems that

- in Sun's version, internal fields are initialised before call to super()

- in Blackberry's version, internal fields are initialised after call to super().

 

I'm sure that this is the problem because I used a wondefull tool called jbe (http://www.cs.ioc.ee/~ando/jbe/) to edit class files, change order of lines in Blackberry's compiled version and ... it works ...

 

I then tried to compile with an older jdk (jdk 1.4.2) and I had the same problem !

So it seems not to be a Blackberry's problems, but a Java <=1.4 problem.

When I compile with jdk 6 using "-target 1.4 -source 1.4" options, no problem, it works.

 

Finally I have workaround for this, but I'm really surprised that there is no more complains on it.

My usecase seems not to be exotic. It's a custom screen that have methods. 

I make an inner version overriding some methods.

the point is that I override a method that might be called from the parent constructor ...

So, do we have to remove any call to any not private methods in constructor to avoid this case ?

 

 

By the way, it is the first time I use this kind of tool and it is really interesting.

I saw, for example, that with sun's jdk (what ever version, 1.4 or 1.6), Strings initialisation are made this way :

 

 

   3:   new     #4; //class java/lang/StringBuffer
   6:   dup
   7:   invokespecial   #5; //Method java/lang/StringBuffer."<init>":()V
   10:  ldc     #16; //String ********** From inner method : 
   12:  invokevirtual   #7; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;

 

 

With Blackberry's compiler, it is done this way :

 

 

   7:   new     #16; //class java/lang/StringBuffer
   10:  dup
   11:  ldc     #18; //String ********** From parent contructor : 
   13:  invokespecial   #20; //Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V

 

 

So instead of calling new() without parameter on a StringBuffer and calling then append(), Blackberry's jdk directly call new(String) and does not need append(). More clever Smiley Happy.

 

 

Mike

Developer
Posts: 1,415
Registered: ‎07-30-2008
My Device: Not Specified

Re: Strange java behaviour on Blackberry JVM

Thanks, I'll have to look into that. I do know I was confused a few time recently building

java to test the BB app about what was going on in ctor and order with super() but again it

is usually just easier to design around it than care- that is anything odd in ctor always

creates issues- should  you throw and have no throw versions, etc. So, personally I try

to avoid doing anything in ctor and then vft validity doesn't matter unless it is still

not right after ctor exits ( which would be quite a gross bug LOL).

 

I do recall vaguely some oddities with string storage although I remember we

used them to store numerical data for an ACELP table as it seemed to be better than

numerical arrays fwiw.