2

I've put wro.xml in src/main/resources as there are some other resources and it's easier to access them in unit tests.

I need to extend some wro classes now to be able to read the model from another place, but can't get it working.

Necessary code

web.xml:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>WebResourceOptimizer</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>wroFilter</param-value>
    </init-param>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>WebResourceOptimizer</filter-name>
    <url-pattern>/resources/*</url-pattern>
</filter-mapping>

applicationContext.xml:

<bean id="wroFilter" class="ro.isdc.wro.http.ConfigurableWroFilter">
    <property name="properties" ref="wroProperties" />
</bean>

<bean id="wroProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="location" value="classpath:wro.properties" />
</bean>

wro.properties:

managerFactoryClassName=com.example.web.wro.manager.factory.MyWroManagerFactory;
preProcessors=cssUrlRewriting,cssImport,semicolonAppender,lessCss
postProcessors=cssMin,jsMin
debug=true

MyWroManagerFactory:

public class MyWroManagerFactory extends CopyrightKeeperConfigurableWroManagerFactory {
    private static final Logger LOG = LoggerFactory.getLogger(MyWroManagerFactory.class);

    @Override
    protected WroModelFactory newModelFactory() {
        LOG.debug("Load wro.xml directly from classpath");
        return new XmlModelFactory() {
            @Override
            protected InputStream getModelResourceAsStream() throws IOException {
                final String resourceLocation = getDefaultModelFilename();
                final InputStream stream = getClass().getResourceAsStream(resourceLocation);

                if (stream == null) {
                    throw new IOException("Invalid resource requested: " + resourceLocation);
                }

                return stream;
            }
        };
    }
}

CopyrightKeeperConfigurableWroManagerFactory:

public class CopyrightKeeperConfigurableWroManagerFactory extends ConfigurableWroManagerFactory {
    private static final Logger LOG = LoggerFactory.getLogger(CopyrightKeeperConfigurableWroManagerFactory.class);

    private static final String[] PROCESSORS = {
        CssImportPreProcessor.ALIAS,
        JawrCssMinifierProcessor.ALIAS,
        CssMinProcessor.ALIAS,
        JSMinProcessor.ALIAS
    };

    @Override
    protected void contributePreProcessors(final Map<String, ResourcePreProcessor> map) {
        for (String processor : PROCESSORS) {
            if (map.containsKey(processor)) {
                LOG.debug("Apply CopyrightKeeperProcessorDecorator on " + processor);
                map.put(processor, CopyrightKeeperProcessorDecorator.decorate(map.get(processor)));
            }
        }
    }
}

Why it can't find classes/wro.xml / How to use a custom location for wro.xml?

EDIT Here's the full log output: http://pastebin.com/NeNy1NH4

dtrunk
  • 4,685
  • 17
  • 65
  • 109

1 Answers1

1

The problem is that you are loading the model relative to the MyWroManagerFactory class:

 final InputStream stream = getClass().getResourceAsStream(resourceLocation);

That means that it will look for the model in the folder where the class is located. Since your wro.xml is located in classes folder (which is a root for classpath), you should use the following:

ClassLoader.getSystemResourceAsStream(resourceLocation);

Alternatively you could use ClasspathUriLocator:

new ClasspathUriLocator().locate("classpath:" + resourceLocation)

EDITED: Apparently this example discovered a problem which is described in the following issue: Until the fix is ready, the following options are available:

Alex Objelean
  • 3,893
  • 2
  • 27
  • 36
  • That is because getDefaultModelFilename(); returns /WEB-INF/wro.xml, while you have the wro.xml in classes folder. Either create a WEB-INF folder in your classpath or do not use getDefaultModelFilename() method. – Alex Objelean May 29 '13 at 14:49
  • No, getDefaultModelFilename() returns wro.xml: https://github.com/alexo/wro4j/blob/1.6.x/wro4j-core/src/main/java/ro/isdc/wro/model/factory/XmlModelFactory.java#L394 – dtrunk May 29 '13 at 15:02
  • The log says: java.io.IOException: Invalid resource requested: /WEB-INF/wro.xml... That means that the requested file path is: /WEB-INF/wro.xml... which is wrong. – Alex Objelean May 29 '13 at 15:11
  • Right, that means my custom XmlModelFactory doesn't take effect?! – dtrunk May 29 '13 at 15:12
  • That seem to be the problem. Do you have the project somewhere on github? I'll try to debug the issue and will let you know. – Alex Objelean May 29 '13 at 15:14
  • Unfortunately not. I'll make another minimal project for it to host it on github. – dtrunk May 29 '13 at 15:17