Using GWT’s DateTimeFormat in Server-Side Code

I was work­ing on some util­i­ty class to for­mat dates. As the for­mat­ting is the same on server and client the same class should be used on both, server and client. With­in the GWT frame­work there is the DateTimeFormat class which seems to be sup­posed to do exact­ly that.

But despite being in the shared pack­age (com.google.gwt.i18n.shared.DateTimeFormat) using it in the server-side code caus­es

java.lang.UnsupportedOperationException: ERROR: GWT.create() is only usable in client code!  It cannot be called, for example, from server code. If you are running a unit test, check that your test case extends GWTTestCase and that GWT.create() is not called from within an initializer or constructor.

Hav­ing a look into the code of the DateTimeFormat class (which is part of the shared pack­age of the GWT frame­work, thus can be used on server and client) reveals there is an import of com.google.gwt.i18n.client.LocaleInfo. But this class is part of the client pack­age — thus, it can not be used in the server-side code. It’s unclear to me why this was done like that because it sim­ply can not work by def­i­n­i­tion…

Going down a bit fur­ther in the code of the DateTimeFormat class shows that the client pack­age class LocaleInfo is used only once like this:

private static DateTimeFormatInfo getDefaultDateTimeFormatInfo() {
  // MUSTFIX(jat): implement
  return LocaleInfo.getCurrentLocale().getDateTimeFormatInfo();
}

The line is marked as “MUSTFIX” but for some rea­son it has not been fixed yet.
There is a way to fix this issue that worked for me:

  • Copy the con­tent of DateTimeFormat to a new file in your own code
  • Remove the import of LocaleInfo
  • Chang­ing the fol­low­ing method (start­ing in line 656) like this:
private static DateTimeFormatInfo getDefaultDateTimeFormatInfo() {
  return new DefaultDateTimeFormatInfo();
}
  • And use this new­ly cre­at­ed class from now on in all your code.

The fix does not seem to cause any major harm, but as John A. Tam­plin (cf. his com­ment below) clear­ly point­ed out, apply­ing this fix will ren­der all dates using the default locale instead of using the user’s locale. Thus, this fix should be con­sid­ered a hack rather than a patch — but it does the trick until the bug has been fixed offi­cial­ly.

The hack can be applied quick­ly — or sim­ply down­load the fixed class here.

p.s. Unfor­tu­nate­ly, it is not pos­si­ble to just over­write the method in a derived class because it’s a sta­t­ic method and pri­vate any­way.
p.p.s. As sug­gest­ed in the com­ments, you might also ini­tial­ize the DateTimeFormat with a new DefaultDateTimeFormatInfo() as the sec­ond para­menter. (Please note that I did not ver­i­fy this sug­ges­tion) In gen­er­al, both ways of fix­ing this issue will cause that the date and time to be for­mat­ed using the default locale rather than the user’s cur­rent locale, unfor­tu­nate­ly.

13 Replies to “Using GWT’s DateTimeFormat in Server-Side Code”

  1. Thank you. Bump­ing in to a bug of this mag­ni­tude on the first day of using GWT does give me the spooks — how is your gen­er­al impres­sion of GWT so far?

    1. Hi Alex, I’d say it’s twofold.

      The evo­lu­tion of GWT is run­ning quite fast, thus, new fea­tures become avail­able quick­ly — but also a few errors show up now an then. But there nev­er was a show-stop­per I was not able to hack/fix/circumvent some­how until the offi­cial fix in the next release.

      To give some back­ground, I’m using GWT for about three years now in an medi­um-sized enter­prise envi­ron­ment and it worked quite well for me. You should also con­sid­er the fol­low­ing gen­er­al points to decide in favor or again­st GWT:

      Pro
      * It’s based on Java so you can use good IDEs like Eclipse and tools like refac­tor­ing; also Java code can be quite mod­u­lar and testable
      * Javascript libraries and Java libraries can be inte­grat­ed

      Cons
      * It’s based on Java again which is IMO to ver­bose. There is going to be Dart and some oth­er guys are work­ing on Scala for GWT — nut non of them seem to be in a posi­tion where GWT is already. Some of the issues with Java (not with GWT in that respect) might be solved with Java 8 and the it’s clo­sure solu­tion and option­al typ­ing.
      * You can wrap up your GWT app as a war file and deploy it e.g. on a Tom­cat. But as soon as you make use of GAE APIs or the Data­s­tore, you will become depen­dent on Google to some extend.

  2. It isn’t done because I sim­ply ran out of time before leav­ing Google. Things have been hec­tic get­ting up to speed at my new job, so it will like­ly be Christ­mas break before I can spend any more time on it.

    Note that your fix above will only use the default locale, and will not give the prop­er ren­der­ing of a date in the user’s locale.

  3. Hi. I’m sor­ry if I stirred emo­tions. It was sim­ply unfor­tu­nate that this was the first thing I bumped into. Svens fix worked well, and it’s been quite a smooth ride since. I must say that I’m impressed by the abil­i­ty of the com­pil­er to han­dle most things that we’ve thrown at it, and com­pared to oth­er RIA frame­works (Dojo) GWT seems to have a low bug ratio.

    I noticed too late that the bug was already report­ed, but now it’s marked as a dupli­cate, thanks for point­ing that out.

    Cheers guys

    1. No wor­ries, the issue was resolved very quick­ly.

      Now I’m real­ly look­ing for­ward to GWT with Java 8 (to be released next year)! The advan­tage of cod­ing server *and* client-side in the same lan­guage *and* shar­ing code remains, but you will also have clo­sures like in JavaScript (main­ly syn­tac­tic sug­ar) and mixins/traits plus oper­a­tor over­load­ing on top of it.

  4. hul­lo Sven, how can i replace this file since I’m deal­ing with jars. I tried to type in the text but wasn’t pos­si­ble.

    1. Hi Der­rick,

      I guess you mean a file in the JAR is refer­ring to the “bro­ken” class, right? In that case, the only option IMO is to use the source files instead of the JAR and mod­i­fy the respec­tive files (make them import the mod­i­fied DateTimeFormat class). But that gets the whole sit­u­a­tion even more messy, unfor­tu­natly. 🙁
      Until the orig­i­nal GWT DateTimeFormat class gets fixed, I’m afraid it’s the only way.

  5. Hi, you don’t have to copy-paste code of the Date­Time­For­mat, you can just extend it in fol­low­ing way:

    Date­Time­For­mat dtf = new DateTimeFormat(/* your pat­tern here*/, new Default­Date­Time­For­mat­In­fo()) {};

    // now use dtf to for­mat or parse no mat­ter if on client or server

  6. Or just
    pub­lic sta­t­ic com.google.gwt.i18n.shared.DateTimeFormat createGwtDTFormat(String pat­tern) throws Excep­tion
    {
    Con­struc­tor c = com.google.gwt.i18n.shared.DateTimeFormat.class
    .getDeclaredConstructor(String.class, DateTimeFormatInfo.class);
    c.setAccessible(true);
    return c.newInstance(pattern, new Date­Time­For­mat­In­foIm­pl_en());
    }

Leave a Reply

Your email address will not be published. Required fields are marked *