TestServlet code that demonstrates issue:
{{{
import java.io.*;
import java.net.*;
import java.security.CodeSource;
import javax.servlet.ServletException;
import javax.servlet.http.*;
/**
- Sample servlet that illustrats JBoss problem with VFS and creating an URL to
- a file residing in the same location as the servlet jar file.
*
- @author jons
*/
public class TestServlet extends HttpServlet
{
private String mCodeSourceURL;
private String mTestFileURL;
private String mTestFileString;
private boolean mErrorOccurred;
public void init() throws ServletException
{
super.init();
}
/**
- This method illustrates the problem.
*/
private void loadTestFile()
{
try
{
// CodeSource.getLocation() returns an URL to the location of the jar file
// containing this class. In JBoss, the location is a VFS URL to the servlet
// jar file, but the URL has a trailing '/' after the jar name.
CodeSource cs = getClass().getProtectionDomain().getCodeSource();
URL csurl = cs.getLocation();
mCodeSourceURL = csurl.toString();
// Creating a new URL from the VFS jar location results in an incorrect URL
// to the test data file. With this URL constructor, a new URL is created
// by parsing the second parameter (the spec) in the context of the first
// parameter (the context). If the spec does not start with a slash, it's considered
// a relative location to the context, and the URL class will truncate the context
// at the last slash in order to determine the parent directory under which the
// relative filespec is located. In JBoss, the last slash is after the jar filename,
// resulting in an invalid URL to the test file.
URL testfileurl = new URL( csurl, "testfile.txt" );
mTestFileURL = testfileurl.toString();
// If URL is valid, read from it as an URLConnection inputstream.
URLConnection urlconn = testfileurl.openConnection();
InputStream is = urlconn.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
while( true )
{
final int numread = is.read( buffer, 0, buffer.length );
if( numread == -1 )
{
break;
}
baos.write( buffer, 0, numread );
}
mTestFileString = new String(baos.toByteArray());
is.close();
}
catch ( Exception e )
{
// If data cannot be read, make some pretty output for display
// in the browser page that's generated.
mErrorOccurred = true;
StringBuffer sb = new StringBuffer();
sb.append( "<b>" );
sb.append( e.getClass() );
sb.append( ": " );
sb.append( e.getMessage() );
sb.append( "</b>" );
sb.append( "<br/>" );
StackTraceElement[] stack = e.getStackTrace();
for ( int i = 0; i < stack.length; i++ )
{
StackTraceElement ste = stack[i];
sb.append( ste.toString() );
sb.append( "<br/>" );
}
mTestFileString = sb.toString();
}
}
/**
- doGet is invoked when a servlet request is made. Here, it's just used to call the method
- that illustrates the problem, then some data resulting from the test method is output
- to the browser page.
- @param request the request.
- @param response the response.
- @throws IOException on IOException
- @throws ServletException on ServletException
*/
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
mErrorOccurred = false;
loadTestFile();
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>TestServlet Results</title>");
out.println("</head>");
out.println("<body>");
out.println( "<h3>CodeSource URL</h3>" );
out.println( mCodeSourceURL );
out.println( "<h3>Test file URL</h3>" );
out.println( mTestFileURL );
if ( !mErrorOccurred )
{
out.println( "<h3>Test file data</h3>" );
out.println( mTestFileString );
}
else
{
out.println( "<h3>Error occurred</h3>");
out.println( mTestFileString );
}
out.println("</body>");
out.println("</html>");
}
}
}}}
Compile test servlet code, package TestServlet.class into a TestServlet.jar file. Create a TestServlet.war file containing these files:
WEB-INF/web.xml
WEB-INF/lib/TestServlet.jar
WEB-INF/lib/testfile.txt (a plain text file containing some random text is fine)
Deploy war file, visit url of web app, results displayed in browser page.