GWT and JavaRebel

5 views
Skip to first unread message

Miguel Ping

unread,
Jan 7, 2008, 10:33:47 AM1/7/08
to Google Web Toolkit Contributors
Hey,

Has anyone tried JavaRebel? It seems that they have extended the
HotSwap capabilities: http://www.zeroturnaround.com/javarebel/features/
I think this would be great it it were possible to use it with gwt's
hosted mode WITHOUT the -noserver option. I still haven't tried it
with the -noserver option... How hard it is to hack some gwt internal
stuff to pass javarebel's java agent to gwt's own tomcat?

mwaschkowski

unread,
Jan 7, 2008, 12:47:40 PM1/7/08
to Google Web Toolkit Contributors
I would love to see JavaRebel working with GWT, the slow hosting
environment seems like a perfect fit.

I have no affiliation with JavaRebel, but tried to get it to run in my
environment but couldn't. Would love to know the correct way to set it
up.

Thanks,

Mark

Toomas Römer

unread,
Jan 9, 2008, 3:44:06 AM1/9/08
to Google Web Toolkit Contributors
Hi

I just tried GWT and played around with the KitchenSink.

I started the GWT shell with the script. Loaded the app. Made
modifications to the source code (java files) and when clicked reload
I saw the changes instantly. So I guess behind the scenes GWT Shell
pickups the modifications and compiles the bytecode to javascript and
resends to the browser.

JavaRebel comes in handy when one needs to restart a container
(Weblogic,Tomcat, Eclipse ...) or reload an app to a container to see
new results, javarebel reloads the changed class files and the new
code is executed.

Have I misunderstood anything? Are there actually Java classes that
need to be reloaded at one point?

Toomas
ZeroTurnaround.com

Miguel Ping

unread,
Jan 9, 2008, 5:58:22 AM1/9/08
to Google-Web-Tool...@googlegroups.com
Hi,

I don't fully understand how the gw shell works behind the scenes. I know for sure that gwt compiler is based on source code, not bytecode. I'm also guessing that gwt compiler does not do incremental builds, because of the nature of optimizations (src is analyzed as a monolithic app).  Maybe some gwt team member can explain how the src is linked to the hosted browser (like does it involve compiling all the way to js? )?

What I want is to be able to add methods, variable instances, and all those features announced in javarebel's page without the need to reload the app (the app runs in a tomcat container, so if I understand correctly instead of restarting the container/app, java rebel would reload the class and update the code). I can already change some method body while debugging in eclipse, but some modifications are not possible with jvm hotswapping.

On Jan 9, 2008 8:44 AM, Toomas Römer <too...@gmail.com> wrote:

Hi

I just tried GWT and played around with the KitchenSink.

I started the GWT shell with the script. Loaded the app. Made
modifications to the source code (java files) and when clicked reload
I saw the changes instantly. So I guess behind the scenes GWT Shell
pickups the modifications and compiles the bytecode to javascript and
resends to the browser.

JavaRebel comes in handy when one needs to restart a container
(Weblogic,Tomcat, Eclipse ...) or reload an app to a container to see
new results, javarebel reloads the changed class files and the new
code is executed.

Have I misunderstood anything? Are there actually Java classes that
need to be reloaded at one point?

Toomas
ZeroTurnaround.com

Toomas Römer

unread,
Jan 9, 2008, 7:36:50 AM1/9/08
to Google-Web-Tool...@googlegroups.com
Hi

> I don't fully understand how the gw shell works behind the scenes. I know
> for sure that gwt compiler is based on source code, not bytecode. I'm also

My bad.

> nature of optimizations (src is analyzed as a monolithic app). Maybe some
> gwt team member can explain how the src is linked to the hosted browser
> (like does it involve compiling all the way to js? )?

This would be great. I'll see what I can read out of the source during
the next days.

> the code). I can already change some method body while debugging in eclipse,
> but some modifications are not possible with jvm hotswapping.

In the shell script there was no reference to running apps in debug
mode but my changes (added a new class and a method and a methodcall)
worked after hitting refresh in the browser so I don't know at the
moment how and when hotswap kicked in (if thats to blame to
propagating my changes).

Toomas

Miguel Ping

unread,
Jan 9, 2008, 7:43:06 AM1/9/08
to Google-Web-Tool...@googlegroups.com
I'm used to running things from eclipse (both in normal and debug mode), so I'm guessing that the shell script does not run in debug mode. I suspect a refresh reloads the application in its full.

John Tamplin

unread,
Jan 9, 2008, 11:41:06 AM1/9/08
to Google-Web-Tool...@googlegroups.com
On Jan 9, 2008 3:44 AM, Toomas Römer <too...@gmail.com> wrote:
I started the GWT shell with the script. Loaded the app. Made
modifications to the source code (java files) and when clicked reload
I saw the changes instantly. So I guess behind the scenes GWT Shell
pickups the modifications and compiles the bytecode to javascript and
resends to the browser.

The actual Java code is just running in your regular VM, so it requires your IDE to be able to swap out the classes with the new versions.  Eclipse can do this, but sometimes fails depending on the nature of the changes.  On top of that, classes with JSNI get re-written by the CompilingClassLoader to change the native methods into Java code that makes the calls into the JSVM.

JavaRebel comes in handy when one needs to restart a container
(Weblogic,Tomcat, Eclipse ...) or reload an app to a container to see
new results, javarebel reloads the changed class files and the new
code is executed.

In my home app, I run an embedded jetty for my server (using -noserver for hosted mode debugging), and Eclipse automatically hot-swaps the modified classes (which fails if you make major changes), so I don't have to reload the server there.  The only problem I have run into is if I change the initialization code it doesn't get rerun, so I have to manually restart my server anyway.  However, it takes less than a second (and doesn't impact the GWT hosted mode shell) so I don't really see much point.   I think after 1.5 we do need to look at ways to make the embedded server work this way, and some of the changes from Out-of-Process hosted mode will force rethinking the way that works anyway.

--
John A. Tamplin
Software Engineer, Google

John Tamplin

unread,
Jan 9, 2008, 11:43:44 AM1/9/08
to Google-Web-Tool...@googlegroups.com
On Jan 9, 2008 5:58 AM, Miguel Ping <migue...@gmail.com> wrote:
I don't fully understand how the gw shell works behind the scenes. I know for sure that gwt compiler is based on source code, not bytecode. I'm also guessing that gwt compiler does not do incremental builds, because of the nature of optimizations (src is analyzed as a monolithic app).  Maybe some gwt team member can explain how the src is linked to the hosted browser (like does it involve compiling all the way to js? )?

The GWT compiler is not run in hosted mode.  Your Java code runs as Java bytecode in your JVM, and the only thing that happens is the CompilingClassLoader takes methods with JSNI and rewrites them into Java code that talks to the JSVM.  The compiler is only run when you click on Compile/Browse.

Miguel Ping

unread,
Jan 9, 2008, 12:08:13 PM1/9/08
to Google-Web-Tool...@googlegroups.com
On Jan 9, 2008 4:41 PM, John Tamplin <j...@google.com> wrote:
On Jan 9, 2008 3:44 AM, Toomas Römer <too...@gmail.com> wrote:
I started the GWT shell with the script. Loaded the app. Made
modifications to the source code (java files) and when clicked reload
I saw the changes instantly. So I guess behind the scenes GWT Shell
pickups the modifications and compiles the bytecode to javascript and
resends to the browser.

The actual Java code is just running in your regular VM, so it requires your IDE to be able to swap out the classes with the new versions.  Eclipse can do this, but sometimes fails depending on the nature of the changes.
 
On top of that, classes with JSNI get re-written by the CompilingClassLoader to change the native methods into Java code that makes the calls into the JSVM.

JavaRebel comes in handy when one needs to restart a container
(Weblogic,Tomcat, Eclipse ...) or reload an app to a container to see
new results, javarebel reloads the changed class files and the new
code is executed.

In my home app, I run an embedded jetty for my server (using -noserver for hosted mode debugging), and Eclipse automatically hot-swaps the modified classes (which fails if you make major changes)

So, I suppose an agent like JavaRebel can cover some of the cases where regular hotswapping does not work (ex: adding new methods to classes or so).
 
, so I don't have to reload the server there.  The only problem I have run into is if I change the initialization code it doesn't get rerun, so I have to manually restart my server anyway. 
 
This is true for any solution, I guess.
 
However, it takes less than a second (and doesn't impact the GWT hosted mode shell) so I don't really see much point.   I think after 1.5 we do need to look at ways to make the embedded server work this way, and some of the changes from Out-of-Process hosted mode will force rethinking the way that works anyway.

--
John A. Tamplin
Software Engineer, Google



I still don't understand one thing:  when you use the  -noserver option you run the services from an outer servlet container/app server/etc. But in the gwt docs, It says you still have to copy the <module>.gwt.js and other .js files into the server's app dir. Are these .js files necessary only to let defer the resource serving to the servlet container ?

Can you explain what happens step-by-step? Like in this use case:

- user clicks on a button on a gwt module running within hosted mode
(... what happes here? is there NO javascript involved (with the exception of JSNI) in these steps?)
- breakpoint in eclipse is activated


John Tamplin

unread,
Jan 9, 2008, 1:20:26 PM1/9/08
to Google-Web-Tool...@googlegroups.com
On Jan 9, 2008 12:08 PM, Miguel Ping <migue...@gmail.com> wrote:
I still don't understand one thing:  when you use the  -noserver option you run the services from an outer servlet container/app server/etc. But in the gwt docs, It says you still have to copy the <module>.gwt.js and other .js files into the server's app dir. Are these .js files necessary only to let defer the resource serving to the servlet container ?

When you click Compile/Browse, the executed browser will fetch the same URL the hosted shell is pointed to.  So, you have to arrange that the JS files get served by your external server, as well as the host html page and any other resources.  In my case, I simply point my jetty instance to <src path>/www/<module name> so it is serving the same content that the tomcat instance would be using.

BTW, it sounds like the documentation is a bit out of date -- what is the URL of the page you are referring to?
 
Can you explain what happens step-by-step? Like in this use case:

This is a rather complicated area and I won't get into all the details.
 
- user clicks on a button on a gwt module running within hosted mode
(... what happes here? is there NO javascript involved (with the exception of JSNI) in these steps?)

Obviously the Javascript has to be running or you wouldn't see anything in the browser.

A brief overview:
  • the embedded browser is started with some native code hooks that make a window.external object available
  • the host page is loaded, and the startup script sees window.external exists, so it calls window.external.gwtOnLoad which eventually gets to BrowserWidgetMoz.gwtOnLoad (on Linux, similar on other platforms)
  • a bunch of magic happens, eventually leading to a call into your module's onModuleLoad
  • your Java code executes, and when it hits some JSNI code, the JS code is executed via the native code browser hookup (see LowLevelMoz, JsValueMoz, jni/linux/*, etc), and the JS code may make other Java calls (through wrapped Java objects) and will eventually return to Java code
- breakpoint in eclipse is activated

Nothing unusual happens here -- Java bytecode is being executed and the normal Java debugger interface is used to control execution.

Miguel Ping

unread,
Jan 9, 2008, 1:33:31 PM1/9/08
to Google-Web-Tool...@googlegroups.com
Thanks for the explanation. I'm guessing that the voodoo magick is all about  js <> java interaction. I'm also guessing that the DOM is key to almost everything. Finally, Im sure that I wont be looking into that magic details anytime soon :)

On Jan 9, 2008 6:20 PM, John Tamplin <j...@google.com> wrote:
On Jan 9, 2008 12:08 PM, Miguel Ping <migue...@gmail.com> wrote:
I still don't understand one thing:  when you use the  -noserver option you run the services from an outer servlet container/app server/etc. But in the gwt docs, It says you still have to copy the <module>.gwt.js and other .js files into the server's app dir. Are these .js files necessary only to let defer the resource serving to the servlet container ?

When you click Compile/Browse, the executed browser will fetch the same URL the hosted shell is pointed to.  So, you have to arrange that the JS files get served by your external server, as well as the host html page and any other resources.  In my case, I simply point my jetty instance to <src path>/www/<module name> so it is serving the same content that the tomcat instance would be using.

BTW, it sounds like the documentation is a bit out of date -- what is the URL of the page you are referring to?
 

Miguel Ping

unread,
Jan 9, 2008, 1:35:50 PM1/9/08
to Google-Web-Tool...@googlegroups.com
Sorry, my bad. I misinterpreted another url (non-gwt). The docs only state that the module's js must be on the client side (among other files).

mwaschkowski

unread,
Jan 10, 2008, 8:29:25 AM1/10/08
to Google Web Toolkit Contributors
Hi John,

Thanks for the explanations. Sounds like I need to setup the noserver
option for myself as I am restarting hosted mode quite a bit and its
fairly slow on my box. Would you mind posting the ant file you use to
build with (when deploying to jetty)?

Thanks,

Mark

On Jan 9, 11:41 am, "John Tamplin" <j...@google.com> wrote:
> On Jan 9, 2008 3:44 AM, Toomas Römer <toom...@gmail.com> wrote:
>
> > I started the GWT shell with the script. Loaded the app. Made
> > modifications to the source code (java files) and when clicked reload
> > I saw the changes instantly. So I guess behind the scenes GWT Shell
> > pickups the modifications and compiles the bytecode to javascript and
> > resends to the browser.
>
> The actual Java code is just running in your regular VM, so it requires your
> IDE to be able to swap out the classes with the new versions. Eclipse can
> do this, but sometimes fails depending on the nature of the changes. On top
> of that, classes with JSNI get re-written by the CompilingClassLoader to
> change the native methods into Java code that makes the calls into the JSVM.
>
> JavaRebel comes in handy when one needs to restart a container
>
> > (Weblogic,Tomcat, Eclipse ...) or reload an app to a container to see
> > new results, javarebel reloads the changed class files and the new
> > code is executed.
>
> In my home app, I run an embedded jetty for my server (using -noserver for
> hosted mode debugging), and Eclipse automatically hot-swaps the modified
> classes (which fails if you make major changes), so I don't have to reload
> the server there. The only problem I have run into is if I change the
> initialization code it doesn't get rerun, so I have to manually restart my
> server anyway. However, it takes less than a second (and doesn't impact the
> GWT hosted mode shell) so I don't really see much point. I think
> after 1.5we do need to look at ways to make the embedded server work

Toomas Römer

unread,
Jan 10, 2008, 9:12:49 AM1/10/08
to Google Web Toolkit Contributors
Hi

I played around with GWT and JavaRebel today and got them working
together. I had to modify the classloading of GWT a bit.

As I have no experience with GWT I don't know exactly the bottlenecks
in the development cycle. Could you give the integration a quick spin
and see if it does help anything? My little snippets we're speedy
enough without javarebel except for I had to click the reload in the
GWT browser wrapper :).

I've compiled the GWT trunk with some modified code and uploaded the
build results to http://www.zeroturnaround.com/downloads/gwtTrunkBuild.tar
It has the necessary gwt-dev-platform.jars and gwt-user.jar. I just
backupped the 1.4 jar's and overwrote the gwt-dev-linux.jar and gwt-
user.jar to get my examples to run with trunk. Probably the same works
for you too.

I've updated the development snapshot of javarebel and it is available
from http://www.zeroturnaround.com/download/

To enable JavaRebel you have to add "-noverify -javaagent:/path/to/
javarebel.jar" to VM arguments. In eclipse run page it is the second
tab named "Arguments" and second textarea from the top.

As I had to change the GWT classloader to an URLClassloader just make
sure that the yourGWTProject/bin is used for the classfiles in
Eclipse. Don't forget to set Eclipse to build files automatically.

Let me know, how it goes and we'll see if, how and when we can support
GWT.

Thanks,
Toomas

On Jan 7, 5:33 pm, Miguel Ping <miguel.p...@gmail.com> wrote:
> Hey,
>
> Has anyone triedJavaRebel? It seems that they have extended the
> HotSwap capabilities:http://www.zeroturnaround.com/javarebel/features/
> I think this would be great it it were possible to use it with gwt's
> hosted mode WITHOUT the -noserver option. I still haven't tried it
> with the -noserver option... How hard it is to hack some gwt internal
> stuff to passjavarebel'sjava agent to gwt's own tomcat?

John Tamplin

unread,
Jan 10, 2008, 11:36:55 AM1/10/08
to Google-Web-Tool...@googlegroups.com
On Jan 10, 2008 8:29 AM, mwaschkowski <mwasch...@gmail.com> wrote:
Thanks for the explanations. Sounds like I need to setup the noserver
option for myself as I am restarting hosted mode quite a bit and its
fairly slow on my box. Would you mind posting the ant file you use to
build with (when deploying to jetty)?

Actually I haven't written one yet -- I just jar up the class files from Eclipse's build :).  Aside from that, I just have a shell script which includes my server's jar, the jetty jars, the JDBC jars, etc.

-noserver is only going to help your speed in that you can restart the client and server portions separately -- if you have to restart because of structural changes to the client, then you will still need to restart with -noserver (although it might be slightly faster not starting up tomcat).

John Tamplin

unread,
Jan 10, 2008, 11:39:16 AM1/10/08
to Google-Web-Tool...@googlegroups.com
On Jan 10, 2008 9:12 AM, Toomas Römer <too...@gmail.com> wrote:
I played around with GWT and JavaRebel today and got them working
together. I had to modify the classloading of GWT a bit.

As I have no experience with GWT I don't know exactly the bottlenecks
in the development cycle. Could you give the integration a quick spin
and see if it does help anything? My little snippets we're speedy
enough without javarebel except for I had to click the reload in the
GWT browser wrapper :).

I've compiled the GWT trunk with some modified code and uploaded the
build results to http://www.zeroturnaround.com/downloads/gwtTrunkBuild.tar
It has the necessary gwt-dev-platform.jars and gwt-user.jar . I just

backupped the 1.4 jar's and overwrote the gwt-dev-linux.jar and gwt-
user.jar to get my examples to run with trunk. Probably the same works
for you too.

I've updated the development snapshot of javarebel and it is available
from http://www.zeroturnaround.com/download/

To enable JavaRebel you have to add "-noverify -javaagent:/path/to/
javarebel.jar" to VM arguments. In eclipse run page it is the second
tab named "Arguments" and second textarea from the top.

As I had to change the GWT classloader to an URLClassloader just make
sure that the yourGWTProject/bin is used for the classfiles in
Eclipse. Don't forget to set Eclipse to build files automatically.

Are you saying you replaced CompilingClassLoader with URLClassLoader?  If so, I don't see how this will work with JSNI code.

Could you post the diff of the changes you made rather than just the compiled jar?

Toomas Römer

unread,
Jan 10, 2008, 12:06:15 PM1/10/08
to Google-Web-Tool...@googlegroups.com
Hi

> Could you post the diff of the changes you made rather than just the
> compiled jar?

Sure, see attachment.

Toomas

diff.txt

mwaschkowski

unread,
Jan 11, 2008, 11:40:08 AM1/11/08
to Google Web Toolkit Contributors
OK thanks, I'll give it a try.

On Jan 10, 11:36 am, "John Tamplin" <j...@google.com> wrote:

Toomas Römer

unread,
Jan 24, 2008, 5:14:39 AM1/24/08
to Google-Web-Tool...@googlegroups.com
Hi

> OK thanks, I'll give it a try.

Any luck?

Toomas

mwaschkowski

unread,
Jan 24, 2008, 9:04:53 AM1/24/08
to Google Web Toolkit Contributors
Hi Toomas,

I was actually referring to trying the -noserver option, wasn't
planning on trying out the javarebel patch because of the concern from
John Tamplin.

John, would you mind commenting on whether or not the approach taken
for the patch is viable?

Thank you,

Mark

On Jan 24, 5:14 am, "Toomas Römer" <toom...@gmail.com> wrote:
> Hi
>
> > OK thanks, I'll give it a try.
>
> Any luck?
>
> Toomas
>

John Tamplin

unread,
Jan 24, 2008, 9:23:38 AM1/24/08
to Google-Web-Tool...@googlegroups.com
On Jan 24, 2008 9:04 AM, mwaschkowski <mwasch...@gmail.com> wrote:
John, would you mind commenting on whether or not the approach taken
for the patch is viable?

I have been busy trying to finish my parts for 1.5, but I will take a closer look at it when I get done with that in the next few days.

John Tamplin

unread,
Jan 25, 2008, 5:59:46 PM1/25/08
to Google-Web-Tool...@googlegroups.com
On Jan 24, 2008 9:04 AM, mwaschkowski <mwasch...@gmail.com> wrote:
John, would you mind commenting on whether or not the approach taken
for the patch is viable?

After looking at the patch and talking it over with the head of the tools team, we won't include something like this for 1.5.  The hosted mode changes have made it significantly faster both to start and to refresh (and also corrected some cache issues) so that should be sufficient for now.

We will keep it in mind for "instant hosted mode" in the release following 1.5 if we don't have something better.  If you wouldn't mind, please create an issue for it so we don't forget about it.

mwaschkowski

unread,
Jan 27, 2008, 8:02:21 AM1/27/08
to Google Web Toolkit Contributors
OK, you got it. see http://code.google.com/p/google-web-toolkit-incubator/issues/detail?id=44

I have built the latest version of gwt and hosted mode is much faster
with Toby's patch, so the motivation for using javarebel is reduced,
falling more into the 'nice to have' category really.

Thanks!

Mark

On Jan 25, 5:59 pm, "John Tamplin" <j...@google.com> wrote:

Scott Blum

unread,
Jan 27, 2008, 11:30:54 AM1/27/08
to Google-Web-Tool...@googlegroups.com
Am I wrong in thinking that issue should be filed in the main GWT project rather than the incubator?

Toomas Römer

unread,
Jan 27, 2008, 11:54:30 AM1/27/08
to Google-Web-Tool...@googlegroups.com
Hi

It was not meant as a proposed patch but as a test if one does get a
shorter turnaround when using JavaRebel with GWT. The integration can
be done in different ways but it is up to users' interest in it. From
the emails I see that the issue is not that important at this moment.

We are launching http://code.google.com/p/zt-oss/ this week which
includes a JavaRebel SDK that is meant for providing a simpler of way
of integrating rebel with different frameworks.

We will keep an eye on
http://code.google.com/p/google-web-toolkit-incubator/issues/detail?id=44
(or if it gets refiled under the main GWT project) and will come back
to it at one point.

Toomas

Reply all
Reply to author
Forward
0 new messages