History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: CACHE-108
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Trivial Trivial
Assignee: Andres March
Reporter: Lars Torunski
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
OSCache

FindBugs reports: Usage of GetResource may be unsafe if class Config is extended

Created: 11/Sep/04 10:23 AM   Updated: 01/Mar/05 12:57 AM
Component/s: Base Classes
Affects Version/s: 2.0.2
Fix Version/s: 2.1.1

File Attachments: 1. Java Source File Config.java (5 kb)
2. Java Source File Config.java (5 kb)



 Description  « Hide
FindBugs says: Usage of GetResource may be unsafe if class Config is extended

Calling getClass().getResource(...) could give results other than expected if this class is extended by a class in another package.


Change line 144 from

in = getClass().getResourceAsStream(PROPERTIES_FILENAME);

to

in = Config.getClass().getResourceAsStream(PROPERTIES_FILENAME);


so FindBugs doesn't report the issue anymore. But since PROPERTIES_FILENAME = "/oscache.properties" is constant this "bug" may no problem.

 All   Comments   Change History      Sort Order:
Lars Torunski - [22/Sep/04 01:06 AM ]
Sorry, I mean

in = Config.class.getResourceAsStream(PROPERTIES_FILENAME);

Lars Torunski - [22/Sep/04 01:09 AM ]
From the discussion:


Obtaining resources using java.lang.ClassLoader or java.lang.Class

By using the methods getResource and getResourceAsStream of java.lang.ClassLoader or java.lang.Class the resource locations are at least platform independant. They can (and should) be contained in JAR files which translates into faster resolution and less disk space usage.

Resources obtained by the ClassLoader (directly or indirectly by Class) are never locale specific like ResourceBundle-resources (explained below).

A (quite unobvious) drawback of Class.getResource is that the apparent usage of this method results in an inheritance unsafe class under certain circumstances.

This is probably best explained by an example:

package foobar;

public class Foo
{
    public void someMethod()
    {
        [..]
        URL resourceUrl = getClass().getResource("myResource.png");
        [..]
    }
}

Looks quite right, doesn't it? Well, it isn't. Instead it contains a major bug!

Because Foo is public and not final it's possible to extend it.

package your.customer;

public class MyFoo extends foobar.Foo
{
    public void anotherMethod()
    {
        [..]
        someMethod();
        [..]
    }
}

If your customer calls someMethod() the class MyFoo won't be able to find the resource because it is searched for relative to the package your.customer (getClass() in someMethod() will, correctly but very unlikely expected, return your.customer.MyFoo.class instead of foobar.Foo.class).

The correct way to implement class Foo in an inheritance safe manner would look like this:

package foobar;

public class Foo
{
    public void someMethod()
    {
        [..]
        URL resourceUrl = Foo.class.getResource("myResource.png");
        [..]
    }
}

That way someMethod() will still search relative to the package foobar even if called on an extending class in a different package.

Lars Torunski - [22/Sep/04 05:26 PM ]
I updated the source file, so FindsBugs isn't reporting a "bug" anymore.

Lars Torunski - [27/Sep/04 02:51 PM ]
Please change the code to

try {
            in = Config.class.getResourceAsStream(PROPERTIES_FILENAME);
            properties.load(in);


Use ".class." instead of ".getClass().". Sorry for that inconvenience.