After reading all of the GWT Group threads concerning this, now well
known, problem and researching Java for processes I had hoped I would
never need to know, I have a solution. As others (e.g.,
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/c5f77dee8cc3ddb3/f1c07299a7c7ad15)
have done, I overrode RemoteServiceServlet.doGetSerializationPolicy.
My Java code is listed at the end of this post.
My web hosting site uses mod_jk to link Apache and Tomcat. Apache
sends requests like /servtet/* to Tomcat. Therefore, my Tomcat
servlets and my GWT developed web page live in (are served from)
different directories. My solution is to read the serialization
policy file directly from the policy file in my GWT web page, when a
request for /servlet/* is made.
I am not a big fan of overriding code that may/probably will change in
future GWT releases. For this reason, I would very much appreciate
someone from GWT to:
1. Tell me if my solution is OK. If not, suggest a better solution/
changes.
2. Consider a better solution to this issue. For example, why would
you ever want to get the policy file from anywhere but where the base
web page lives?
Thanks,
Danny
________________________________________________________
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.google.gwt.user.server.rpc.SerializationPolicy;
import com.google.gwt.user.server.rpc.SerializationPolicyLoader;
public class RemoteServiceServletSeparatePaths extends
RemoteServiceServlet {
protected SerializationPolicy doGetSerializationPolicy(
HttpServletRequest request, String moduleBaseURL, String
strongName) {
// The request can tell you the path of the web app relative to the
// container root.
SerializationPolicy serializationPolicy = null;
String serializationPolicyFilePath = "";
InputStream is = null;
String contextPath = request.getContextPath();
String modulePath = null;
if (moduleBaseURL != null) {
try {
modulePath = new URL(moduleBaseURL).getPath();
} catch (MalformedURLException ex) {
// log the information, we will default
getServletContext().log("Malformed moduleBaseURL: " +
moduleBaseURL, ex);
}
}
else { //Just quit, if we do not know the module base. (07/11/08 -
Danny)
return serializationPolicy;
}
//Disregard same web source. (07/11/08 - Danny)
if (modulePath == null ) {
String message = "ERROR: The module path requested, "
+ modulePath
+ ", is null, "
+ contextPath
+ ". Your module may not be properly configured or your client
and server code maybe out of date.";
getServletContext().log(message);
} else {
//Set up input stream for serialization policy file, based on /
servlet call. (07/11/08 - Danny)
if(contextPath.equals("/servlet")) {
try {
URL baseURL = new URL(moduleBaseURL + strongName + ".gwt.rpc");
URLConnection baseURLConnection = baseURL.openConnection();
is = baseURLConnection.getInputStream();
}
catch(Exception ex) {
String message = "ERROR: Could not open policy file, "
+ modulePath
+ ", is null, "
+ contextPath
+ ". Your module may not be properly configured or your client
and server code maybe out of date."
+ " Exception=" + ex.toString();
getServletContext().log(message);
return serializationPolicy;
}
}
else {
// Strip off the context path from the module base URL. It should
be a
// strict prefix.
String contextRelativePath =
modulePath.substring(contextPath.length());
serializationPolicyFilePath =
SerializationPolicyLoader.getSerializationPolicyFileName(contextRelativePath
+ strongName);
// Open the RPC resource file read its contents.
is = getServletContext().getResourceAsStream(
serializationPolicyFilePath);
}
try {
if (is != null) {
try {
serializationPolicy =
SerializationPolicyLoader.loadFromStream(is, null);
} catch (ParseException e) {
getServletContext().log(
"ERROR: Failed to parse the policy file '"
+ serializationPolicyFilePath + "'", e);
} catch (IOException e) {
getServletContext().log(
"ERROR: Could not read the policy file '"
+ serializationPolicyFilePath + "'", e);
}
} else {
String message = "ERROR: The serialization policy file '"
+ serializationPolicyFilePath
+ "' was not found; did you forget to include it in this
deployment?";
getServletContext().log(message);
}
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// Ignore this error
}
}
}
}
return serializationPolicy;
}
}