Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TilesConfigurer class no longer works with Tiles 2.1.1 [SPR-5411] #10084

Closed
spring-projects-issues opened this issue Jan 14, 2009 · 26 comments
Closed
Assignees
Labels
has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Jan 14, 2009

Simon Barbey opened SPR-5411 and commented

After upgrading Apache Tiles from version 2.1.0 to 2.1.1, the integration with Spring no longer works.

The class TilesConfigurer fails to initialize properly the Tiles environment, as visible in the stack trace :

java.lang.UnsupportedOperationException: Class org.apache.tiles.web.util.ServletContextAdapter
not recognized a TilesApplicationContext
at org.apache.tiles.factory.TilesContainerFactory.createContainer(TilesContainerFactory.java:219)
at org.springframework.web.servlet.view.tiles2.TilesConfigurer.createTilesContainer(TilesConfigurer.java:214)
at org.springframework.web.servlet.view.tiles2.TilesConfigurer.afterPropertiesSet(TilesConfigurer.java:201)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:402)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:316)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:282)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:126)
at javax.servlet.GenericServlet.init(GenericServlet.java:69)
at com.caucho.server.dispatch.ServletConfigImpl.createServletImpl(ServletConfigImpl.java:646)
at com.caucho.server.dispatch.ServletConfigImpl.createServlet(ServletConfigImpl.java:587)
at com.caucho.server.dispatch.ServletManager.init(ServletManager.java:154)
at com.caucho.server.webapp.Application.start(Application.java:1654)
at com.caucho.server.deploy.DeployController.startImpl(DeployController.java:621)
at com.caucho.server.deploy.DeployController.restartImpl(DeployController.java:584)
at com.caucho.server.deploy.StartAutoRedeployAutoStrategy.request(StartAutoRedeployAutoStrategy.java:125)
at com.caucho.server.deploy.DeployController.request(DeployController.java:554)
at com.caucho.server.webapp.ApplicationContainer.getApplication(ApplicationContainer.java:885)
at com.caucho.server.webapp.ApplicationContainer.buildInvocation(ApplicationContainer.java:725)
at com.caucho.server.host.Host.buildInvocation(Host.java:459)
at com.caucho.server.host.HostContainer.buildInvocation(HostContainer.java:353)
at com.caucho.server.resin.ServletServer.buildInvocation(ServletServer.java:653)
at com.caucho.server.dispatch.DispatchServer.buildInvocation(DispatchServer.java:198)
at com.caucho.server.hmux.HmuxRequest.handleRequest(HmuxRequest.java:415)
at com.caucho.server.port.TcpConnection.run(TcpConnection.java:514)
at com.caucho.util.ThreadPool.runTasks(ThreadPool.java:520)


Affects: 2.5.6

Reference URL: http://forum.springsource.org/showthread.php?t=65907

Attachments:

Issue Links:

Referenced from: commits 2b13afd

11 votes, 21 watchers

@spring-projects-issues
Copy link
Collaborator Author

Antonio Petrelli commented

FWIW I think that pure java configuration could be used to configure Tiles 2.1.x under a Spring environment. See:
http://tiles.apache.org/framework/tutorial/configuration.html#Pure_Java_configuration
Notice that the docs refer to the 2.1.2-SNAPSHOT version of Tiles.

@spring-projects-issues
Copy link
Collaborator Author

Richard Jr Barabé commented

Here is a version of the TilesConfigurer class that made rid of some deprecated configuration in the property map. It adds support for using wildcard in definitions ( see http://tiles.apache.org/framework/tutorial/wildcard-configuration.html ), which also enable the definitions files to be in the classpath.

This class also integrates the EL support for spring definition files ( see http://tiles.apache.org/framework/tutorial/advanced/el-support.html ).

usage example :
<bean id="tilesConfigurer" class="com.x.web.tiles2.SpringTilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF//*.tiles-def.xml</value>
<value>classpath:/your/package/directory/anotherTileConfigFile.xml</value>
<value>classpath:
/*.tiles-def.xml</value>
</list>
</property>
</bean>

http://richardbarabe.wordpress.com/2009/02/23/apache-tiles-2-integration-with-spring-mvc/

@spring-projects-issues
Copy link
Collaborator Author

Richard Jr Barabé commented

I'm sorry, my bean configuration didn't use the right class name. Here is the example, corrected :

 
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/**/*.tiles-def.xml</value>
            <value>classpath:/your/package/directory/anotherTileConfigFile.xml</value>
            <value>classpath:**/*.tiles-def.xml</value>
        </list>
    </property>
</bean>

Sorry for the double post. And also,since I didn't know how to use jira properly, it stripped some * in my previous comment.

@spring-projects-issues
Copy link
Collaborator Author

Keith Donald commented

Another Tiles 2.1 adapted Configurer from the community

@spring-projects-issues
Copy link
Collaborator Author

Richard Jr Barabé commented

Hello Keith, I downloaded your SpringTilesConfigurer to take a look and, I didn't find how the SpringTilesConfigurer you attached was different from the TilesConfigured I posted before. The only difference I saw was the class name and package, plus two imports, one because you SpringTilesConfigurer is not in the org.springframework.web.servlet.view.tiles2 package, to use the SpringLocaleResolver, and another import of org.springframework.web.servlet.view.tiles2.TilesView, which I didn't manage to find the reference in the class.

Does this class add features, maybe I just didn't see ?

@spring-projects-issues
Copy link
Collaborator Author

Bjorn Harvold commented

Neither of these solutions will work in an OSGi environment.

[CODE][SIZE="1"]
protected TilesContainer createTilesContainer() throws TilesException {
ServletContextAdapter adaptedContext = new ServletContextAdapter(new DelegatingServletConfig());
TilesApplicationContext preliminaryContext = new ServletTilesApplicationContext(adaptedContext);
[COLOR="red"]AbstractTilesApplicationContextFactory contextFactory = AbstractTilesApplicationContextFactory.createFactory(preliminaryContext);[/COLOR] <== HERE
this.tilesContext = contextFactory.createApplicationContext(adaptedContext);
[COLOR="red"]AbstractTilesContainerFactory factory = AbstractTilesContainerFactory.getTilesContainerFactory(this.tilesContext);[/COLOR] <== HERE
return factory.createContainer(this.tilesContext);
}
[/CODE][/SIZE]

This will fail because Tiles will try to instantiate org.apache.tiles.servlet.context.wildcard.WildcardServletTilesApplicationContextFactory (which is in the tiles-servlet bundle) using org.apache.tiles.reflect.ClassUtil which is in the tiles-api bundle. The tiles-api bundle does not have any import statements to tiles-servlet.

@spring-projects-issues
Copy link
Collaborator Author

Richard Jr Barabé commented

Hum, I'm not sure to understand, but I'm curious, could you explain a little more ?
Or point me somewhere you think could help me understand and maybe fix the thing ?

@spring-projects-issues
Copy link
Collaborator Author

Bjorn Harvold commented

I have added an issue with the Tiles team here: https://issues.apache.org/struts/browse/TILES-387

@spring-projects-issues
Copy link
Collaborator Author

Bjorn Harvold commented

Thanks to Antonio with the Tiles team for pointing me in the right direction. If you use a pure Java configuration it will work in an OSGi environment as well as those pesky class loaders won't come into play.

To summarize:

  1. Create a pure java configuration solution that can support Tiles on its own and using the tilesConfigurer. I will attach 3 files all starting with the name Custom, to illustrate my point.
  2. If you are just using Tiles, you would only need to indicate the listener class in your deployment descriptor and you are set.
  3. If you are using the tilesConfigurer bean, you would only need to indicate the bean in one of Spring's xml files
  4. The tilesConfigurer class checks for the existence of a TilesContainer that might have already been initialized by the web.xml listener if the user tries to do both and won't proceed.
  5. The tilesConfigurer instantiates the custom tiles container factory and the application context the same way the tiles listener would. My tilesConfigurer is bare boned and only for illustration purposes.
  6. The custom container factory supports wildcard paths and tiles defs located in the classpath. If no definitions are injected in the tilesConfigurer bean, the factory will go looking for definition files in some default locations. It too is bare boned and can be worked on.

I created 3 files so people only wishing to use Tiles on its own can do so. The custom container factory can hypothetically be an inner class of tiles configurer.

Cheers
bjorn

@spring-projects-issues
Copy link
Collaborator Author

Bjorn Harvold commented

Short and sweet way of getting the new tilesConfigurer working using a pure java configuration solution as explained in the Tiles doc and support running within OSGi.

@spring-projects-issues
Copy link
Collaborator Author

Bjorn Harvold commented

FYI. The custom container factory created above should also support EL definitions if you look at the source. Most of this code was hoisted from Tiles test classes.

@spring-projects-issues
Copy link
Collaborator Author

Bjorn Harvold commented

Attached updated version of tiles configurer and factory.

The previous files did not completely work as there was a class loading issue in one of the factory methods. I had to override that method and duplicate it in my factory for it to load correctly. There is one outstanding issue with the factory that I am still working on. It works when the tiles defs xml is on the classpath such as "classpath:tiles-defs.xml". However it cannot find the definition file if it's located under WEB-INF as the URL is pointing to "jndi:/localhost//WEB-INF/tiles-defs.xml" and it fails with unknown protocol. It should be pointing to somethng like "file://bundlecontext/78/WEB-INF/tiles-defs.xml" I think, but when you call applicationContext.getResource("/WEB-INF/tiles-defs.xml"), it will create the jndi.... url.

@spring-projects-issues
Copy link
Collaborator Author

Bjorn Harvold commented

Correction, the url for a resource under WEB-INF should look something like: bundleresource://102/WEB-INF/tiles-defs.xml

@spring-projects-issues
Copy link
Collaborator Author

Christopher Frost commented

I'm trying this on Spring 3. The TilesConfigurer given above is good but there is another issue to do with the way the provided TilesView works with the latest version of Tiles (I got 2.1.2). I will comment more here once I've done some investigation.

@spring-projects-issues
Copy link
Collaborator Author

Christopher Frost commented

OK, I've done some propper investigation now. The most recent code in TilesView will never work with Tiles 2.1.2. It has this method,

@Override
public boolean checkResource() throws Exception {
     TilesContainer container = TilesAccess.getContainer(getServletContext());
     return container.isValidDefinition(getUrl());
}

The call to isValidDefinition must also pass in a var array of objects. If you pass in HttpServletRequest and HttpServletResponse it will end up with a ServletTilesRequestContextFactory. If you pass in just a PageContext you will get a JspTilesRequestContextFactory. I'm not sure what the difference between these is, when they should be used. In the case above, no RequestContextFactory will be found at all and the page request will fail with an exception that no factory could be found. I have had a quick look at the stuff in the associated fourm thread but had no luck. I don't have the time to dig much further, I believe this is also breaking the new PetClinic sample app that is intended for Spring 3 as it has moved on to Tiles.

@spring-projects-issues
Copy link
Collaborator Author

Bjorn Harvold commented

Hi Chris

My webapp is running fine with Tiles 2.1.2. Do you encounter this error at runtime or at startup?

@spring-projects-issues
Copy link
Collaborator Author

Christopher Frost commented

Hi,

I get this at runtime when I make a request that requires tiles to render the view. I'm doing this in a dm Server so it's a slightly different world. I'm going to keep going on it and I'll probably report back after the weekend and let you know what I've found. It would be useful to know if your doing this with Tiles portlet support though?

Thanks, Chris.

@spring-projects-issues
Copy link
Collaborator Author

Rick Mangi commented

Chris,

Not sure if this is the same issue as you are seeing, but I got this to work (Spring M3 and a build of tiles from the trunk we made a few weeks ago) using the following SpringBeanPreparerFactory. It's not pretty but it did solve the Jsp/Servlet context issue.

public class NickSpringBeanPreparerFactory extends SpringBeanPreparerFactory {

public ViewPreparer getPreparer(String name, TilesRequestContext context)
		throws TilesException {
	ServletContext c = null;
	if (context instanceof ServletTilesRequestContext) {
		ServletTilesRequestContext strc = (ServletTilesRequestContext) context;
		c = (ServletContext) strc.getContext();
	} else if (context instanceof JspTilesRequestContext) {
		JspTilesRequestContext j = (JspTilesRequestContext) context;
		c = j.getPageContext().getServletContext();
	}

	if (c == null) {
		throw new TilesException("Could not determine context! "
				+ context.getClass());
	}
	return super.getPreparer(name, WebApplicationContextUtils
			.getWebApplicationContext(c));
}

}

HTH,

Rick

@spring-projects-issues
Copy link
Collaborator Author

Christopher Frost commented

Hi Rick,

Thanks for the help, I'll be working on this again come Monday so I'll give it a try. I do like they way your resolving the servletContext. Juergen said he would have a fix for the approaching RC1 so I'll see where he is up to as well.

Thanks again, Chris.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Chris, I have a (different) fix for the SpringBeanPreparerFactory issue, and I suppose passing HttpServletRequest and HttpServletResponse references into that isValidDefinition call will work, since we're doing the same for the render call.

However, I'm unclear on which version of TilesConfigurer to use: The one Bjorn submitted is radically different from what we used for Tiles 2.0.5; have you been using that one? Any feedback on whether the first TilesConfigurer patch in this issue can potentially work on OSGi as well?

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Antonio Petrelli commented

About the OSGi compliance, I wish you to know that a bug in Tiles 2.1.2 has been fixed, and Tiles 2.1.3 is currently under the vote process:
https://issues.apache.org/struts/browse/TILES-404
http://markmail.org/message/gnq4bdf5p5ailvov?q=tiles+2%2E1%2E3

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

This is resolved in trunk now and should be available in upcoming 3.0 RC1 snapshots.

However, it hasn't been integration-tested yet. Chris, it would be great if you could give this a try with dm Server...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Christopher Frost commented

I'll give it a try as soon as a snapshot build goes through, thanks for the work. I've got a copy of the proposed 2.1.3 Tiles so will try it with that as well as the one in our EBR.

@spring-projects-issues
Copy link
Collaborator Author

Antonio Petrelli commented

Tiles 2.1.3 has been released and declared to be GA.

@spring-projects-issues
Copy link
Collaborator Author

Eric Rizzo commented

Sorry for being a newb, but it's not clear to me if Tiles 2.1.x can work with Spring 2.5.x without using the patched code attached to this bug? In other words, is there a combination of versions of Tiles 2.1.x and 2.5.x that play nicely together?

@spring-projects-issues
Copy link
Collaborator Author

Xabier Burgos commented

I know it's a bit late but I took Bjorn's customized configuration classes and modified them to use Tiles 2.2 new interfaces so as to avoid using the deprecated ones and also activated support for velocity (you'll need Velocity 1.6.x and Velocity Tools 2.0.x). So if you want to add Tiles 2.2 and Velocity to your Spring project you just need to add them and configure them with spring.

@spring-projects-issues spring-projects-issues added type: enhancement A general enhancement has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has: votes-jira Issues migrated from JIRA with more than 10 votes at the time of import in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants