views:

50

answers:

2

I have a class that must be initialized with an absolute pathname. The thing I want to initialize it with the pathname of is a file sitting in WEB-INF.

I am using the ContextLoaderListener from Spring to set this all into motion, so I can't run Java code to obtain the path from the context and stick it where a ${whatever} could find it.

Consider some bean definition like:

<bean class="my.class">
  <property name="somePath" value="/WEB-INF/a.txt"/>
</bean>

I need a way, if possible, to make that pathname pass through the ServletContextResource mechanism. There doesn't seem to be a 'prefix' for those like classpath:

In this case, it won't help to have the item in the classpath, trust me.

EDIT:

I went and dug up the source of the bean class, and it already accepts Resources on the relevant properties. So Something Ridiculous is going on here, insofar as it complains as if it can't find things. Off to the debugger for me.

EDIT AGAIN:

So, this turns out to be a maven prank, unrelated to Spring. It's upvotes all around for your help, and open another question.

+1  A: 

Is the file on the classpath?

In your bean, you could have a property such as Resource fileResource, and then set it in your bean like

<property name="fileResource" value="classpath:/path/to/the/file"/>

The Spring Resource interface has a method named getFile(), which will return a File handle for the resource. From there you can simply call File.getAbsolutePath().

matt b
Not in classpath. I'm expecting the ServletContextResource to be used for the property value since this is a WebApp context, but no such luck. Perhaps because the property (which is not under my control) is a String and not a File.
bmargulies
+3  A: 

My preference would be to modify this class to take a Resource, rather than a pathname. You can then inject it using:

<property name="fileResource" value="/WEB-INF/path/to/file"/>

This is more flexible, and you can use the various methods on the Resource interface to get things like the underlying file pathname, such as getFile().getAbsolutePath().

However, if modifying the target class is not feasible, then you need some way of converting a Resource into a pathname. You could use a FactoryBean for this, something like:

public class ResourcePathFactoryBean extends AbstractFactoryBean<String> {

    private Resource resource;

    @Required
    public void setResource(Resource resource) {
        this.resource = resource;
    }

    @Override
    protected String createInstance() throws Exception {
        return resource.getFile().getAbsolutePath();
    }

    @Override
    public Class<?> getObjectType() {
        return String.class;
    }
}

You can then use it to inject your path:

<bean id="myBean" class="com.MyBean">
   <property name="path">
      <bean class="com.ResourcePathFactoryBean">
         <property name="resource" value="/WEB-INF/path/to/file"/>
      </bean>
   </property>
</bean>
skaffman