Tapestry 5.x can not find the core pages and components from the URLs provided from classloaders in JBoss 5.x. Please see https://issues.apache.org/jira/browse/TAP5-576 for details. In JIRA 576, Benjamin Bentmann provided an implementation of ClasspathURLConverter to overcome the problem.

public class ClasspathURLConverterJBoss5 implements ClasspathURLConverter
{
    private static Logger log = Logger.getLogger(ClasspathURLConverterJBoss5.class);

    public URL convert(URL url)
    {
        // If the URL is a "vfs" URL (JBoss 5 uses a Virtual File System)...
		
        if (url != null && url.getProtocol().startsWith("vfs"))
        {
            // Ask the VFS what the physical URL is...

            try
            {
                URLConnection connection = url.openConnection();
                Object virtualFile = invokerGetter(connection, "getContent");
                // Use reflection so that we don't need JBoss in the classpath at compile time.
                Object zipEntryHandler = invokerGetter(virtualFile, "getHandler");
                Object realUrl = invokerGetter(zipEntryHandler, "getRealURL");
                return (URL) realUrl;
            }
            catch (Exception e)
            {
                log.info(e.getCause());
                if (e.getCause() == null)
                {
                    logger.error(e.toString());
                }
                else
                {
                    logger.error(e.getCause().toString());
                }
            }
        }
        return url;
    }

    private Object invokerGetter(Object target, String getter) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
    {
        Class<?> type = target.getClass();
        Method method;
        try
        {
            method = type.getMethod(getter);
        }
        catch (NoSuchMethodException e)
        {
            method = type.getDeclaredMethod(getter);
            method.setAccessible(true);
        }
        return method.invoke(target);
    }

}

To override the default implementation of ClasspathURLConverter, just add the above ClasspathURLConverterJBoss5.java to your project and add the following piece of code to your AppModule.java.

public static void contributeServiceOverride(MappedConfiguration<Class,Object> configuration)
{
    configuration.add(ClasspathURLConverter.class,  new ClasspathURLConverterJBoss5());
}    

The above just override the default ClaspathURLConverter service. For more information on overriding a general service, please see http://tapestry.apache.org/tapestry5.1/tapestry-ioc/cookbook/override.html

The above fix has been test with Tapestry 5.1 and 5.2 on JBoss 5.0.1. It does not work on JBoss 5.1.0!

  • No labels