views:

23

answers:

2

I am designing a plugin system for our web based application using Spring framework. Plugins are jars on classpath. So I am able to get sources such as jsp, see below

ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] pages = resolver.getResources("classpath*:jsp/*jsp");

So far so good. But I have a problem with the messageSource. It seems to me that ReloadableResourceBundleMessageSource#setBasename does NOT support multiple class path via the "classpath*:" If I use just "classpath:", I get the messageSource just only from one plugin.

Does anyone have an idea how to register messageSources from all plugins? Does exist such an implementation of MessageSource?

A: 

You could do something similar to below - essentially specify each relevant basename explicitly.

 <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>classpath:com/your/package/source1</value>
                <value>classpath:com/your/second/package/source2</value>
                <value>classpath:com/your/third/package/source3/value>
                <value>classpath:com/your/fourth/package/source4</value>
            </list>
        </property>
    </bean>
Raghuram
Yes, that's right. But you have to know all plugins beforehand. The soulution should be universal for plugins.
banterCZ
+1  A: 

The issue here is not with multiple classpaths or classloaders, but with how many resources the code will try and load for a given path.

The classpath* syntax is a Spring mechanism, one which allows code to load multiple resources for a given path. Very handy. However, ResourceBundleMessageSource uses the standard java.util.ResourceBundle to load the resources, and this is a much simpler, dumber mechanism, which will load the first resource for a given path, and ignore everything else.

I don't really have an easy fix for you. I think you're going to have to ditch ResourceBundleMessageSource and write a custom implementation of MessageSource (most likely by subclassing AbstractMessageSource) which uses PathMatchingResourcePatternResolver to locate the various resources and expose them via the MessageSource interface. ResourceBundle isn't going to be much help.

skaffman
Thanks! It is something I worried about.
banterCZ