20 Sep 2012, 1:32pm
gwt java:

13 comments




  • Anzeige
  • Using GWT’s DateTimeFormat in Server-Side Code

    I was work­ing on some util­ity 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. Within the GWT frame­work there is the DateTimeFormat class which seems to be sup­posed to do exactly that.

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

    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 definition…

    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 newly cre­ated 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) clearly pointed 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 officially.

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

    p.s. Unfor­tu­nately, it is not pos­si­ble to just over­write the method in a derived class because it’s a sta­tic method and pri­vate any­way.
    p.p.s. As sug­gested 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­ify this sug­ges­tion) In gen­eral, both ways of fix­ing this issue will cause that the date and time to be for­mated using the default locale rather than the user’s cur­rent locale, unfortunately.

    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­eral impres­sion of GWT so far?

    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 quickly — but also a few errors show up now an then. But there never was a show-stopper 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 medium-sized enter­prise envi­ron­ment and it worked quite well for me. You should also con­sider the fol­low­ing gen­eral points to decide in favor or against 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 integrated

    Cons
    * It’s based on Java again which is IMO to ver­bose. There is going to be Dart and some other 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 optional 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.

    Look at this one: https://code.google.com/p/google-web-toolkit/issues/detail?id=7671
    Seems they acknowl­edged the issue already. Or do you con­sider the issue you reported to be dif­fer­ent from that one there?

    27 Nov 2012, 3:59pm
    by John A. Tamplin


    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 likely 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 proper ren­der­ing of a date in the user’s locale.

    Hi John,

    Thanks for the insight. You are right that the fix described above should be con­sid­ered a hack, not a patch. ;)
    I’ll add a note about the issue you described to my post…

    3 Dec 2012, 8:29am
    by Alex T


    Hi. I’m sorry 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­ity of the com­piler to han­dle most things that we’ve thrown at it, and com­pared to other RIA frame­works (Dojo) GWT seems to have a low bug ratio.

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

    Cheers guys

    No wor­ries, the issue was resolved very quickly.

    Now I’m really 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 (mainly syn­tac­tic sugar) and mixins/traits plus oper­a­tor over­load­ing on top of it.

    13 May 2013, 10:29am
    by der­rick


    hullo Sven, how can i replace this file since I’m deal­ing with jars. I tried to type in the text but wasn’t possible.

    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­ify 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.

    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 DefaultDateTimeFormatInfo()) {};

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

    Or just
    pub­lic sta­tic 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 DateTimeFormatInfoImpl_en());
    }

    Hi Sergei,
    I think this is a nice alter­na­tive for the server-side, thanks! But to my knowl­edge, GWT does not sup­port reflec­tion on the client side, unfortunately.

    *name

    *e-mail

    web site

    leave a comment