0

I'm writing a couple of library classes that I am sharing between several projects. Some of these projects are plain-old Java and others are GWT applications. For some of these classes the exact implementation is different whether they need to run in GWT or in Java (Let's not get into exactly why, but just as one of many examples, Date.getMonth is deprecated in Java, but the Calendar replacement isn't available in GWT).

Is there a way to mark certain sections of code as pertaining to one or the other scenario?

I looked at using deferred binding and class-replacement in GWT, but that requires instantiation of classes using GWT.create() which isn't available for a plain-old Java app and will therefore lead to compile errors.

Markus A.
  • 12,349
  • 8
  • 52
  • 116

2 Answers2

2

Found a solution that works beautifully: the <super-source> tag in my library's .gwt.xml file!

Basically, I have two versions of the following EnvironmentFlags class in my library. One in the actual library that is used by Java located in folder "lib":

my.library.EnvironmentFlags looks like this:

package my.library;

public class EnvironmentFlags {
  public static final boolean IS_GWT      = false;
  public static final boolean IS_DEV_MODE = false;
}

And then a file in the folder "super/my/library" that looks like this:

package my.library;

import com.google.gwt.core.client.GWT;

public class EnvironmentFlags {
  public static final boolean IS_GWT      = true;
  public static final boolean IS_DEV_MODE = !GWT.isProdMode();
}

Now the magic: The .gwt.xml file of my library looks like this:

<module>
  <source       path='lib'   />
  <super-source path='super' />
</module>

This leads to plain-old Java using the first version of the EnvironmentFlags class, which simply sets both flags to false, while the GWT compiler replaces the source of that class with the second version loaded from the super-source directory, which sets the GWT flag to true and the DEV_MODE flag to whatever it gets from GWT.

Now, in my code I can simply use the following:

if (EnvironmentFlags.IS_GWT) {
  // Do GWT stuff
} else {
  // Do plain-old Java stuff
}

and both, the Java and the GWT compiler should drop the respective unreachable/unneeded code from the compiled result, i.e. no run-time overhead needed.

PS: The IS_DEV_MODE flag doesn't actually have anything to do with my original question. I just included it as a freebie which allows me to have my code act differently (more verbose, for example) depending on whether I am testing or deploying my GWT app.

Markus A.
  • 12,349
  • 8
  • 52
  • 116
  • I would replace `GWT.isProdMode` by `GWT.isClient` as mentioned above – Jean-Michel Garcia Oct 14 '12 at 20:58
  • @Jean-MichelGarcia: The isClient() would be for the IS_GWT flag, which I already have taken care of with the true/false constants and the class replacement. The second IS_DEV_MODE flag doesn't actually have anything to do with my original question, I just included it so I can also have my code act differently (more verbose errors, for example) depending on whether I am in GWT dev mode or GWT production mode. – Markus A. Oct 14 '12 at 21:04
0

Sounds like you could use the static GWT.isClient() which returns true if your code is running in GWT environment (Dev or Production) or false elsewhere. You'll have to include gwt-user.jar in your server classpath. For example, running the following in a JVM:

import com.google.gwt.core.shared.GWT;

public class Main {
    public static void main(String[] args) {
        System.out.println(GWT.isClient() ? "Running client-side." 
                : "Running server-side.");
    }
}

Will produce Running server-side. in your console.

Boris Brudnoy
  • 2,405
  • 18
  • 28
  • This won't be available in a non GWT environment – Jean-Michel Garcia Oct 14 '12 at 20:39
  • @Jean-MichelGarcia Reflection would be necessary. – FThompson Oct 14 '12 at 20:52
  • @Jean-MichelGarcia see the edited answer, try it for yourself and retract the downvote. The class GWT is in the `shared` package for a reason. – Boris Brudnoy Oct 14 '12 at 20:56
  • @Boris-Brudnoy, OK If you mention the GWT dep. I was thinking that he was trying to avoid the use of GWT in his non GWT code – Jean-Michel Garcia Oct 14 '12 at 21:01
  • I was trying to avoid the dependency, yes. But still it would be a working solution. The question I would have about it: Can the Java compiler drop code based on the isClient() function call's result? (Not sure how far the compile-time evaluation goes there) – Markus A. Oct 14 '12 at 21:06