From 94e663964f2c9faf3354837194ed9b0231cf0adc Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sun, 13 Apr 2025 13:46:20 +0200 Subject: [PATCH 1/2] Update HtmlUnit to 4.11.1, update necessary dependencies --- .github/workflows/full-check.yml | 3 +- .github/workflows/quick-check.yml | 3 +- dev/build.xml | 55 ++++++++++--------- .../gwt/dev/shell/HostedModePluginObject.java | 20 +++---- .../gwt/dev/shell/HtmlUnitSessionHandler.java | 42 +++++--------- .../com/google/gwt/dev/shell/JavaObject.java | 10 ++-- .../impl/SelectionScriptJavaScriptTest.java | 12 ++-- maven/poms/gwt/gwt-dev/pom-template.xml | 2 +- maven/poms/gwt/pom-template.xml | 4 +- .../google/gwt/junit/RunStyleHtmlUnit.java | 52 +++++++++--------- .../gwt/emultest/java/util/DateTest.java | 6 +- 11 files changed, 100 insertions(+), 109 deletions(-) diff --git a/.github/workflows/full-check.yml b/.github/workflows/full-check.yml index 2e7a2644bc7..27bf3b861f3 100644 --- a/.github/workflows/full-check.yml +++ b/.github/workflows/full-check.yml @@ -31,7 +31,8 @@ jobs: - name: Checkout GWT tools into a sibling directory uses: actions/checkout@v4 with: - repository: 'gwtproject/tools' + repository: 'zbynek/tools' + ref: 'htmlunit-4' path: 'tools' - name: Set up JDK ${{ matrix.java-version }} # GWT requires Java 11+ to build diff --git a/.github/workflows/quick-check.yml b/.github/workflows/quick-check.yml index 09977bd4d68..fcdd80d0378 100644 --- a/.github/workflows/quick-check.yml +++ b/.github/workflows/quick-check.yml @@ -19,7 +19,8 @@ jobs: - name: Checkout GWT tools into a sibling directory uses: actions/checkout@v4 with: - repository: 'gwtproject/tools' + repository: 'zbynek/tools' + ref: 'htmlunit-4' path: 'tools' - name: Set up JDK ${{ matrix.java-version }} # GWT presently requires Java 11+ to build diff --git a/dev/build.xml b/dev/build.xml index 28846480959..bf5c0354c8e 100755 --- a/dev/build.xml +++ b/dev/build.xml @@ -85,19 +85,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -155,20 +156,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/dev/core/src/com/google/gwt/dev/shell/HostedModePluginObject.java b/dev/core/src/com/google/gwt/dev/shell/HostedModePluginObject.java index 98d5051d8f9..c9e3fff8d18 100644 --- a/dev/core/src/com/google/gwt/dev/shell/HostedModePluginObject.java +++ b/dev/core/src/com/google/gwt/dev/shell/HostedModePluginObject.java @@ -17,17 +17,15 @@ import com.google.gwt.core.ext.TreeLogger; -import com.gargoylesoftware.htmlunit.WebClient; -import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine; -import com.gargoylesoftware.htmlunit.javascript.host.Window; - -import net.sourceforge.htmlunit.corejs.javascript.Context; -import net.sourceforge.htmlunit.corejs.javascript.Function; -import net.sourceforge.htmlunit.corejs.javascript.Scriptable; -import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject; +import org.htmlunit.WebClient; +import org.htmlunit.corejs.javascript.Context; +import org.htmlunit.corejs.javascript.Function; +import org.htmlunit.corejs.javascript.Scriptable; +import org.htmlunit.corejs.javascript.ScriptableObject; +import org.htmlunit.javascript.JavaScriptEngine; +import org.htmlunit.javascript.host.Window; import java.io.IOException; -import java.util.Collections; /** * HTMLUnit object that represents the hosted-mode plugin. @@ -193,8 +191,8 @@ public boolean connect(String url, String sessionKey, String address, // Object[] with a success boolean and a value, and HtmlUnit will guard against this. // The simplest way to do that here is to mark java.lang.Object as the java equivalent // of some JS type - the name of the type doesn't matter. - webClient.setActiveXObjectMap(Collections.singletonMap( - "GwtLegacyDevModeExceptionOrReturnValue", "java.lang.Object")); + // webClient.setActiveXObjectMap(Collections.singletonMap( + // "GwtLegacyDevModeExceptionOrReturnValue", "java.lang.Object")); try { HtmlUnitSessionHandler htmlUnitSessionHandler = new HtmlUnitSessionHandler( diff --git a/dev/core/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java b/dev/core/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java index 75abb3aea3c..aa172f6e4e7 100644 --- a/dev/core/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java +++ b/dev/core/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java @@ -23,23 +23,20 @@ import com.google.gwt.dev.shell.BrowserChannelClient.SessionHandlerClient; import com.google.gwt.dev.util.log.PrintWriterTreeLogger; -import com.gargoylesoftware.htmlunit.ScriptException; -import com.gargoylesoftware.htmlunit.ScriptResult; -import com.gargoylesoftware.htmlunit.WebClient; -import com.gargoylesoftware.htmlunit.WebWindow; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine; -import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable; -import com.gargoylesoftware.htmlunit.javascript.SimpleScriptableProxy; -import com.gargoylesoftware.htmlunit.javascript.host.Window; - -import net.sourceforge.htmlunit.corejs.javascript.ConsString; -import net.sourceforge.htmlunit.corejs.javascript.Context; -import net.sourceforge.htmlunit.corejs.javascript.Function; -import net.sourceforge.htmlunit.corejs.javascript.JavaScriptException; -import net.sourceforge.htmlunit.corejs.javascript.Scriptable; -import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject; -import net.sourceforge.htmlunit.corejs.javascript.Undefined; +import org.htmlunit.ScriptException; +import org.htmlunit.ScriptResult; +import org.htmlunit.WebClient; +import org.htmlunit.WebWindow; +import org.htmlunit.corejs.javascript.ConsString; +import org.htmlunit.corejs.javascript.Context; +import org.htmlunit.corejs.javascript.Function; +import org.htmlunit.corejs.javascript.JavaScriptException; +import org.htmlunit.corejs.javascript.Scriptable; +import org.htmlunit.corejs.javascript.ScriptableObject; +import org.htmlunit.corejs.javascript.Undefined; +import org.htmlunit.html.HtmlPage; +import org.htmlunit.javascript.JavaScriptEngine; +import org.htmlunit.javascript.host.Window; import java.util.Arrays; import java.util.HashMap; @@ -187,8 +184,6 @@ public ExceptionOrReturnValue invoke(BrowserChannelClient channel, Value thisObj Object obj = makeJsvalFromValue(jsContext, thisObj); if (obj instanceof ScriptableObject) { jsThis = (ScriptableObject) obj; - } else if (obj instanceof SimpleScriptableProxy) { - jsThis = ((SimpleScriptableProxy) obj).getDelegee(); } else { logger.log(TreeLogger.ERROR, "Unable to convert " + obj + " to either " + " ScriptableObject or SimpleScriptableProxy"); @@ -289,15 +284,6 @@ public Value makeValueFromJsval(Context jsContext, Object value) { return returnVal; } if (value instanceof Scriptable) { - if (value instanceof SimpleScriptableProxy) { - // HtmlUnit will return proxies to java for the window/document objects, - // so that those objects can work after navigating away from the page. - // However, GWTTestCase operates inside a single page session, so we - // can unwrap these proxies to get the real instance. Without doing - // this, the refToJsObject mapping would indicate that an object might - // not equal itself - value = ((SimpleScriptableProxy) value).getDelegee(); - } if (value instanceof ScriptableObject) { /* * HACK: check for native types like NativeString. NativeString is diff --git a/dev/core/src/com/google/gwt/dev/shell/JavaObject.java b/dev/core/src/com/google/gwt/dev/shell/JavaObject.java index 19a31f96042..86a91fcfa15 100644 --- a/dev/core/src/com/google/gwt/dev/shell/JavaObject.java +++ b/dev/core/src/com/google/gwt/dev/shell/JavaObject.java @@ -21,11 +21,11 @@ import com.google.gwt.dev.shell.BrowserChannel.SessionHandler.ExceptionOrReturnValue; import com.google.gwt.dev.shell.BrowserChannel.Value; -import net.sourceforge.htmlunit.corejs.javascript.Context; -import net.sourceforge.htmlunit.corejs.javascript.Function; -import net.sourceforge.htmlunit.corejs.javascript.Scriptable; -import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject; -import net.sourceforge.htmlunit.corejs.javascript.Undefined; +import org.htmlunit.corejs.javascript.Context; +import org.htmlunit.corejs.javascript.Function; +import org.htmlunit.corejs.javascript.Scriptable; +import org.htmlunit.corejs.javascript.ScriptableObject; +import org.htmlunit.corejs.javascript.Undefined; import java.io.IOException; diff --git a/dev/core/test/com/google/gwt/core/ext/linker/impl/SelectionScriptJavaScriptTest.java b/dev/core/test/com/google/gwt/core/ext/linker/impl/SelectionScriptJavaScriptTest.java index b1b1e513cab..0bbc97169e4 100644 --- a/dev/core/test/com/google/gwt/core/ext/linker/impl/SelectionScriptJavaScriptTest.java +++ b/dev/core/test/com/google/gwt/core/ext/linker/impl/SelectionScriptJavaScriptTest.java @@ -18,14 +18,14 @@ import com.google.gwt.core.ext.linker.LinkerUtils; -import com.gargoylesoftware.htmlunit.AlertHandler; -import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; -import com.gargoylesoftware.htmlunit.MockWebConnection; -import com.gargoylesoftware.htmlunit.Page; -import com.gargoylesoftware.htmlunit.WebClient; - import junit.framework.TestCase; +import org.htmlunit.AlertHandler; +import org.htmlunit.FailingHttpStatusCodeException; +import org.htmlunit.MockWebConnection; +import org.htmlunit.Page; +import org.htmlunit.WebClient; + import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; diff --git a/maven/poms/gwt/gwt-dev/pom-template.xml b/maven/poms/gwt/gwt-dev/pom-template.xml index c8f34193507..70d0c0655ff 100644 --- a/maven/poms/gwt/gwt-dev/pom-template.xml +++ b/maven/poms/gwt/gwt-dev/pom-template.xml @@ -95,7 +95,7 @@ - net.sourceforge.htmlunit + org.htmlunit htmlunit diff --git a/maven/poms/gwt/pom-template.xml b/maven/poms/gwt/pom-template.xml index b165744e3e9..0e6d70be8d7 100644 --- a/maven/poms/gwt/pom-template.xml +++ b/maven/poms/gwt/pom-template.xml @@ -141,9 +141,9 @@ 63.1 - net.sourceforge.htmlunit + org.htmlunit htmlunit - 2.55.0 + 4.11.1 org.w3c.css diff --git a/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java b/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java index 73815427f5b..625cd45abb1 100644 --- a/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java +++ b/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java @@ -20,28 +20,26 @@ import com.google.gwt.thirdparty.guava.common.collect.ImmutableSet; import com.google.gwt.thirdparty.guava.common.collect.Maps; -import com.gargoylesoftware.htmlunit.AlertHandler; -import com.gargoylesoftware.htmlunit.BrowserVersion; -import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; -import com.gargoylesoftware.htmlunit.IncorrectnessListener; -import com.gargoylesoftware.htmlunit.OnbeforeunloadHandler; -import com.gargoylesoftware.htmlunit.Page; -import com.gargoylesoftware.htmlunit.ScriptException; -import com.gargoylesoftware.htmlunit.WebClient; -import com.gargoylesoftware.htmlunit.WebWindow; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine; -import com.gargoylesoftware.htmlunit.javascript.JavaScriptErrorListener; -import com.gargoylesoftware.htmlunit.javascript.host.Window; -import com.gargoylesoftware.htmlunit.util.WebClientUtils; - -import net.sourceforge.htmlunit.corejs.javascript.Context; -import net.sourceforge.htmlunit.corejs.javascript.Function; -import net.sourceforge.htmlunit.corejs.javascript.JavaScriptException; -import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.htmlunit.AlertHandler; +import org.htmlunit.BrowserVersion; +import org.htmlunit.FailingHttpStatusCodeException; +import org.htmlunit.IncorrectnessListener; +import org.htmlunit.OnbeforeunloadHandler; +import org.htmlunit.Page; +import org.htmlunit.ScriptException; +import org.htmlunit.WebClient; +import org.htmlunit.WebWindow; +import org.htmlunit.corejs.javascript.Context; +import org.htmlunit.corejs.javascript.Function; +import org.htmlunit.corejs.javascript.JavaScriptException; +import org.htmlunit.corejs.javascript.ScriptableObject; +import org.htmlunit.html.HtmlPage; +import org.htmlunit.javascript.JavaScriptEngine; +import org.htmlunit.javascript.JavaScriptErrorListener; +import org.htmlunit.javascript.host.Window; +import org.htmlunit.util.WebClientUtils; import java.io.IOException; import java.net.MalformedURLException; @@ -52,6 +50,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TimeZone; /** * Launches a web-mode test via HTMLUnit. @@ -105,6 +104,7 @@ public void run() { webClient.setAlertHandler(this); webClient.setIncorrectnessListener(this); webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); + webClient.getOptions().setFetchPolyfillEnabled(true); // To receive exceptions from js side in the development mode, we need set this to 'true'. // However, as htmlunit dies after throwing the exception, we still want it to be 'false' // for web mode. @@ -197,7 +197,7 @@ private static class HostedJavaScriptEngine extends JavaScriptEngine { private final WebClient webClient; private final TreeLogger logger; - public HostedJavaScriptEngine(WebClient webClient, TreeLogger logger) { + HostedJavaScriptEngine(WebClient webClient, TreeLogger logger) { super(webClient); this.webClient = webClient; this.logger = logger; @@ -223,7 +223,7 @@ private static class WebJavaScriptEngine extends JavaScriptEngine { private static final Log LOG = LogFactory.getLog(JavaScriptEngine.class); private final WebClient webClient; - public WebJavaScriptEngine(WebClient webClient) { + WebJavaScriptEngine(WebClient webClient) { super(webClient); this.webClient = webClient; } @@ -290,14 +290,16 @@ private void triggerOnError(Window w, ScriptException e) { private static final Map USER_AGENT_MAP = Maps.newHashMap(); static { - // “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0″ + // “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) + // Chrome/39.0.2171.71 Safari/537.36 Edge/12.0″ addBrowser(BrowserVersion.EDGE, "safari"); addBrowser(BrowserVersion.FIREFOX, "gecko1_8"); addBrowser(BrowserVersion.CHROME, "safari"); - addBrowser(BrowserVersion.INTERNET_EXPLORER, "gecko1_8"); } - private static void addBrowser(BrowserVersion browser, String userAgent) { + private static void addBrowser(BrowserVersion baseBrowser, String userAgent) { + BrowserVersion browser = new BrowserVersion.BrowserVersionBuilder(baseBrowser) + .setSystemTimezone(TimeZone.getDefault()).build(); BROWSER_MAP.put(browser.getNickname(), browser); USER_AGENT_MAP.put(browser, userAgent); } diff --git a/user/test/com/google/gwt/emultest/java/util/DateTest.java b/user/test/com/google/gwt/emultest/java/util/DateTest.java index 452e1f53f94..62ae7b2fb02 100644 --- a/user/test/com/google/gwt/emultest/java/util/DateTest.java +++ b/user/test/com/google/gwt/emultest/java/util/DateTest.java @@ -573,13 +573,15 @@ public void testToLocaleString() { // ///////////////////////////// Date accum1 = create(PAST); String a1 = accum1.toLocaleString(); - assertTrue(a1.indexOf("1890") != -1); + assertTrue(a1 + " should describe 1/5/1890", + a1.contains("1890") || a1.contains("1/5/90")); // ///////////////////////////// // Future // ///////////////////////////// Date accum2 = create(FUTURE); String a2 = accum2.toLocaleString(); - assertTrue(a2.indexOf("2030") != -1); + assertTrue(a2 + " should describe 12/30/2030", + a2.contains("2030") || a2.contains("12/30/2030")); } } From 808a9b2fc0904add418a72f134ec0459e3105cf5 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sun, 13 Apr 2025 22:09:49 +0200 Subject: [PATCH 2/2] Use local date, remove workarounds --- .../gwt/dev/shell/HostedModePluginObject.java | 9 -- .../google/gwt/junit/RunStyleHtmlUnit.java | 82 +------------------ .../gwt/emultest/java/util/DateTest.java | 11 ++- 3 files changed, 10 insertions(+), 92 deletions(-) diff --git a/dev/core/src/com/google/gwt/dev/shell/HostedModePluginObject.java b/dev/core/src/com/google/gwt/dev/shell/HostedModePluginObject.java index c9e3fff8d18..c9aeaef5853 100644 --- a/dev/core/src/com/google/gwt/dev/shell/HostedModePluginObject.java +++ b/dev/core/src/com/google/gwt/dev/shell/HostedModePluginObject.java @@ -185,15 +185,6 @@ public boolean connect(String url, String sessionKey, String address, return false; } // TODO: add whitelist and default-port support? - - // We know that legacy dev mode is running, we need to tell HtmlUnit that it is safe - // to permit plain Java objects to leak into JS - the JavaObject type will return a - // Object[] with a success boolean and a value, and HtmlUnit will guard against this. - // The simplest way to do that here is to mark java.lang.Object as the java equivalent - // of some JS type - the name of the type doesn't matter. - // webClient.setActiveXObjectMap(Collections.singletonMap( - // "GwtLegacyDevModeExceptionOrReturnValue", "java.lang.Object")); - try { HtmlUnitSessionHandler htmlUnitSessionHandler = new HtmlUnitSessionHandler( window, jsEngine, webClient); diff --git a/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java b/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java index 625cd45abb1..4f060d985a8 100644 --- a/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java +++ b/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java @@ -20,8 +20,6 @@ import com.google.gwt.thirdparty.guava.common.collect.ImmutableSet; import com.google.gwt.thirdparty.guava.common.collect.Maps; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.htmlunit.AlertHandler; import org.htmlunit.BrowserVersion; import org.htmlunit.FailingHttpStatusCodeException; @@ -31,9 +29,6 @@ import org.htmlunit.ScriptException; import org.htmlunit.WebClient; import org.htmlunit.WebWindow; -import org.htmlunit.corejs.javascript.Context; -import org.htmlunit.corejs.javascript.Function; -import org.htmlunit.corejs.javascript.JavaScriptException; import org.htmlunit.corejs.javascript.ScriptableObject; import org.htmlunit.html.HtmlPage; import org.htmlunit.javascript.JavaScriptEngine; @@ -177,7 +172,7 @@ protected void setupWebClient(WebClient webClient) { treeLogger); webClient.setJavaScriptEngine(hostedEngine); } else { - JavaScriptEngine webEngine = new WebJavaScriptEngine(webClient); + JavaScriptEngine webEngine = new JavaScriptEngine(webClient); webClient.setJavaScriptEngine(webEngine); } if (System.getProperty("gwt.htmlunit.debug") != null) { @@ -207,85 +202,12 @@ private static class HostedJavaScriptEngine extends JavaScriptEngine { public void initialize(WebWindow webWindow, Page page) { // Hook in the hosted-mode plugin after initializing the JS engine. super.initialize(webWindow, page); - Window window = (Window) webWindow.getScriptableObject(); + Window window = webWindow.getScriptableObject(); window.defineProperty("__gwt_HostedModePlugin", new HostedModePluginObject(this, webClient, logger), ScriptableObject.READONLY); } } - /** - * JavaScriptEngine subclass that fixes a bug when calling {@code window.onerror}. - * Make sure to remove when updating HtmlUnit. - * - * @see HtmlUnit bug #1924 - */ - private static class WebJavaScriptEngine extends JavaScriptEngine { - private static final Log LOG = LogFactory.getLog(JavaScriptEngine.class); - private final WebClient webClient; - - WebJavaScriptEngine(WebClient webClient) { - super(webClient); - this.webClient = webClient; - } - - @Override - protected void handleJavaScriptException(ScriptException scriptException, - boolean triggerOnError) { - // XXX(tbroyer): copied from JavaScriptEngine to call below triggerOnError - // instead of Window's triggerOnError. - - // Trigger window.onerror, if it has been set. - final HtmlPage page = scriptException.getPage(); - if (triggerOnError && page != null) { - final WebWindow window = page.getEnclosingWindow(); - if (window != null) { - final Window w = (Window) window.getScriptableObject(); - if (w != null) { - try { - triggerOnError(w, scriptException); - } catch (final Exception e) { - handleJavaScriptException(new ScriptException(page, e, null), false); - } - } - } - } - final JavaScriptErrorListener javaScriptErrorListener = - webClient.getJavaScriptErrorListener(); - if (javaScriptErrorListener != null) { - javaScriptErrorListener.scriptException(page, scriptException); - } - // Throw a Java exception if the user wants us to. - if (webClient.getOptions().isThrowExceptionOnScriptError()) { - throw scriptException; - } - // Log the error; ScriptException instances provide good debug info. - LOG.info("Caught script exception", scriptException); - } - - private void triggerOnError(Window w, ScriptException e) { - // XXX(tbroyer): copied from HtmlUnit's javascript.host.Window - // with fix unwrapping the JS exception before passing it back to JS. - final Object o = w.getOnerror(); - if (o instanceof Function) { - final Function f = (Function) o; - final String msg = e.getMessage(); - final String url = e.getPage().getUrl().toExternalForm(); - final int line = e.getFailingLineNumber(); - - final int column = e.getFailingColumnNumber(); - - Object jsError = null; - if (e.getCause() instanceof JavaScriptException) { - jsError = ((JavaScriptException) e.getCause()).getValue(); - } - - Object[] args = new Object[]{msg, url, line, column, jsError}; - - f.call(Context.getCurrentContext(), w, w, args); - } - } - } - private static final Map BROWSER_MAP = Maps.newHashMap(); private static final Map USER_AGENT_MAP = Maps.newHashMap(); diff --git a/user/test/com/google/gwt/emultest/java/util/DateTest.java b/user/test/com/google/gwt/emultest/java/util/DateTest.java index 62ae7b2fb02..ba1507c0df4 100644 --- a/user/test/com/google/gwt/emultest/java/util/DateTest.java +++ b/user/test/com/google/gwt/emultest/java/util/DateTest.java @@ -571,17 +571,17 @@ public void testToLocaleString() { // ///////////////////////////// // Past // ///////////////////////////// - Date accum1 = create(PAST); + Date accum1 = createLocal("1/5/1890"); String a1 = accum1.toLocaleString(); assertTrue(a1 + " should describe 1/5/1890", a1.contains("1890") || a1.contains("1/5/90")); // ///////////////////////////// // Future // ///////////////////////////// - Date accum2 = create(FUTURE); + Date accum2 = createLocal("12/30/2030 3:4:5"); String a2 = accum2.toLocaleString(); assertTrue(a2 + " should describe 12/30/2030", - a2.contains("2030") || a2.contains("12/30/2030")); + a2.contains("2030") || a2.contains("12/30/30")); } } @@ -897,6 +897,11 @@ Date create(String s) { } } + Date createLocal(String s) { + // aligned with the TZ used in CI + return new Date(s + " GMT-8:00"); + } + private String createString(String s) { if (s.equals(FUTURE)) { return "12/30/2030 3:4:5 GMT";