diff --git a/user/src/com/google/gwt/user/server/rpc/AbstractRemoteServiceServlet.java b/user/src/com/google/gwt/user/server/rpc/AbstractRemoteServiceServlet.java index a21e4fb7a3..bca9fc8d27 100644 --- a/user/src/com/google/gwt/user/server/rpc/AbstractRemoteServiceServlet.java +++ b/user/src/com/google/gwt/user/server/rpc/AbstractRemoteServiceServlet.java @@ -19,7 +19,6 @@ import java.io.IOException; -import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -41,9 +40,8 @@ public AbstractRemoteServiceServlet() { * Standard HttpServlet method: handle the POST. Delegates to * {@link #processPost(HttpServletRequest, HttpServletResponse)}. * - * This doPost method swallows ALL exceptions, logs them in the - * ServletContext, and returns a GENERIC_FAILURE_MSG response with status code - * 500. + * This doPost method swallows ALL exceptions, logs them, + * and returns a GENERIC_FAILURE_MSG response with status code 500. */ @Override public final void doPost(HttpServletRequest request, @@ -106,9 +104,7 @@ protected void doUnexpectedFailure(Throwable e) { */ throw new RuntimeException("Unable to report failure", e); } - ServletContext servletContext = getServletContext(); - RPCServletUtils.writeResponseForUnexpectedFailure(servletContext, - getThreadLocalResponse(), e); + RPCServletUtils.writeResponseForUnexpectedFailure(getThreadLocalResponse(), e); } /** diff --git a/user/src/com/google/gwt/user/server/rpc/RPCServletUtils.java b/user/src/com/google/gwt/user/server/rpc/RPCServletUtils.java index 8a2a50fb01..c205a88b66 100644 --- a/user/src/com/google/gwt/user/server/rpc/RPCServletUtils.java +++ b/user/src/com/google/gwt/user/server/rpc/RPCServletUtils.java @@ -24,6 +24,8 @@ import java.nio.charset.StandardCharsets; import java.util.Locale; import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletContext; @@ -37,6 +39,8 @@ */ public class RPCServletUtils { + private static final Logger logger = Logger.getLogger(RPCServletUtils.class.getName()); + public static final String CHARSET_UTF8_NAME = "UTF-8"; /** @@ -319,12 +323,19 @@ public static boolean shouldGzipResponseContent(HttpServletRequest request, && exceedsUncompressedContentLengthLimit(responseContent); } + @Deprecated + public static void writeResponse(ServletContext servletContext, + HttpServletResponse response, String responseContent, boolean gzipResponse) + throws IOException { + writeResponse(response, responseContent, gzipResponse); + } + + /** * Write the response content into the {@link HttpServletResponse}. If * gzipResponse is true, the response content will * be gzipped prior to being written into the response. * - * @param servletContext servlet context for this response * @param response response instance * @param responseContent a string containing the response content * @param gzipResponse if true the response content will be gzip @@ -332,7 +343,7 @@ public static boolean shouldGzipResponseContent(HttpServletRequest request, * @throws IOException if reading, writing, or closing the response's output * stream fails */ - public static void writeResponse(ServletContext servletContext, + public static void writeResponse( HttpServletResponse response, String responseContent, boolean gzipResponse) throws IOException { @@ -363,7 +374,7 @@ public static void writeResponse(ServletContext servletContext, } if (caught != null) { - servletContext.log("Unable to compress response", caught); + logger.log(Level.SEVERE, "Unable to compress response", caught); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } @@ -378,18 +389,23 @@ public static void writeResponse(ServletContext servletContext, response.getOutputStream().write(responseBytes); } + @Deprecated + public static void writeResponseForUnexpectedFailure( + ServletContext servletContext, HttpServletResponse response, + Throwable failure) { + writeResponseForUnexpectedFailure(response, failure); + } + /** * Called when the servlet itself has a problem, rather than the invoked * third-party method. It writes a simple 500 message back to the client. * - * @param servletContext * @param response * @param failure */ public static void writeResponseForUnexpectedFailure( - ServletContext servletContext, HttpServletResponse response, - Throwable failure) { - servletContext.log("Exception while dispatching incoming RPC call", failure); + HttpServletResponse response, Throwable failure) { + logger.log(Level.SEVERE, "Exception while dispatching incoming RPC call", failure); // Send GENERIC_FAILURE_MSG with 500 status. // @@ -403,7 +419,7 @@ public static void writeResponseForUnexpectedFailure( response.getWriter().write(GENERIC_FAILURE_MSG); } } catch (IOException ex) { - servletContext.log( + logger.log(Level.SEVERE, "respondWithUnexpectedFailure failed while sending the previous failure to the client", ex); } diff --git a/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java b/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java index 1bd73e142e..d25733d9df 100644 --- a/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java +++ b/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java @@ -30,6 +30,8 @@ import java.text.ParseException; import java.util.HashMap; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -45,6 +47,8 @@ public class RemoteServiceServlet extends AbstractRemoteServiceServlet implements SerializationPolicyProvider { + private static final Logger logger = Logger.getLogger(RemoteServiceServlet.class.getName()); + /** * Loads a serialization policy stored as a servlet resource in the same * ServletContext as this servlet. Returns null if not found. @@ -62,7 +66,7 @@ static SerializationPolicy loadSerializationPolicy(HttpServlet servlet, modulePath = new URL(moduleBaseURL).getPath(); } catch (MalformedURLException ex) { // log the information, we will default - servlet.log("Malformed moduleBaseURL: " + moduleBaseURL, ex); + logger.log(Level.SEVERE, "Malformed moduleBaseURL: " + moduleBaseURL, ex); } } @@ -74,12 +78,12 @@ static SerializationPolicy loadSerializationPolicy(HttpServlet servlet, * this method. */ if (modulePath == null || !modulePath.startsWith(contextPath)) { - String message = "ERROR: The module path requested, " + String message = "The module path requested, " + modulePath + ", is not in the same web application as this servlet, " + contextPath + ". Your module may not be properly configured or your client and server code maybe out of date."; - servlet.log(message); + logger.log(Level.SEVERE, message); } else { // Strip off the context path from the module base URL. It should be a // strict prefix. @@ -98,11 +102,13 @@ static SerializationPolicy loadSerializationPolicy(HttpServlet servlet, null); if (serializationPolicy.hasClientFields()) { if (ENABLE_ENHANCED_CLASSES) { - servlet.log("WARNING: Service deserializes enhanced JPA/JDO classes, which is " + + logger.log(Level.WARNING, + "Service deserializes enhanced JPA/JDO classes, which is " + "unsafe. See https://github.com/gwtproject/gwt/issues/9709 for more " + "detail on the vulnerability that this presents."); } else { - servlet.log("ERROR: Service deserializes enhanced JPA/JDO classes, which is " + + logger.log(Level.SEVERE, + "Service deserializes enhanced JPA/JDO classes, which is " + "unsafe. Review build logs to see which classes are affected, or set " + ENABLE_GWT_ENHANCED_CLASSES_PROPERTY + " to true to allow using this " + "service. See https://github.com/gwtproject/gwt/issues/9709 for more " + @@ -111,17 +117,19 @@ static SerializationPolicy loadSerializationPolicy(HttpServlet servlet, } } } catch (ParseException e) { - servlet.log("ERROR: Failed to parse the policy file '" + logger.log(Level.SEVERE, + "Failed to parse the policy file '" + serializationPolicyFilePath + "'", e); } catch (IOException e) { - servlet.log("ERROR: Could not read the policy file '" + logger.log(Level.SEVERE, + "Could not read the policy file '" + serializationPolicyFilePath + "'", e); } } else { - String message = "ERROR: The serialization policy file '" + String message = "The serialization policy file '" + serializationPolicyFilePath + "' was not found; did you forget to include it in this deployment?"; - servlet.log(message); + logger.log(Level.SEVERE, message); } } finally { if (is != null) { @@ -260,8 +268,8 @@ public final SerializationPolicy getSerializationPolicy(String moduleBaseURL, if (serializationPolicy == null) { // Failed to get the requested serialization policy; use the default - log( - "WARNING: Failed to get the SerializationPolicy '" + logger.log(Level.WARNING, + "Failed to get the SerializationPolicy '" + strongName + "' for module '" + moduleBaseURL @@ -311,7 +319,8 @@ public String processCall(String payload) throws SerializationException { try { rpcRequest = RPC.decodeRequest(payload, delegate.getClass(), this); } catch (IncompatibleRemoteServiceException ex) { - log( + logger.log( + Level.SEVERE, "An IncompatibleRemoteServiceException was thrown while processing this call.", ex); return RPC.encodeResponseForFailedRequest(null, ex); @@ -350,12 +359,13 @@ public String processCall(RPCRequest rpcRequest) throws SerializationException { rpcRequest.getParameters(), rpcRequest.getSerializationPolicy(), rpcRequest.getFlags()); } catch (IncompatibleRemoteServiceException ex) { - log( + logger.log(Level.SEVERE, "An IncompatibleRemoteServiceException was thrown while processing this call.", ex); return RPC.encodeResponseForFailedRequest(rpcRequest, ex); } catch (RpcTokenException tokenException) { - log("An RpcTokenException was thrown while processing this call.", + logger.log(Level.SEVERE, + "An RpcTokenException was thrown while processing this call.", tokenException); return RPC.encodeResponseForFailedRequest(rpcRequest, tokenException); } @@ -364,9 +374,8 @@ public String processCall(RPCRequest rpcRequest) throws SerializationException { /** * Standard HttpServlet method: handle the POST. * - * This doPost method swallows ALL exceptions, logs them in the - * ServletContext, and returns a GENERIC_FAILURE_MSG response with status code - * 500. + * This doPost method swallows ALL exceptions, logs them, + * and returns a GENERIC_FAILURE_MSG response with status code 500. * * @throws ServletException * @throws SerializationException @@ -469,12 +478,12 @@ protected SerializationPolicy loadPolicyFromCodeServer(String url) { @Override public void logInfo(String message) { - RemoteServiceServlet.this.log(message); + logger.log(Level.INFO, message); } @Override public void logError(String message, Throwable throwable) { - RemoteServiceServlet.this.log(message, throwable); + logger.log(Level.SEVERE, message, throwable); } }; return CODE_SERVER_CLIENT.loadPolicy(url, adapter); @@ -541,7 +550,6 @@ private void writeResponse(HttpServletRequest request, boolean gzipEncode = RPCServletUtils.acceptsGzipEncoding(request) && shouldCompressResponse(request, response, responsePayload); - RPCServletUtils.writeResponse(getServletContext(), response, - responsePayload, gzipEncode); + RPCServletUtils.writeResponse(response, responsePayload, gzipEncode); } } diff --git a/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTest.java b/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTest.java index 0cd88ac545..a6d3a6c89a 100644 --- a/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTest.java +++ b/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTest.java @@ -96,7 +96,6 @@ public String getServletName() { } private class MockServletContext implements ServletContext { - private String messageLogged; public MockServletContext() { } @@ -190,7 +189,7 @@ public void log(String arg0) { } public void log(String arg0, Throwable arg1) { - messageLogged = arg0; + throw new UnsupportedOperationException(); } public void removeAttribute(String arg0) { @@ -329,7 +328,6 @@ public InputStream getResourceAsStream(String resource) { SerializationPolicy serializationPolicy = rss.doGetSerializationPolicy( mockRequest, "http://www.google.com/MyModule", "12345"); assertNull(serializationPolicy); - assertNotNull(mockContext.messageLogged); } /** @@ -337,8 +335,8 @@ public InputStream getResourceAsStream(String resource) { * {@link com.google.gwt.user.server.rpc.RemoteServiceServlet#doGetSerializationPolicy(javax.servlet.http.HttpServletRequest, java.lang.String, java.lang.String)}. * * This method tests that if the module path is in a different context than - * the RemoteServiceServlet which is processing the request, a message will be - * logged and null is returned for the SerializationPolicy. + * the RemoteServiceServlet which is processing the request, + * null is returned for the SerializationPolicy. */ public void testDoGetSerializationPolicy_ModuleInSeparateServlet() throws ServletException { @@ -353,7 +351,6 @@ public void testDoGetSerializationPolicy_ModuleInSeparateServlet() mockRequest.contextPath = "/foo"; SerializationPolicy serializationPolicy = rss.doGetSerializationPolicy( mockRequest, "http://www.google.com/MyModule", ""); - assertNotNull(mockContext.messageLogged); assertNull(serializationPolicy); }