[
https://issues.apache.org/jira/browse/WINK-187?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12756046#action_12756046
]
Kaloyan Kolev commented on WINK-187:
------------------------------------
The problem is not related to OSGi, but to the way we mangle the URI
identifier. Here is the problematic code in method :
{code}
public static InputStream loadFileAsStream(String fileName) throws
FileNotFoundException {
...
// decode any escaped sequences such as <space> which is %20 in
// URL
URI uri = url.toURI();
String path = uri.getSchemeSpecificPart();
url = new URL(url.getProtocol(), null, path);
...
}
{code}
As you can see the schema-specific-part is treated as a regular path which it
is not. This violates the URI specification. For more details please refer to
the URI specification here http://www.ietf.org/rfc/rfc2396.txt
My suggestion is simply to avoid dealing with URLs when that is not required.
At this point the external code has requested an InputStream object and since
we have an API for accessing that through the classloaders we could return that
directly. My suggestion also considers the context classloader set on the
thread. As you can see in the bellow code you have the same functionality as
before but this way you do one step less to get the same result.
These are new methods that need to be added:
{code}
/**
* open the specified resource using class loaders
*
* @param filename
* the name of the resource
* @return the resource as {...@link InputStream} if found
* @throws FileNotFoundException
* if the resource was not found
*/
private static InputStream openResourceUsingClassLoaders(String filename)
throws FileNotFoundException {
logger.debug("Searching for {} using thread context classloader.",
filename);
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
InputStream is = openResourceUsingClassLoader(classLoader, filename);
if (is == null) {
logger.debug("Searching for {} using current classloader.",
filename);
classLoader = FileLoader.class.getClassLoader();
is = openResourceUsingClassLoader(classLoader, filename);
if (is == null) {
logger.debug("Searching for {} using system
classloader.", filename);
is = ClassLoader.getSystemResourceAsStream(filename);
if (is == null) {
// well, the last attempt has failed! throw
// FileNotFoundException
logger.error("Failed to open resource using
classloaders");
throw new FileNotFoundException(filename);
}
}
}
return is;
}
private static InputStream openResourceUsingClassLoader(ClassLoader
classLoader, String filename) {
InputStream is = null;
if (classLoader != null) {
is = classLoader.getResourceAsStream(filename);
}
return is;
}
{code}
> org.apache.wink.common.internal.utils.FileLoader is not able to open a stream
> to existing File.
> -----------------------------------------------------------------------------------------------
>
> Key: WINK-187
> URL: https://issues.apache.org/jira/browse/WINK-187
> Project: Wink
> Issue Type: Bug
> Components: Common
> Affects Versions: 0.2
> Environment: IBM Lotus Expeditor's Web Container - LWI. It is loaded
> in Equinox OSGi framework.
> Reporter: Kaloyan Kolev
> Priority: Minor
> Fix For: 0.2
>
>
> It seems like the org.apache.wink.common.internal.utils.FileLoader is trying
> to locate the META-INF/wink-default.properties file using an OSGi class
> loader.
> This is the exception that is being produced:
> 31 [HttpServer : 0] ERROR org.apache.wink.common.internal.utils.FileLoader -
> No bundle ID found: bundleresource:////300/META-INF/wink-default.properties
> java.io.IOException: No bundle ID found:
> bundleresource:////300/META-INF/wink-default.properties
> at
> org.eclipse.osgi.framework.internal.core.BundleResourceHandler.openConnection(BundleResourceHandler.java:137)
> at java.net.URL.openConnection(URL.java:945)
> at java.net.URL.openStream(URL.java:1009)
> at
> org.apache.wink.common.internal.utils.FileLoader.loadFileAsStream(FileLoader.java:97)
> at
> org.apache.wink.server.internal.utils.ServletFileLoader.loadFileAsStream(ServletFileLoader.java:50)
> at
> org.apache.wink.server.internal.servlet.RestServlet.loadProperties(RestServlet.java:166)
> at
> org.apache.wink.server.internal.servlet.RestServlet.getProperties(RestServlet.java:125)
> at
> org.apache.wink.server.internal.servlet.RestServlet.getDeploymentConfiguration(RestServlet.java:119)
> at
> org.apache.wink.server.internal.servlet.RestServlet.createRequestProcessor(RestServlet.java:108)
> at
> org.apache.wink.server.internal.servlet.RestServlet.init(RestServlet.java:85)
> at
> com.ibm.di.tp.server.servlet.EntryPointServlet.init(EntryPointServlet.java:110)
> at javax.servlet.GenericServlet.init(GenericServlet.java:211)
> at
> com.ibm.di.tp.server.servlet.EntryPointServlet.init(EntryPointServlet.java:99)
> at
> com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:185)
> at
> com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:341)
> at
> com.ibm.pvc.internal.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:86)
> at
> com.ibm.pvc.internal.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:102)
> at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3124)
> at
> com.ibm.pvc.internal.webcontainer.webapp.BundleWebApp.handleRequest(BundleWebApp.java:451)
> at
> com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:235)
> at
> com.ibm.pvc.internal.webcontainer.VirtualHost.handleRequest(VirtualHost.java:96)
> at
> com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:811)
> at
> com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:41)
> at
> com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:464)
> at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:355)
> at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1498)
> 46 [HttpServer : 0] ERROR org.apache.wink.server.internal.servlet.RestServlet
> - META-INF/wink-default.properties
> java.io.FileNotFoundException: META-INF/wink-default.properties
> at
> org.apache.wink.common.internal.utils.FileLoader.loadFileAsStream(FileLoader.java:100)
> at
> org.apache.wink.server.internal.utils.ServletFileLoader.loadFileAsStream(ServletFileLoader.java:50)
> at
> org.apache.wink.server.internal.servlet.RestServlet.loadProperties(RestServlet.java:166)
> at
> org.apache.wink.server.internal.servlet.RestServlet.getProperties(RestServlet.java:125)
> at
> org.apache.wink.server.internal.servlet.RestServlet.getDeploymentConfiguration(RestServlet.java:119)
> at
> org.apache.wink.server.internal.servlet.RestServlet.createRequestProcessor(RestServlet.java:108)
> at
> org.apache.wink.server.internal.servlet.RestServlet.init(RestServlet.java:85)
> at
> com.ibm.di.tp.server.servlet.EntryPointServlet.init(EntryPointServlet.java:110)
> at javax.servlet.GenericServlet.init(GenericServlet.java:211)
> at
> com.ibm.di.tp.server.servlet.EntryPointServlet.init(EntryPointServlet.java:99)
> at
> com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:185)
> at
> com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:341)
> at
> com.ibm.pvc.internal.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:86)
> at
> com.ibm.pvc.internal.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:102)
> at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3124)
> at
> com.ibm.pvc.internal.webcontainer.webapp.BundleWebApp.handleRequest(BundleWebApp.java:451)
> at
> com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:235)
> at
> com.ibm.pvc.internal.webcontainer.VirtualHost.handleRequest(VirtualHost.java:96)
> at
> com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:811)
> at
> com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:41)
> at
> com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:464)
> at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:355)
> at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1498)
> Exception occured in com.ibm.ws.webcontainer.servlet.ServletInstance.service
> javax.servlet.UnavailableException: META-INF/wink-default.properties
> at
> org.apache.wink.server.internal.servlet.RestServlet.init(RestServlet.java:95)
> at
> com.ibm.di.tp.server.servlet.EntryPointServlet.init(EntryPointServlet.java:110)
> at javax.servlet.GenericServlet.init(GenericServlet.java:211)
> at
> com.ibm.di.tp.server.servlet.EntryPointServlet.init(EntryPointServlet.java:99)
> at
> com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:185)
> at
> com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:341)
> at
> com.ibm.pvc.internal.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:86)
> at
> com.ibm.pvc.internal.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:102)
> at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3124)
> at
> com.ibm.pvc.internal.webcontainer.webapp.BundleWebApp.handleRequest(BundleWebApp.java:451)
> at
> com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:235)
> at
> com.ibm.pvc.internal.webcontainer.VirtualHost.handleRequest(VirtualHost.java:96)
> at
> com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:811)
> at
> com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:41)
> at
> com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:464)
> at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:355)
> at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1498)
> Exception occured in
> com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest()
> javax.servlet.UnavailableException: META-INF/wink-default.properties
> at
> org.apache.wink.server.internal.servlet.RestServlet.init(RestServlet.java:95)
> at
> com.ibm.di.tp.server.servlet.EntryPointServlet.init(EntryPointServlet.java:110)
> at javax.servlet.GenericServlet.init(GenericServlet.java:211)
> at
> com.ibm.di.tp.server.servlet.EntryPointServlet.init(EntryPointServlet.java:99)
> at
> com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:185)
> at
> com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:341)
> at
> com.ibm.pvc.internal.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:86)
> at
> com.ibm.pvc.internal.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:102)
> at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3124)
> at
> com.ibm.pvc.internal.webcontainer.webapp.BundleWebApp.handleRequest(BundleWebApp.java:451)
> at
> com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:235)
> at
> com.ibm.pvc.internal.webcontainer.VirtualHost.handleRequest(VirtualHost.java:96)
> at
> com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:811)
> at
> com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:41)
> at
> com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:464)
> at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:355)
> at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1498)
> Here is a possible fix you might want to consider for the
> org.apache.wink.common.internal.utils.FileLoader class:
> {code}
> /**
> * <p>
> * loads file
> * <p>
> * first searches for file in file system
> * <p>
> * if not found, searchs for file using classloaders
> *
> * @param fileName
> * @return
> * @throws FileNotFoundException
> * @throws URISyntaxException
> */
> public static InputStream loadFileAsStream(String fileName) throws
> FileNotFoundException {
> if (fileName == null || fileName.trim().equals("")) {
> throw new NullPointerException("fileName");
> }
> logger.debug("Searching for {} in file system.", fileName);
> File file = new File(fileName);
> if (file.isFile()) {
> // since file is a normal file, return it
> logger.debug("File {} found in file system.", fileName);
> return new FileInputStream(file);
> }
> // before using URLs try to open it as stream provided by the
> // classloaders first.
> InputStream result = openResourceUsingClassLoaders(fileName);
> if (result == null) {
> // file is not a normal file, try to find it using classloaders
> URL url = loadFileUsingClassLoaders(fileName);
> try {
> // decode any escaped sequences such as <space> which
> is %20 in
> // URL
> URI uri = url.toURI();
> String path = uri.getSchemeSpecificPart();
> url = new URL(url.getProtocol(), null, path);
> } catch (IOException e) {
> logger.error(e.getMessage(), e);
> throw new FileNotFoundException(fileName);
> } catch (URISyntaxException e) {
> // do nothing, but return the real (!) url
> }
> try {
> result = url.openStream();
> } catch (IOException e) {
> logger.error(e.getMessage(), e);
> throw new FileNotFoundException(fileName);
> }
> }
> return result;
> }
> /**
> * open the specified resource using class loaders
> *
> * @param filename
> * the name of the resource
> * @return the resource as {...@link InputStream} if found
> * @throws FileNotFoundException
> * if the resource was not found
> */
> private static InputStream openResourceUsingClassLoaders(String filename)
> throws FileNotFoundException {
> logger.debug("Searching for {} using thread context classloader.",
> filename);
> ClassLoader classLoader =
> Thread.currentThread().getContextClassLoader();
> InputStream is = openResourceUsingClassLoader(classLoader, filename);
> if (is == null) {
> logger.debug("Searching for {} using current classloader.",
> filename);
> classLoader = FileLoader.class.getClassLoader();
> is = openResourceUsingClassLoader(classLoader, filename);
> if (is == null) {
> logger.debug("Searching for {} using system
> classloader.", filename);
> is = ClassLoader.getSystemResourceAsStream(filename);
> if (is == null) {
> // well, the last attempt has failed! throw
> // FileNotFoundException
> logger.error("Failed to open resource using
> classloaders");
> throw new FileNotFoundException(filename);
> }
> }
> }
> return is;
> }
> private static InputStream openResourceUsingClassLoader(ClassLoader
> classLoader, String filename) {
> InputStream is = null;
> if (classLoader != null) {
> is = classLoader.getResourceAsStream(filename);
> }
> return is;
> }
> {code}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.