When to "pre-load" classes?

29 views
Skip to first unread message

Udo

unread,
May 10, 2012, 2:47:34 PM5/10/12
to Java2Script
I ran into an error

TypeError: 'undefined' is not a constructor (evaluating 'new
java.util.Properties ()')

when running this code:

ClazzLoader.loadClass ("com.example.DemoApplet", function () {
var applet = new com.example.DemoApplet();
});

Somewhere down the constructor the Properties class is used but not
found.

However when I explicitly load the Properties class prior to my class
everything is fine:

ClazzLoader.loadClass ("java.util.Properties");
ClazzLoader.loadClass ("com.example.DemoApplet", function () {
var applet = new com.example.DemoApplet();
});


I thought referenced classes were loaded "on demand", without the need
to explicitly load them. Are there any rules I have to observe to make
this "automatic class loading" happen?


Udo

Zhou Renjian

unread,
May 10, 2012, 7:29:16 PM5/10/12
to java2...@googlegroups.com
What is your Java source?

Java2Script has supported loading class automatically. If not, it is considered as a bug.

Regards,
Zhou Renjian





Udo

--
You received this message because you are subscribed to the Google Groups "Java2Script" group.
To post to this group, send email to java2...@googlegroups.com.
To unsubscribe from this group, send email to java2script...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/java2script?hl=en.


Udo

unread,
May 11, 2012, 2:32:21 AM5/11/12
to Java2Script
Hi Renjian,

> What is your Java source?
it is a quite big piece of proprietary software.

I will try to come up with a simpler/smaller test case that shows the
problem.

Udo

Udo

unread,
May 11, 2012, 3:52:04 AM5/11/12
to Java2Script
Hi Renjian,

here a simple test case to reproduce the issue. It involves three
classes (all in separate files):

public class Foo implements Moo {
private static Bar bar = init();

private static Bar init() {
return new Bar();
}
}

public interface Moo {
}

public class Bar {
}

Running this script:

ClazzLoader.packageClasspath ("java", "j2slib/", true);
ClazzLoader.setPrimaryFolder ("build/classes/");

ClazzLoader.loadClass ("org.abego.j2s.loadClassBug.Foo", function ()
{
var foo = new org.abego.j2s.loadClassBug.Foo();
});

results in the error:

TypeError: 'undefined' is not a constructor (evaluating 'new
org.abego.j2s.loadClassBug.Bar ()')


(Using Java2Script 2.0.0 v20100601 (Eclipse 3.6.*), MacOSX 10.6.8,
Safari 5.1.7)

You can see this bug "in action" at:

http://www.abego.org/j2s/J2SLoadClassBug/index.html


Udo

Udo

unread,
May 11, 2012, 3:59:55 AM5/11/12
to Java2Script
You can get the sources for the test case here:

http://www.abego.org/j2s/J2SLoadClassBug/J2SLoadClassBug-src.zip

Udo

Zhou Renjian

unread,
May 11, 2012, 5:03:55 AM5/11/12
to java2...@googlegroups.com
Hi Udo,

Thanks for reporting your problems.

We consider this bug as a Java2Script defect. 

To avoid similar defects or bugs, try to add @J2SRequireImport annotations. e.g.

@J2SRequireImport(Bar.class)

public class Foo implements Moo {

...

or try to avoid use static initializer with static methods in Java2Script environments.

Java2Script compiler and loader do not calculate deep dependencies inside static initializers (it may be impossible to do so).

BTW: If intentionally written, static initializer may run into different branches in Java, as class loader may loading those classes and invoking initializers in different orders.


Regards,
Zhou Renjian

Udo

unread,
May 11, 2012, 7:03:29 AM5/11/12
to Java2Script
Hi Renjian,

thanks for your feedback.

Avoiding static initializer with static methods is not an optionm but
I will use the @J2SRequireImport feature.

Where do I find the library/jar file that defines these annotations? I
checked the "Eclipse 3.6" download zip and found nothing.

Udo

Zhou Renjian

unread,
May 11, 2012, 8:38:29 AM5/11/12
to java2...@googlegroups.com
The following annotations are functioned as those @j2s* Javadoc tags in http://j2s.sourceforge.net/articles/tutorial-advanced-programming-on-j2s.html
@J2SDebug
@J2SKeep
@J2SIgnore
@J2SIgnoreSuperConstructor
@J2SOverride
@J2SNative
@J2SNativeSrc
The last @J2SNativeSrc is same as @J2SNative. It is available for JavaScript obfuscate mode, which is not enabled be default. And we do not recommend to open obfuscate compiling mode for normal projects.


The following three annotations are about JavaScript class loader.

For a class A, class loader will try to load those classes that class A is dependent on before the class loader initialize class A. These classes are considered as "required imports". e.g. all super classes or interfaces, and all classes used in static initializer statements (not its static method invocations).  And then class loader will try to initialize those classes that class A will run into. These classes are considered as "optional imports". e.g. all new instances inside non-static methods, like "{ if (a) return new ClassC(); }", ClassC will only be loaded after all other classes are loaded and initialized.

Loading orders would simply be "required imports" -> main class -> "optional imports".

But in some cases, they won't be a linear order to load all classes. Classes may get cycle loading, which should be avoided and should be broken. So we introduce these annotations to reduce/break/fix imports.

@J2SIgnoreImport
ignoring all required imports and optional imports
@J2SRequireImport
add required import classes
@J2SOptionalImport
add optional import classes

The following two annotations are available for adding scripts before or after the generated *.js file.
@J2SSuffix
@J2SPrefix

All these annotations have their @j2s* Javadoc tags.

There is a j2stagsrc.zip file under plugins/net.sf.j2s.ajax_2.0.0/, contains all the above annotations.

You can <Ctrl/Command>+Click to navigator into those class, source should be attached with those classes.

Regards,
Zhou Renjian

Udo

unread,
May 15, 2012, 4:57:16 AM5/15/12
to Java2Script
Hi Renjian,

thanks for the info.

After compiling the sources from j2stagsrc.zip and linking to my
project I can now use the @J2SRequireImport annotation.

I added @J2SRequireImport to the classes I ran into problems and
everything is fine now. Thanks.


May I suggest to provide a pre-build jar file from the file
j2stagsrc.zip, e.g. "j2stags.jar". This way one only needs to add
"j2stags.jar" to the classpat to use the annotations. If you like you
can use this ant build script (https://gist.github.com/2700168) for
this purpose. Make sure to put the source file in the "src" directory.


BTW: I think the annotation "J2SIngoreSuperConstructor" has a typo:
"Ingore" instead of "Ignore".

Udo


On May 11, 2:38 pm, Zhou Renjian <zhourenj...@gmail.com> wrote:
> The following annotations are functioned as those @j2s* Javadoc tags inhttp://j2s.sourceforge.net/articles/tutorial-advanced-programming-on-...

Zhou Renjian

unread,
May 15, 2012, 5:14:36 AM5/15/12
to java2...@googlegroups.com
Thanks for pointing out the typo.

J2S* annotation jar file is already pre-built and embedded as net.sf.j2s.lib_2.0.0/j2stag.jar. Try to add variable "J2S_ANNOTATION" into your Libraries in Java Build Path. Or you can create a Java2Script AJAX or Servlet project using wizard. Those project will add *.jar containing J2S* annotations by default.

It is a bug that normal Java2Script project and Java2Script SWT project do not add J2S* annotations as referenced libraries. 

Regards,
Zhou Renjian

Udo

unread,
May 15, 2012, 4:49:20 PM5/15/12
to Java2Script
Thanks, I now added the variable "J2S_ANNOTATION" to my classpath.

Maybe you could mention this variable in the "Advanced Programming
Tutorial" (http://j2s.sourceforge.net/articles/tutorial-advanced-
programming-on-j2s.html) ?

Udo
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages