I tested the latest 1.8.2 code using the file upload example from Component Showcase against WebLogic 9.2 and WebLogic 10.3. I installed the application using both the Admin Console and the autodeploy directory. The only adjustment was to the web.xml file to use an absolute directory for uploading files:
<context-param>
<param-name>com.icesoft.faces.uploadDirectoryAbsolute</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>com.icesoft.faces.uploadDirectory</param-name>
<param-value>/[absolute-path]/upload</param-value>
</context-param>
The upload worked in all cases. I also double-checked the source code for the UploadServer class where getRealPath is invoked but ONLY if uploadDirectoryAbsolute is set to false:
// InputFile uploadDirectoryAbsolute attribute takes precedence,
// but if it's not given, then default to the
// com.icesoft.faces.uploadDirectoryAbsolute context-param
Boolean folderAbs = uploadConfig.getUploadDirectoryAbsolute();
if (!folderAbs.booleanValue())
{
folder = servletContext.getRealPath(folder);
}
So it appears that specifying an absolute directory path is a valid workaround on WebLogic (or any app server) where it's possible to deploy archives unexploded.
As some follow up information, I found the following link in the Oracle/BEA documentation:
http://download.oracle.com/docs/cd/E12840_01/wls/docs103/deployment/deployunits.html#wp1049133
The interesting part is in the section called "Using Exploded Archive Directories" where this is noted:
"In this case, the modules that perform the I/O operations should have a physical filesystem directory in which to work; you cannot obtain a file when the application is deployed as an archive, as per the specification."
So while we have a workaround for deployments that are not exploded, we may want to look for a way to remove the use of getRealPath altogether at some point.
The problems are related to the use of the ServletContext.getRealPath() method. The getRealPath() method does odd things on WebLogic. What happens is that, in WL 9 and 10, when you deploy a .war through the web console, it's doesn't unpack it but just uses it "as is". So all calls to getRealPath() return null because there are no real paths. Calls to get resource() return "zip://" type URLs pointing to entries in the .war file.
WebLogic has always had this problem (and some other less common app servers too like SAP's). Previously, to get around this, we used a different method:
final IdGenerator idGenerator = new IdGenerator(context.getResource("/WEB-INF/web.xml").getPath());
Of course this only helps for reading the value. If you need to write to the location (ie file upload), then it still might be an issue because the URL will be "zip://" instead of "file://" and it may not let you write at all.
In the end, we really shouldn't be using getRealPath() if we can avoid it. It's unreliable across app servers and it's not exposed by the JSF APIs (ExternalContext doesn't have a matching version of getRealPath). Perhaps getResourcePaths and some manipulation of the set that is returned or getResource().getPath. Of course, none of these may help if the .war file is not exploded during deployment.