Tuesday, May 30, 2017

Re: Code references between client/server/shared folders

my understanding of the typical folders in a GWT project is this:
  • client
    only client-side code here
  • server
    only server-side code here
  • shared
    code that may be used on client-side and server-side
It is just a convention, you can generally use whatever folders you want to organize your code. This convention has been made primarily for projects that have client/shared/server code in the same code base (the default project layout if you create one using the GWT Eclipse Plugin). Maven projects usually consists of multiple modules which makes this distinction via package names optional.

I believe that the code in the client folder gets compiled by the GWT compiler into JS only, while the code in the server folder gets compiled by javac into class files only.
Besides that, code in the shared folder gets compiled twice, once by the GWT compiler and once from javac.

Right, if you have made client/shared folder visible to the GWT compiler using the <source path="..."/> tags in your *.gwt.xml file. If there isn't any such tag then <source path="client"/> will be assumed as a default by GWT compiler.

My understanding always was that the code in the shared folder must be "pure" java, so that it can be compiled in both worlds, without any references into pure client-side code.

Generally yes, but you could also use Java classes that GWT does not understand out of the box. You would then mark code as @GwtIncompatible if you don't need it on the client or you provide a super-source implementation. For the past GWT releases a good example might be ConcurrentMap which GWT does not support out of the box but might be useful in a shared class.

So far so good. But what happens, when code in the shared folder references some classes in the client folder?
I have just found such an example in my projects:
  • There is a class Move that represents a move in a chess game.
    It's located in the shared folder, since it's used by the server and the client.
  • The class Move uses a class TimeFormatter (to format timestamps as "yyyy-mm-dd hh:mm:ss").
    It's located in the client code and in turn uses the class com.google.gwt.i18n.client.DateTimeFormat.
What happens, when the javac compiler sees the Move class?
What does it do with com.google.gwt.i18n.client.DateTimeFormat when compiling server-side code?

If will fail to compile if you don't have that class on your classpath. In your specific example if will probably work if you use GWT-RPC because then you need gwt-servlet.jar on your classpath which in turn contains this class (yes it is a bit weird to have a server jar with client classes in it but well).

Should I move TimeFormatter into the shared folder, too?
And one more step: Could you use the same time formatting code in client and server code?
(At the moment I use com.google.gwt.i18n.client.DateTimeFormat at the client and SimpleDateFormat.format at the client.)

You could make your TimeFormatter class the single source for time formatting in your project. In that case you would move it into your shared folder, implement it using SimpleDateFormat.format() and in addition provide a super-source version of TimeFormatter for GWT compiler which will use com.google.gwt.i18n.client.DateTimeFormat to implement the TimeFormatter API. Alternatively you could emulate SimpleDateFormat.format() by providing a super-source version of SimpleDateFormat. The whole approach is the same GWT itself uses to let you use all the emulated JRE classes in the browser.

Alternatively you could use com.google.gwt.i18n.shared.DateTimeFormat to implement your TimeFormatter class. Then it should work on server and client but then your server has an additional dependency to GWT, maybe you don't want that.

BTW: What's the "public" folder for? I saw it in some projects but not in the docs...

"public" folders are folders whose content will be copied by the GWT compiler to the GWT compile output folder without any modifications. If a project uses it then mostly for images (e.g. favicon.ico and the like), css, html. The name "public" is also just a convention and can be changed by adding <public path="some folder" /> to your *.gwt.xml file.

-- J.

You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment