From e71147c3f86f95a3eca0ad56d89f4f45a166cc54 Mon Sep 17 00:00:00 2001
From: Colin Alworth
Date: Wed, 8 Jan 2025 20:58:14 -0600
Subject: [PATCH 1/2] Quick draft
---
.../com/google/doctool/ResourceIncluder.java | 23 ++---------
.../gwt/dev/shell/BrowserChannelServer.java | 21 +---------
.../gwt/dev/util/GwtprojectOrgHelpInfo.java | 41 +++++++++++++++++++
.../gwt/dev/util/InstalledHelpInfo.java | 4 ++
.../src/doc/helpInfo/servletMappings.html | 7 +---
5 files changed, 51 insertions(+), 45 deletions(-)
create mode 100644 dev/core/src/com/google/gwt/dev/util/GwtprojectOrgHelpInfo.java
diff --git a/build_tools/doctool/src/com/google/doctool/ResourceIncluder.java b/build_tools/doctool/src/com/google/doctool/ResourceIncluder.java
index 71fe1a01d22..38905a2bce8 100644
--- a/build_tools/doctool/src/com/google/doctool/ResourceIncluder.java
+++ b/build_tools/doctool/src/com/google/doctool/ResourceIncluder.java
@@ -52,29 +52,12 @@ public static String getResourceFromClasspathScrubbedForHTML(String partialPath)
*/
private static String getFileFromClassPath(String partialPath)
throws IOException {
- InputStream in = ResourceIncluder.class.getClassLoader().getResourceAsStream(
- partialPath);
- try {
+ try (InputStream in = ResourceIncluder.class.getClassLoader().getResourceAsStream(partialPath);
+ ){
if (in == null) {
throw new FileNotFoundException(partialPath);
}
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int bytesRead;
- while (true) {
- bytesRead = in.read(buffer);
- if (bytesRead >= 0) {
- // Copy the bytes out.
- os.write(buffer, 0, bytesRead);
- } else {
- // End of input stream.
- break;
- }
- }
-
- return os.toString(StandardCharsets.UTF_8);
- } finally {
- close(in);
+ return new String(in.readAllBytes(), StandardCharsets.UTF_8);
}
}
diff --git a/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java b/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java
index a7f37326924..70f3361a06f 100644
--- a/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java
+++ b/dev/core/src/com/google/gwt/dev/shell/BrowserChannelServer.java
@@ -412,27 +412,8 @@ protected void processConnection() throws IOException, BrowserChannelException {
moduleName = oldLoadModule.getModuleName();
userAgent = oldLoadModule.getUserAgent();
protocolVersion = 1;
- HelpInfo helpInfo = new HelpInfo() {
- @Override
- public String getAnchorText() {
- return "UsingOOPHM wiki page";
- }
-
- @Override
- public URL getURL() {
- try {
- // TODO(jat): better landing page for more info
- return new URL(
- "http://code.google.com/p/google-web-toolkit/wiki/UsingOOPHM");
- } catch (MalformedURLException e) {
- // can't happen
- return null;
- }
- }
- };
logger.log(TreeLogger.WARN, "Connection from old browser plugin -- "
- + "please upgrade to a later version for full functionality", null,
- helpInfo);
+ + "please upgrade to a later version for full functionality");
break;
case CHECK_VERSIONS:
String connectError = null;
diff --git a/dev/core/src/com/google/gwt/dev/util/GwtprojectOrgHelpInfo.java b/dev/core/src/com/google/gwt/dev/util/GwtprojectOrgHelpInfo.java
new file mode 100644
index 00000000000..f7dfa779b0e
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/GwtprojectOrgHelpInfo.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2025 GWT Project Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.util;
+
+import com.google.gwt.core.ext.TreeLogger;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * Reference to a help document on the GWT project website.
+ */
+public class GwtprojectOrgHelpInfo extends TreeLogger.HelpInfo {
+ private URL url;
+
+ public GwtprojectOrgHelpInfo(String relativeUrl) {
+ try {
+ url = new URL("https://gwtproject.org" + relativeUrl);
+ } catch (MalformedURLException ignored) {
+ // ignore, url will be null
+ }
+ }
+
+ @Override
+ public URL getURL() {
+ return url;
+ }
+}
diff --git a/dev/core/src/com/google/gwt/dev/util/InstalledHelpInfo.java b/dev/core/src/com/google/gwt/dev/util/InstalledHelpInfo.java
index c8b39f2d677..2c49c1432ad 100644
--- a/dev/core/src/com/google/gwt/dev/util/InstalledHelpInfo.java
+++ b/dev/core/src/com/google/gwt/dev/util/InstalledHelpInfo.java
@@ -24,7 +24,11 @@
/**
* Help info based on the GWT installation directory.
+ *
+ * @deprecated Use {@link GwtprojectOrgHelpInfo} instead so that links work when users aren't using
+ * the GWT SDK zip.
*/
+@Deprecated
public class InstalledHelpInfo extends HelpInfo {
private URL url;
diff --git a/distro-source/core/src/doc/helpInfo/servletMappings.html b/distro-source/core/src/doc/helpInfo/servletMappings.html
index bad50eed871..d6e7b0d40a4 100644
--- a/distro-source/core/src/doc/helpInfo/servletMappings.html
+++ b/distro-source/core/src/doc/helpInfo/servletMappings.html
@@ -9,11 +9,8 @@
tags. These define Java Servlets that implement the server-side
component of a GWT-enabled web application.
-Prior to GWT 1.6, these GWT module servlet tags controlled the set of
-servlets were actually instantiated during hosted mode. But as of GWT 1.6, this
-is no longer true. Instead, the web application's WEB-INF/web.xml
-configuration file controls what servlets are instantiated. A GWT module
-specifies only what servlets are expected.
+
In modern GWT applications, these are only used for testing, and it is
+discouraged to use them in application code.
During hosted mode startup, the set of expected servlets (from GWT module
<servlet>
tags) is validated against the set of actual
From c6beedca31790425e9da37ce73416ee216a154dc Mon Sep 17 00:00:00 2001
From: "Ahmad K. Bawaneh"
Date: Thu, 9 Jan 2025 16:20:34 +0300
Subject: [PATCH 2/2] Update, migrate, improve log help links
Fix #10042
See also https://github.com/gwtproject/gwt-site/pull/386
---
.../com/google/doctool/ResourceIncluder.java | 23 ++++++--
dev/core/src/com/google/gwt/dev/DevMode.java | 4 +-
.../gwt/dev/javac/JSORestrictionsChecker.java | 12 ++---
.../gwt/dev/javac/JsniReferenceResolver.java | 6 +--
.../gwt/dev/shell/jetty/JettyLauncher.java | 4 +-
.../src/doc/helpInfo/jsoRestrictions.html | 54 -------------------
.../src/doc/helpInfo/longJsniRestriction.html | 42 ---------------
.../src/doc/helpInfo/servletMappings.html | 21 --------
.../src/doc/helpInfo/webAppClassPath.html | 39 --------------
9 files changed, 32 insertions(+), 173 deletions(-)
delete mode 100644 distro-source/core/src/doc/helpInfo/jsoRestrictions.html
delete mode 100644 distro-source/core/src/doc/helpInfo/longJsniRestriction.html
delete mode 100644 distro-source/core/src/doc/helpInfo/servletMappings.html
delete mode 100644 distro-source/core/src/doc/helpInfo/webAppClassPath.html
diff --git a/build_tools/doctool/src/com/google/doctool/ResourceIncluder.java b/build_tools/doctool/src/com/google/doctool/ResourceIncluder.java
index 38905a2bce8..71fe1a01d22 100644
--- a/build_tools/doctool/src/com/google/doctool/ResourceIncluder.java
+++ b/build_tools/doctool/src/com/google/doctool/ResourceIncluder.java
@@ -52,12 +52,29 @@ public static String getResourceFromClasspathScrubbedForHTML(String partialPath)
*/
private static String getFileFromClassPath(String partialPath)
throws IOException {
- try (InputStream in = ResourceIncluder.class.getClassLoader().getResourceAsStream(partialPath);
- ){
+ InputStream in = ResourceIncluder.class.getClassLoader().getResourceAsStream(
+ partialPath);
+ try {
if (in == null) {
throw new FileNotFoundException(partialPath);
}
- return new String(in.readAllBytes(), StandardCharsets.UTF_8);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while (true) {
+ bytesRead = in.read(buffer);
+ if (bytesRead >= 0) {
+ // Copy the bytes out.
+ os.write(buffer, 0, bytesRead);
+ } else {
+ // End of input stream.
+ break;
+ }
+ }
+
+ return os.toString(StandardCharsets.UTF_8);
+ } finally {
+ close(in);
}
}
diff --git a/dev/core/src/com/google/gwt/dev/DevMode.java b/dev/core/src/com/google/gwt/dev/DevMode.java
index 312f3eb9f44..8cd2cfd82f4 100644
--- a/dev/core/src/com/google/gwt/dev/DevMode.java
+++ b/dev/core/src/com/google/gwt/dev/DevMode.java
@@ -30,7 +30,7 @@
import com.google.gwt.dev.shell.jetty.JettyLauncher;
import com.google.gwt.dev.ui.RestartServerCallback;
import com.google.gwt.dev.ui.RestartServerEvent;
-import com.google.gwt.dev.util.InstalledHelpInfo;
+import com.google.gwt.dev.util.GwtprojectOrgHelpInfo;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.arg.ArgHandlerDeployDir;
import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
@@ -723,7 +723,7 @@ private void validateServletTags(TreeLogger logger, ServletValidator servletVali
TreeLogger servletLogger =
logger.branch(TreeLogger.DEBUG, "Validating tags for module '" + module.getName()
- + "'", null, new InstalledHelpInfo("servletMappings.html"));
+ + "'", null, new GwtprojectOrgHelpInfo("/doc/latest/gwt-dev-help/servletMappings.html"));
for (String servletPath : servletPaths) {
String servletClass = module.findServletForPath(servletPath);
assert (servletClass != null);
diff --git a/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java b/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java
index 2d249d39552..f5bda9b775b 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JSORestrictionsChecker.java
@@ -16,7 +16,7 @@
package com.google.gwt.dev.javac;
import com.google.gwt.dev.jdt.SafeASTVisitor;
-import com.google.gwt.dev.util.InstalledHelpInfo;
+import com.google.gwt.dev.util.GwtprojectOrgHelpInfo;
import com.google.gwt.dev.util.collect.Stack;
import org.eclipse.jdt.core.compiler.CharOperation;
@@ -43,16 +43,14 @@
* Check a compilation unit for violations of
* {@link com.google.gwt.core.client.JavaScriptObject JavaScriptObject} (JSO)
* restrictions. The restrictions are summarized in
- * jsoRestrictions.html
.
- *
- *
+ * @see jsoRestrictions.html.
* Any violations found are attached as errors on the
* CompilationUnitDeclaration.
*
* @see Overlay
* types design doc
- * @see jsoRestrictions.html
+ * @see jsoRestrictions.html
*/
public class JSORestrictionsChecker {
@@ -288,8 +286,8 @@ static String errAlreadyImplemented(String intfName, String impl1,
private static void errorOn(ASTNode node, CompilationUnitDeclaration cud,
String error) {
- GWTProblem.recordError(node, cud, error, new InstalledHelpInfo(
- "jsoRestrictions.html"));
+ GWTProblem.recordError(node, cud, error, new GwtprojectOrgHelpInfo(
+ "/doc/latest/DevGuideCodingBasicsJSNI.html"));
}
private final CompilationUnitDeclaration cud;
diff --git a/dev/core/src/com/google/gwt/dev/javac/JsniReferenceResolver.java b/dev/core/src/com/google/gwt/dev/javac/JsniReferenceResolver.java
index 5b3e0488932..c98ca1a2952 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JsniReferenceResolver.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JsniReferenceResolver.java
@@ -23,7 +23,7 @@
import com.google.gwt.dev.js.ast.JsFunction;
import com.google.gwt.dev.js.ast.JsModVisitor;
import com.google.gwt.dev.js.ast.JsNameRef;
-import com.google.gwt.dev.util.InstalledHelpInfo;
+import com.google.gwt.dev.util.GwtprojectOrgHelpInfo;
import com.google.gwt.dev.util.JsniRef;
import com.google.gwt.dev.util.collect.Stack;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
@@ -824,8 +824,8 @@ private boolean isUnsafeLongAnnotation(Annotation annot, ClassScope scope) {
}
private void longAccessError(ASTNode node, String message) {
- GWTProblem.recordError(node, cud, message, new InstalledHelpInfo(
- "longJsniRestriction.html"));
+ GWTProblem.recordError(node, cud, message, new GwtprojectOrgHelpInfo(
+ "/doc/latest/gwt-dev-help/longJsniRestriction.html"));
}
private static void resolveJsniRef(JsniRef jsniRef, FieldBinding fieldBinding) {
diff --git a/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java b/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java
index c5d3cbcccd9..771fa641134 100644
--- a/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java
+++ b/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java
@@ -19,7 +19,7 @@
import com.google.gwt.core.ext.ServletContainerLauncher;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.dev.util.InstalledHelpInfo;
+import com.google.gwt.dev.util.GwtprojectOrgHelpInfo;
import com.google.gwt.dev.util.Util;
import com.google.gwt.thirdparty.guava.common.collect.Iterators;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
@@ -447,7 +447,7 @@ private boolean addContainingClassPathEntry(String warnMessage,
}
branch = branch.branch(logLevel, "Adding classpath entry '"
+ classPathURL + "' to the web app classpath for this session",
- null, new InstalledHelpInfo("webAppClassPath.html"));
+ null, new GwtprojectOrgHelpInfo("/doc/latest/gwt-dev-help/webAppClassPath.html"));
try {
addClassPath(classPathURL);
return true;
diff --git a/distro-source/core/src/doc/helpInfo/jsoRestrictions.html b/distro-source/core/src/doc/helpInfo/jsoRestrictions.html
deleted file mode 100644
index b3ef73f8dc5..00000000000
--- a/distro-source/core/src/doc/helpInfo/jsoRestrictions.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-Restrictions on subclasses of JavaScriptObject
-
-
-Subclasses of JavaScriptObject represent a view of a JavaScript
-object from Java. Such classes must conform to a number of restrictions
-so that the compiler can implement them. This page lists those
-restrictions.
-In the following, "JSO class" means any subclass of JavaScriptObject
.
-Rationales are written like this.
-
- - All instance methods on JSO classes must be one of:
- explicitly final, a member of a final class, or private. Methods
- of JSO classes cannot be overridden, because calls to such methods
- could require dynamic dispatch.
- - An interface type may be implemented by at most one JSO
- subtype. This ensures that polymorphic dispatch via a
- "SingleJsoImpl" interface can be statically resolved to exactly one
- implementing JSO subtype.
-
- - A
JavaScriptObject
that implements a
- "SingleJsoImpl" interface may be further extended. The subclasses
- may implement additional "SingleJsoImpl" interfaces. The
- methods on a JSO must be effectively final, so each "SingleJsoImpl"
- method still has a 1:1 mapping to a method defined within a JSO
- subtype.
- - It is valid for any number of any non-
JavaScriptObject
- types to implement a "SingleJsoImpl" interface. There is a
- slight runtime dispatch penalty when a "SingleJsoImpl" interface is
- implemented by both JSO and non-JSO types.
-
-
- - No instance methods on JSO classes may override another
- method. This catches accidents where JSO itself did not
- finalize some method from its superclass.
- - JSO classes cannot have instance fields. The fields
- would have no place to live in web mode. Programmers should instead
- make an explicit wrapper class and put the fields there.
- - Nested JSO classes must be static. The implicit
this
- fields of a non-static inner class has the same problems as an
- explicit field.
- - "new" operations cannot be used with JSO classes. This
- avoids ever being able to try to instantiate JSO objects using the new
- keyword. New JSO instances can only come from JSNI, as in previous
- versions of GWT.
- - JSNI methods may not refer to instance methods defined within
- a
JavaScriptObject
.
- - Every JSO class must have precisely one constructor, and it
- must be protected, empty, and no-argument.
-
-
-
diff --git a/distro-source/core/src/doc/helpInfo/longJsniRestriction.html b/distro-source/core/src/doc/helpInfo/longJsniRestriction.html
deleted file mode 100644
index cbbb0335f94..00000000000
--- a/distro-source/core/src/doc/helpInfo/longJsniRestriction.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
- Restrictions on long values with JSNI
-
-
-
- The Java long
type cannot be represented in JavaScript
- as a numeric type, so GWT emulates it using an opaque data structure.
- This means that JSNI methods cannot process a long
as a
- numeric type. The compiler therefore disallows, by default, directly
- accessing a long
from JSNI: JSNI methods cannot have
- long
as a parameter type or a return type, and they
- cannot access a long
using a JSNI reference. If you
- find yourself wanting to pass a long
into or out of a
- JSNI method, here are some options:
-
-
-
- - For numbers that fit into type
double
, use type
- double
instead of type long
.
-
- - For computations that require the full
long
- semantics, rearrange the code so that the computations happen in
- Java instead of in JavaScript. That way they will use the
- long
emulation.
-
- - For values meant to be passed through unchanged to Java code,
- wrap the value in a
Long
. There are no restrictions
- on type Long
with JSNI methods.
-
- - If you are sure you know what you are doing, you can add the
- annotation
-
com.google.gwt.core.client.UnsafeNativeLong
to the
- method. The compiler will then allow you to pass a
- long
into and out of JavaScript. It will still be an
- opaque data type, however, so the only thing you will be able to
- do with it will be to pass it back to Java.
-
-
-
-
diff --git a/distro-source/core/src/doc/helpInfo/servletMappings.html b/distro-source/core/src/doc/helpInfo/servletMappings.html
deleted file mode 100644
index d6e7b0d40a4..00000000000
--- a/distro-source/core/src/doc/helpInfo/servletMappings.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-Servlet Mappings, GWT Modules, and web.xml
-
-
-
-GWT modules may declare one or more <servlet>
-tags. These define Java Servlets that implement the server-side
-component of a GWT-enabled web application.
-
-In modern GWT applications, these are only used for testing, and it is
-discouraged to use them in application code.
-
-During hosted mode startup, the set of expected servlets (from GWT module
-<servlet>
tags) is validated against the set of actual
-servlets (from the WEB-INF/web.xml
) and a warning is issued for
-each expected servlet which does not match an actual servlet.
-
-
-
diff --git a/distro-source/core/src/doc/helpInfo/webAppClassPath.html b/distro-source/core/src/doc/helpInfo/webAppClassPath.html
deleted file mode 100644
index 8932f64f5c7..00000000000
--- a/distro-source/core/src/doc/helpInfo/webAppClassPath.html
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-Web App Classpath Problem
-
-
-
-Web App Classpath Problem
-
-You were directed to this help topic because your server code needed a class or
-resource that was not found on the web app classpath, but was found
-on the system classpath. The system classpath is the classpath
-you specify when launching the Java VM to run hosted mode. The web app
-classpath is different — it consists of classes that live in your web
-application's war directory. All server classes and dependencies should
-to be placed in your war directory: libraries (jars) should be placed in
-war/WEB-INF/lib/
and classes that don't live in
-jars should be placed in war/WEB-INF/classes/
.
-
-
GWT hosted mode helpfully works around this problem by mapping these outside
-resources into your web app classpath. This warning reminds you that failing to
-address the issue can lead to problems when you actually deploy your web app to
-a real server.
-
-Tips
-
-
-- The most common reason to encounter this problem with a new project is
-using RPC, which tries to load
-
com.google.gwt.user.client.rpc.RemoteService
. The
-solution to is copy gwt-servlet.jar
from the GWT install directory
-into your web app's war/WEB-INF/lib/
directory.
-- If you have a good reason for not following the recommended configuration,
-you can suppress warning by setting the Java system property
-
gwt.nowarn.webapp.classpath
. Specify
--Dgwt.nowarn.webapp.classpath
as a JVM argument when
-launching hosted mode.
-
-