Re: How to (locally) disable method pruning by the GWT compiler?

105 views
Skip to first unread message

Manuel Carrasco Moñino

unread,
Oct 16, 2012, 1:48:53 AM10/16/12
to google-we...@googlegroups.com
AFAIK there is no a standard way to say the compiler which classes/methods leave in your js code except from using them, apart from obfuscate names, the compiler will remove any single method you dont use in your code, and even it could inline certain method calls.

Said that, I think a way to control that those methods remain in the compiled stuff although you dont use them is by using the gwt-exporter library as you point in your email. It will generate auxiliary code to expose the api wich will reference all the annotated methods and classes guaranteeing you that all that stuff will be in your compiled js modules. 
But what it isn't possible is that both separate GWT modules generate the same names and references inside the gwt classes, so although gwt-exporter allows exported methods which returns gwt objects, those objects would not be usable across modules.

In summary, what I would do is to use gwt-exporter in both modules to generate a js api of certain parts of your app, and consume that js api via jsni like any other external js library.

- Manolo

On Mon, Oct 15, 2012 at 12:06 PM, erik <m8r-y...@chammy.info> wrote:
Hey everyone,

I'm currently researching ways to implement communication between two separate GWT modules within a host page. I know it's generally possible using JSNI, exporting of Java functions (via gwt-exporter or manually) and overlay types (JavascriptObject and so on).
However, due to project circumstances I need to pass java objects between those modules that do NOT extend JavascriptObject. The reason is that I cannot introduce a GWT dependency into an otherwise non-GWT code base which is used for one of these modules. So far I only added classes around the actual code base that implement GWT-specific behaviour (mainly an EntryPoint class) and delegate to the underlying functionality.

By testing I found out that I can pass custom java objects between my modules if I make sure that the necessary methods for them are existing at the receiving side (I checked this by looking at and stepping through the generated javascript code.)
In my small sample application I forced the GWT-compiler to generate specific methods of a class by creating a dummy instance and calling its methods in onModuleLoad(). As soon as those were generated to javascript I could pass an object of the same type from another module and use its methods.
If I didn't create these dummies and "dummy"-use their methods the javascript code was not generated and it ended up calling null.nullMethod(). I believe this is due to the pruning phase during optimization steps of the compile process.

Long story, short question: Can I disable this pruning step for selected classes (or even methods) of my java classes?
Or is there another way to force the compiler to generate these methods to javascript?

With kind regards,
Erik

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/hNtg34rQf1sJ.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

erik

unread,
Oct 16, 2012, 2:42:34 AM10/16/12
to google-we...@googlegroups.com
Thank you for your thoughts, Manuel!

I've tested this some more yesterday and found out that using gwt-exporter isn't enough. The compiler will still prune any methods and class that doesn't seem to be used even if it was exported to JS.
The real problem here is that the compiler has strict rules about where "original" java objects can be obtained.
If the only way to get a reference to a java object of type X is an external call from JS (or another gwt module via jsni), the compiler will always remove this type and all it's methods. The JSNI documentation here is the key for me: "Java Object of the correct type that must have originated in Java code" ...

Following this description I've added an exported dummy method which returns a static object of type X. That way it's possible to have a reference to a java object in javascript and pass it back to java. However, I don't actually use this method. Instead I use a jsni call from my second gwt module which transfers a different object of the same type to my receiver module. Et voilà, it works!

Erik

Manuel Carrasco Moñino

unread,
Oct 16, 2012, 10:09:11 AM10/16/12
to google-we...@googlegroups.com
On Tue, Oct 16, 2012 at 8:42 AM, erik <m8r-y...@chammy.info> wrote:
Thank you for your thoughts, Manuel!

I've tested this some more yesterday and found out that using gwt-exporter isn't enough. The compiler will still prune any methods and class that doesn't seem to be used even if it was exported to JS.
The real problem here is that the compiler has strict rules about where "original" java objects can be obtained.
If the only way to get a reference to a java object of type X is an external call from JS (or another gwt module via jsni), the compiler will always remove this type and all it's methods. The JSNI documentation here is the key for me: "Java Object of the correct type that must have originated in Java code" ...

I think you have something wrong in your tests, if you annotate a class with @Export and it  implements Exportable, when you call GWT.create(...), or ExporterUtil.esportAll(), that class and all its methods will be available in the js outuput because gwt-exporter references those methods in the generated wrapper class.

 

Following this description I've added an exported dummy method which returns a static object of type X. That way it's possible to have a reference to a java object in javascript and pass it back to java. However, I don't actually use this method. Instead I use a jsni call from my second gwt module which transfers a different object of the same type to my receiver module. Et voilà, it works!


Erik

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
Reply all
Reply to author
Forward
0 new messages