codeaudit / dkpro-core-asl

Automatically exported from code.google.com/p/dkpro-core-asl
0 stars 0 forks source link

ResourceUtils.resolveLocation() always fails when aLocation is on the classpath and aCaller is null #93

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Call ResourceUtils.resolveLocation() where the first argument, aLocation, is 
some location on the classpath, and aCaller is null.  For example:

URL url = ResourceUtils.resolveLocation("classpath:/foo/bar", null, null);

What is the expected output? What do you see instead?

Assuming foo/bar actually exists on the classpath, I expect url to be populated 
with an URL pointing to it.  Instead, I get the following:

Exception in thread "main" java.io.FileNotFoundException: No file found at 
[classpath:/foo/bar]
    at de.tudarmstadt.ukp.dkpro.core.api.resources.ResourceUtils.resolveLocation(ResourceUtils.java:282)

This is a serious problem as it means that resolveLocation() cannot be called 
from a static context.

Apparently the problem lies with the following lines:

// if there is no caller, we use the thread  classloader
url = Thread.currentThread().getContextClassLoader().getResource(
      aLocation.substring(prefixClasspath.length()));

Copying and pasting these lines into a minimal example (see attached) shows 
that it assigns null to url even when the resource exists.  The attached 
example also contains two possible solutions to the problem:  one of them 
requires another polymorph of resolveLocation() where the second argument is of 
type Class rather than type Object, and the other is to use getStackTrack() 
instead of getContextClassLoader().  I don't know enough about Java or DKPro to 
know which (if either) of these two solutions is better.

Original issue reported on code.google.com by tristan.miller@nothingisreal.com on 16 Aug 2012 at 10:31

Attachments:

GoogleCodeExporter commented 9 years ago
Using the contextClassLoader seems to be a really bad idea here. It should just 
use the static ResourceUtils.class classloader.

Original comment by richard.eckart on 16 Aug 2012 at 10:45

GoogleCodeExporter commented 9 years ago
Changed in rev 863. Should work now using ResourceUtils.class.getResource. 
Another (generally not very good, but probably) workaround in a static context 
would be

URL url = ResourceUtils.resolveLocation("classpath:/foo/bar", 
MyStaticClass.class, null);

Actually, another method should be added with the following signature:

   URL resolveLocation(String aLocation, Classloader aClassloader, UimaContext aContext)

Passing in the caller seemed a convenient idea (and probably still is) but does 
not provide the necessary level of control.

Original comment by richard.eckart on 16 Aug 2012 at 10:51

GoogleCodeExporter commented 9 years ago
Added a couple of additional signatures for resolveLocation, including one 
which takes a classloader (and now is the central one).

revision 864

Original comment by richard.eckart on 16 Aug 2012 at 10:57

GoogleCodeExporter commented 9 years ago
Btw. the context classloader might even have worked, but the URL passed to it 
would be wrong. While one would call e.g.

getClass().getResource("/my/resource.xml")

one has to say

classloader.getResource("my/resource.xml") to achieve the same thing. If the 
"/" is left in front, it would always return null.

Original comment by richard.eckart on 16 Aug 2012 at 12:02