gwt

Adding standard java classes that are missing in GWT


MOTIVATION

PROBLEM

QUESTION


Solution

  • Important note: Implementing java.lang.Thread will not give you threads in the browser, and there is no JS equivalent to setting the interrupted status on a thread (and thus causing interruptable IO or other operations to fail).

    As you noted in a comment, it probably makes more sense to guard some of your code with @GwtIncompatible instead - this tells the compiler to ignore a class/field/method. In some cases this will make other code no longer compiler, so use this approach carefully, so that there is some other way to interpret the code instead.


    To provide custom emulation for a class in GWT, first make sure that there is no custom emulation already. java.lang.Thread has no emulation today, so we pass that already. Next, make a package for the emulated sources in one of your own GWT modules - that is, next to the *.gwt.xml file, add a directory. There are certain conventions for this - typically your client-only code is in a package called client/, and your emulated code is in a package called super/.

    The .gwt.xml file then will need a reference to this package, with a line like

    <super-source path="super" />
    

    Then, in that package, you re-create the package structure to reflect the emulated class - a java/lang/Thread.java path in this case.

    Following the maven/gradle default directory structure, this will either go in src/main/java or src/main/resources - the class doesn't compile to bytecode, so some people prefer resources instead. Users of https://tbroyer.github.io/gwt-maven-plugin/ usually will instead prefer src/main/super, see that plugin's documentation for more details on how you might want to relocate those sources.

    Example using src/main/resources

    src/
      main/
        resources/
          com/
            mycompany/
              project/
                MyApp.gwt.xml
                super/
                  java/
                    lang/
                      Thread.java
                      InterruptedException.java
    

    Now you create Thread.java's contents, in a way that will satisfy your requirements, but also be compatible with GWT. Detecting problems in your source can be tricky here, since javac won't compile your code - take care to keep it simple, write tests, and/or carefully review your compile logs with strict or failOnError turned on.

    InterruptedException should be pretty clear to implement (so that you can subclass it). Thread is mildly more interesting, since it only requires two methods (going by your example code) - we can/should omit most of the others, or throw if they were called (so that you would get a runtime error instead of a compile-time error).

    package java.lang;
    
    public class Thread {
      private static final ONLY_THREAD = new Thread();
      public static Thread currentThread() {
        return ONLY_THREAD;
      }
      public void interrupt() {
        // Do nothing? Set a flag for other later calls to check?
      }
      // etc...
    }