开发者

Setting directory permissions for JSP/Tomcat/Windows [duplicate]

This question already has answers here: How to save generated file temporarily in servlet based web application (2 answers) Closed 6 years ago.

I have a web app consisting of some JSPs that were previously running on a Linux box. I need to get this running on a Windows XP SP3 machine running Tomcat 5.5.29. Most everything is working now but this one item: The app has a capability to write a configuration file to its Windows directory (i.e. C:\Program Files\Apache\Tomcat\webapps\myapp). But when it tries to do this, the app cannot open the FileOutputStream (returns null). If I drop off the path specifier, and just let it open the file, it successfully opens it in the Tomcat directory.

The first line fails, but the second one succeeds:

//  outputFile2 = new PrintWriter(new FileOutputStream(basePathName + "programAll.txt", false));
    outputFile2 = new PrintWriter(new FileOutputStream("programAll.txt", false));

Here is the code that creates the basePathName:

    String basePathName = getBaseFilePath();  
    ...
    public String getBaseFilePath()
            {
            String curDir = System.getProperty("catalina.home");  
            curDir = curDir + "/webapps/pubmed/"; 
            curDir = "file:///" + formatPathNameForOS(curDir);
            return curDir;
            }

   public String formatPathNameForOS(String pathName)
        {
        if (codeIsOnWindows())
            {
            pathName = pathName.replace('/','\\');
            }
        else
            {
            pathName = pathName.replace('\\','/');
            }
        return pathName;
    }

Here's the exception message:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException
    org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:460)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:373)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:321)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:257)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
root cause

java.lang.NullPointerException
    org.apache.jsp.updateMemberLists_jsp._jspService(updateMemberLists_jsp.java:1492)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:321)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:257)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)

Here's the stack trace:

Aug 6, 2010 1:20:39 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.NullPointerException
    at org.apache.jsp.updateMemberLists_jsp._jspService(updateMemberLists_jsp.java:1492)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:321)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:257)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
    at org.globus.tomcat.coyote.valves.HTTPSValve55.invoke(HTTPSValve55.java:45)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:873)
    at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
    at java.lang.Thread.run(Thread.java:595)

I've looked at the updateMembersLists_jsp.java, and here is the section where the null pointer is occurring:

//create a file to write to the output
PrintWriter outputFile2 = null;
try
    {
    outputFile2 = new PrintWriter(new FileOutputStream(basePathName + "programAll.txt", false));
//  outputFile2 = new PrintWriter(new FileOutputStream("programAll.txt", false));
    }
    catch (FileNotFoundException e)
        {
        out.write("<p><font color='red'>Error Saving</font></p>");
        }
outputFile2.print(output);  // THIS IS LINE 1492 -- NULL POINTER
outputFile2.close();
开发者_如何学JAVA

Also: We are now running Tomcat off of the root directory instead of Program Files. I have checked the basePathName and it is being calculated correctly.

Now I figured out that Tomcat's policy settings might need to be adjusted. I added the following lines to catalina.policy hoping it would set things right:

// The permissions granted to the pubmed webapp
grant codeBase "file:${catalina.home}/webapps/pubmed/-" {
        permission java.io.FilePermission "${catalina.home}/webapps/pubmed/-", "read, write";
        permission java.io.FilePermission "${catalina.home}/webapps/pubmed/*", "read, write";
};

This didn't seem to have any effect. The Windows user that tomcat is running under has read/write permissions on the pubmed directory. Aside from the fact that it seems questionable for this webapp to be writing files to its own directory, what am I missing?

Sean


Try obtaining the path in the following way:

String path = getServletContext().getRealPath("/");

This will convert your path (to your webapp) to the actual path on your disk.


You should not use relative paths in Java IO. The path would become relative to the current working directory which depends on how you started the webserver/webapplication. When Tomcat is started in Eclipse for example, it may be the Eclipse project directory. When Tomcat is started from CMD, it may be the currently opened folder in CMD. When Tomcat is started as service, it may be /bin folder of Tomcat. To determine it yourself, do as follows:

System.out.println(new File("programAll.txt").getAbsolutePath()); 

And you'll see that it's completely different than you'd expect.

You need to specify absolute paths instead. You can use ServletContext#getRealPath() to convert a webcontent-relative path to an absolute disk file system path.

String relativeWebPath = "programAll.txt";
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
output = new FileOutputStream(absoluteDiskPath);
// ...

The getServletContext() method is available inside every servlet.


That said, did you take into consideration that all modified files in the webcontent will be wiped/overriden whenever you redeploy/restart the webapp/server? If you'd like to have a bit more permanent storage, I strongly recommend to store them outside the webcontent (of course in an absolute path, e.g. /var/webapp/files or so).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜