Hello

My application is using Hibernate for the database with Spring wired
services for business logic and Tapestry for the UI.

To customize the database access and image base url and the like, I use
multiple properties files for configuration, loaded from the filesystem or
classpath depending on which system should be accessed.

This is achieved by implementing a Spring PropertyPlaceholderConfigurer
which exposes properties using the expression syntax (${key}) for use in
applicationContext.xml.

Accessing these same properties in Tapestry is possible by implementing a
SymbolProvider and connect that to the SymbolSource in my AppModule.


This worked fine in Tapestry 5.1.0.5 using Spring 2.5.6 but broke down when
I upgraded to Tapestry 5.2.4 using Spring 3.0.5.

The workaround to use the servlet
context-param tapestry.use-external-spring-context works fine, but I would
like to understand why that is needed.


The closest I came to getting it to work without reporting errors was to
contribute to SymbolSource using this in my AppModule:


public static void
contributeSymbolSource(OrderedConfiguration<SymbolProvider> configuration,
ObjectLocator locator) {

configuration.add("SpringSymbolProvider",

locator.proxy(SymbolProvider.class, SpringSymbolProvider.class),

"after:ApplicationDefaults");

}

This throws no exception and works but reports an error in the log:

ERROR 2011-01-11 20:03:03,179 [main] (OperationTrackerImpl.java:108) -
Construction of service 'ApplicationContext' has failed due to recursion:
the service depends on itself in some way. Please check
org.apache.tapestry5.ioc.internal.util.internalutil...@1341363e for
references to another service that is itself dependent on service
'ApplicationContext'.
ERROR 2011-01-11 20:03:03,179 [main] (OperationTrackerImpl.java:109) -
Operations trace:
ERROR 2011-01-11 20:03:03,180 [main] (OperationTrackerImpl.java:118) - [ 1]
Realizing service ApplicationContext
ERROR 2011-01-11 20:03:03,181 [main] (OperationTrackerImpl.java:118) - [ 2]
Invoking ObjectCreator for Spring ApplicationContext
ERROR 2011-01-11 20:03:03,181 [main] (OperationTrackerImpl.java:118) - [ 3]
Creating Spring ApplicationContext via ContextLoader
ERROR 2011-01-11 20:03:03,181 [main] (OperationTrackerImpl.java:118) - [ 4]
Autobuilding instance of class i.l.c.t.services.SpringSymbolProvider
ERROR 2011-01-11 20:03:03,181 [main] (OperationTrackerImpl.java:118) - [ 5]
Realizing service ApplicationContext

Seems like the Tapestry service ApplicationContext which provides access to
Spring beans depends on SpringSymbolProvider which uses ApplicationContext
to provide the Spring symbols. Catch-22.
Tapestry seems to recover from this and eventually instantiates the services
properly.

As far as I understand the clever use of proxy objects and on-demand
instantiation of Tapestry services, this should be possible if I can inject
the objects properly (correct order or use of @Inject or constructor
arguments).
The reason I think so is that the above errors appear when
SpringSymbolProvider accepts an ApplicationContext reference in
the constructor and uses that object to load the properties immediately
after which the object is discarded.

When instead using @Inject to instantiate an ApplicationContext member which
is used only when requesting a valueForSymbol, the properties don't get
translated and the following errors occur:

ERROR 2011-01-11 20:16:34,010 [main] (OperationTrackerImpl.java:108) -
Construction of service 'ApplicationContext' has failed due to recursion:
the service depends on itself in some way. Please check
org.apache.tapestry5.ioc.internal.util.internalutil...@62de76a1 for
references to another service that is itself dependent on service
'ApplicationContext'.
ERROR 2011-01-11 20:16:34,010 [main] (OperationTrackerImpl.java:109) -
Operations trace:
ERROR 2011-01-11 20:16:34,010 [main] (OperationTrackerImpl.java:118) - [ 1]
Realizing service ApplicationContext
ERROR 2011-01-11 20:16:34,011 [main] (OperationTrackerImpl.java:118) - [ 2]
Invoking ObjectCreator for Spring ApplicationContext
ERROR 2011-01-11 20:16:34,011 [main] (OperationTrackerImpl.java:118) - [ 3]
Creating Spring ApplicationContext via ContextLoader
ERROR 2011-01-11 20:16:34,011 [main] (OperationTrackerImpl.java:118) - [ 4]
Realizing service ApplicationContext

This strikes me as quite weird, ApplicationContext cannot be injected and no
exception is reported.

I would appreciate it if someone has any hints for me as I prefer to use the
more integrated approach.

Thanks in advance.
Regards, Óli

Reply via email to