You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Erik Fäßler <er...@uni-jena.de> on 2011/06/07 11:15:23 UTC
Tapestry IoC: Service "Alias" depends on itself?
Hey all,
First of all: I know this isn't new at all, but I couldn't find my exact
case and no solution for it. So:
I am currently building my own SymbolProvider for being able to
configure my Tapestry 5.2.5 webapp more easily. I look for a file
"/WEB-INF/configuration.properties" in the ServletContext and load it
into a Properties object which in turn I then contribute to tapestry's
SymbolSource service. As I want to be able to get configurations from
several sources, I built a service "MySymbolProvider" which gets an
UnorderedConfiguration of Properties. The only existing contribution is
this one:
public static void
contributeTestSymbolProvider(Configuration<Properties> conf,
ApplicationGlobals applicationGlobals) {
Properties properties = null;
InputStream is =
applicationGlobals.getServletContext().getResourceAsStream("/WEB-INF/configuration.properties");
properties = new Properties();
try {
properties.load(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
properties.setProperty("my.value", "A value.");
conf.add(properties);
}
Here the actual contribution to the SymbolSource service:
public static void contributeSymbolSource(
final OrderedConfiguration<SymbolProvider> configuration,
@InjectService("TestSymbolProvider") SymbolProvider
semedicoSymbolProvider) {
configuration.add("TestSymbolProvider", semedicoSymbolProvider);
}
Here's the service definition:
@ServiceId("TestSymbolProvider")
public static SymbolProvider buildSemedicoSymbolProvider(
final Collection<Properties> configurations) {
Properties properties = null;
Iterator<Properties> it = configurations.iterator();
if (it.hasNext())
properties = it.next();
return new TestSymbolProvider(properties);
}
And a test service using the symbols provided by TestSymbolProvider (by
@Inject@Value....)
public static void bind(ServiceBinder binder) {
binder.bind(ITestService.class, TestService.class).eagerLoad();
}
Now: After I do a "clean" on Jetty and published everything freshly,
everything is fine. But then (not necessarily on 2nd try), _sometimes_
starting up Jetty leads to these exceptions:
[ERROR] ioc.Registry Construction of service 'Alias' has failed due to
recursion: the service depends on itself in some way. Please check
org.apache.tapestry5.services.TapestryModule.buildAlias(Logger, String,
AliasManager, Collection) (at TapestryModule.java:411) for references to
another service that is itself dependent on service 'Alias'.
[ERROR] ioc.Registry Operations trace:
[ERROR] ioc.Registry [ 1] Realizing service ServletApplicationInitializer
[ERROR] ioc.Registry [ 2] Invoking
org.apache.tapestry5.services.TapestryModule.buildServletApplicationInitializer(Logger,
List, ApplicationInitializer) (at TapestryModule.java:1501)
[ERROR] ioc.Registry [ 3] Constructing module class
org.apache.tapestry5.services.TapestryModule
[ERROR] ioc.Registry [ 4] Determining injection value for parameter #1
(org.apache.tapestry5.ioc.services.PipelineBuilder)
[ERROR] ioc.Registry [ 5] Resolving object of type
org.apache.tapestry5.ioc.services.PipelineBuilder using MasterObjectProvider
[ERROR] ioc.Registry [ 6] Realizing service Alias
[ERROR] ioc.Registry [ 7] Invoking
org.apache.tapestry5.services.TapestryModule.buildAlias(Logger, String,
AliasManager, Collection) (at TapestryModule.java:411)
[ERROR] ioc.Registry [ 8] Determining injection value for parameter #2
(java.lang.String)
[ERROR] ioc.Registry [ 9] Resolving object of type java.lang.String
using MasterObjectProvider
[ERROR] ioc.Registry [10] Realizing service TestSymbolProvider
[ERROR] ioc.Registry [11] Invoking
tests.mytapestrytest.services.AppModule.buildTestSymbolProvider(Collection)
(at AppModule.java:55)
[ERROR] ioc.Registry [12] Determining injection value for parameter #1
(java.util.Collection)
[ERROR] ioc.Registry [13] Collecting unordered configuration for service
TestSymbolProvider
[ERROR] ioc.Registry [14] Invoking method
tests.mytapestrytest.services.AppModule.contributeTestSymbolProvider(Configuration,
ApplicationGlobals) (at AppModule.java:39).
[ERROR] ioc.Registry [15] Determining injection value for parameter #2
(org.apache.tapestry5.services.ApplicationGlobals)
[ERROR] ioc.Registry [16] Resolving object of type
org.apache.tapestry5.services.ApplicationGlobals using MasterObjectProvider
[ERROR] ioc.Registry [17] Realizing service Alias
[ERROR] AppModule.TestSymbolProvider Construction of service
TestSymbolProvider failed: Error invoking service builder method
tests.mytapestrytest.services.AppModule.buildTestSymbolProvider(Collection)
(at AppModule.java:55) (for service 'TestSymbolProvider'): Error
invoking service contribution method
tests.mytapestrytest.services.AppModule.contributeTestSymbolProvider(Configuration,
ApplicationGlobals): Exception constructing service 'Alias':
Construction of service 'Alias' has failed due to recursion: the service
depends on itself in some way. Please check
org.apache.tapestry5.services.TapestryModule.buildAlias(Logger, String,
AliasManager, Collection) (at TapestryModule.java:411) for references to
another service that is itself dependent on service 'Alias'.
The only interesting thing I see above is that "Alias" gets realized
twice. Is this normal behaviour?
I _guess_ this has something to do with the ApplicationGlobals used. Do
the Alias service and the ApplicationGlobals depend on each other? When
searching for a solution, I found something similar, unfortunately I did
not find a solution. When I remove the ApplicationGlobals from
contributeTestSymbolProvider, the error is gone. Of course, so is my
possibility to access the servlet context for reading my configuration
file which in turn I need to contribute to the SymbolSource service.
And, like I said, the strange thing is that the error does not occur on
every start up.
I got this behavior by starting from scratch with the Maven Tapestry
quickstart archetype, updating the tapestry version to 5.2.5 and writing
the minimal classes and interfaces to get this example running. So I
would consider this as a minimal example. But perhaps I did miss
something all the same, I dont know - and appreciaty your help :-)
Best regards,
Erik
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: Tapestry IoC: Service "Alias" depends on itself?
Posted by Erik Fäßler <er...@uni-jena.de>.
Oh my - a simple @InjectService did the trick. Thank you, everything
works great now.
Side node: Since the old version did sometimes work I just hoped for
your answer and continued working. In this process I added a logger to
the contribution method:
public static void
contributeTestSymbolProvider(Configuration<Properties> conf,
ApplicationGlobals applicationGlobals, Logger logger) {
Like I said, this sometimes worked and sometimes didnt. When I just
added an @InjectService("ApplicationGlobals") to the ApplicationGlobals,
I would get a NullPointerException with every start - the
ApplicationGlobals were null. I guess this is clear to you, I however
don't know why this should be. My random guess was the
ApplicationGlobals would need some more time to load or something. The
only thing I could think of was to put the logger before the
ApplicationGlobals:
public static void
contributeTestSymbolProvider(Configuration<Properties> conf,
Logger logger,
@InjectService("ApplicationGlobals") ApplicationGlobals applicationGlobals) {
Now everything works fine. Interesting thing for me.
So again, I thank you very much for your answer. Let me add that I just
love T5.2 IoC (I spent the last two days migrating from the old Hivemind
container). Its so easy and understandable once you got the hang of it,
just great. The documentation states several times, with T5 IoC, things
would "just work". I admit I'm a bit surprised this is actually true
(besides such minor issues like the ApplicationGlobals thing).
Hivemind already has been good, although it was verbose, sometimes a bit
complicated (Factory classes) and not very thankful for refactoring ;-)
I especially love the ServiceBinder's bind method. I couldn't believe
how my large hivemodule.xml was pressed into a few calls to bind() and
two or three build methods.
Okay, enough of this chatter now, just wanted to drop I really like the
IoC (and Tapestry in overall).
Cheers!
Am 07.06.2011 21:24, schrieb Howard Lewis Ship:
> Well, the good news is that Alias is going away in 5.3 :-)
>
> Contributing to TypeCoercer and SymbolSource can, too easily, lead to
> these unintentional circular dependencies, as type coercion and
> symbols are often present in other contributions.
>
> public static void
> contributeTestSymbolProvider(Configuration<Properties> conf,
> ApplicationGlobals applicationGlobals) {
>
>
> is the problem. You may need to add an @InjectService to
> ApplicationGlobals to prevent the circular dependency.
>
> Alternately, inject an ObjectLocator (this is a resource, not a
> service, and is available to all services) and use its getObject()
> method to resolve the ApplicationGlobals once you need it.
>
>
> On Tue, Jun 7, 2011 at 2:15 AM, Erik Fäßler<er...@uni-jena.de> wrote:
>> Hey all,
>>
>> First of all: I know this isn't new at all, but I couldn't find my exact
>> case and no solution for it. So:
>> I am currently building my own SymbolProvider for being able to configure my
>> Tapestry 5.2.5 webapp more easily. I look for a file
>> "/WEB-INF/configuration.properties" in the ServletContext and load it into a
>> Properties object which in turn I then contribute to tapestry's SymbolSource
>> service. As I want to be able to get configurations from several sources, I
>> built a service "MySymbolProvider" which gets an UnorderedConfiguration of
>> Properties. The only existing contribution is this one:
>>
>> public static void contributeTestSymbolProvider(Configuration<Properties>
>> conf, ApplicationGlobals applicationGlobals) {
>> Properties properties = null;
>> InputStream is =
>> applicationGlobals.getServletContext().getResourceAsStream("/WEB-INF/configuration.properties");
>> properties = new Properties();
>> try {
>> properties.load(is);
>> } catch (IOException e) {
>> // TODO Auto-generated catch block
>> e.printStackTrace();
>> }
>> properties.setProperty("my.value", "A value.");
>> conf.add(properties);
>> }
>>
>> Here the actual contribution to the SymbolSource service:
>>
>> public static void contributeSymbolSource(
>> final OrderedConfiguration<SymbolProvider> configuration,
>> @InjectService("TestSymbolProvider") SymbolProvider
>> semedicoSymbolProvider) {
>> configuration.add("TestSymbolProvider", semedicoSymbolProvider);
>> }
>>
>> Here's the service definition:
>>
>> @ServiceId("TestSymbolProvider")
>> public static SymbolProvider buildSemedicoSymbolProvider(
>> final Collection<Properties> configurations) {
>> Properties properties = null;
>> Iterator<Properties> it = configurations.iterator();
>> if (it.hasNext())
>> properties = it.next();
>> return new TestSymbolProvider(properties);
>> }
>>
>> And a test service using the symbols provided by TestSymbolProvider (by
>> @Inject@Value....)
>>
>> public static void bind(ServiceBinder binder) {
>> binder.bind(ITestService.class, TestService.class).eagerLoad();
>> }
>>
>> Now: After I do a "clean" on Jetty and published everything freshly,
>> everything is fine. But then (not necessarily on 2nd try), _sometimes_
>> starting up Jetty leads to these exceptions:
>>
>> [ERROR] ioc.Registry Construction of service 'Alias' has failed due to
>> recursion: the service depends on itself in some way. Please check
>> org.apache.tapestry5.services.TapestryModule.buildAlias(Logger, String,
>> AliasManager, Collection) (at TapestryModule.java:411) for references to
>> another service that is itself dependent on service 'Alias'.
>> [ERROR] ioc.Registry Operations trace:
>> [ERROR] ioc.Registry [ 1] Realizing service ServletApplicationInitializer
>> [ERROR] ioc.Registry [ 2] Invoking
>> org.apache.tapestry5.services.TapestryModule.buildServletApplicationInitializer(Logger,
>> List, ApplicationInitializer) (at TapestryModule.java:1501)
>> [ERROR] ioc.Registry [ 3] Constructing module class
>> org.apache.tapestry5.services.TapestryModule
>> [ERROR] ioc.Registry [ 4] Determining injection value for parameter #1
>> (org.apache.tapestry5.ioc.services.PipelineBuilder)
>> [ERROR] ioc.Registry [ 5] Resolving object of type
>> org.apache.tapestry5.ioc.services.PipelineBuilder using MasterObjectProvider
>> [ERROR] ioc.Registry [ 6] Realizing service Alias
>> [ERROR] ioc.Registry [ 7] Invoking
>> org.apache.tapestry5.services.TapestryModule.buildAlias(Logger, String,
>> AliasManager, Collection) (at TapestryModule.java:411)
>> [ERROR] ioc.Registry [ 8] Determining injection value for parameter #2
>> (java.lang.String)
>> [ERROR] ioc.Registry [ 9] Resolving object of type java.lang.String using
>> MasterObjectProvider
>> [ERROR] ioc.Registry [10] Realizing service TestSymbolProvider
>> [ERROR] ioc.Registry [11] Invoking
>> tests.mytapestrytest.services.AppModule.buildTestSymbolProvider(Collection)
>> (at AppModule.java:55)
>> [ERROR] ioc.Registry [12] Determining injection value for parameter #1
>> (java.util.Collection)
>> [ERROR] ioc.Registry [13] Collecting unordered configuration for service
>> TestSymbolProvider
>> [ERROR] ioc.Registry [14] Invoking method
>> tests.mytapestrytest.services.AppModule.contributeTestSymbolProvider(Configuration,
>> ApplicationGlobals) (at AppModule.java:39).
>> [ERROR] ioc.Registry [15] Determining injection value for parameter #2
>> (org.apache.tapestry5.services.ApplicationGlobals)
>> [ERROR] ioc.Registry [16] Resolving object of type
>> org.apache.tapestry5.services.ApplicationGlobals using MasterObjectProvider
>> [ERROR] ioc.Registry [17] Realizing service Alias
>> [ERROR] AppModule.TestSymbolProvider Construction of service
>> TestSymbolProvider failed: Error invoking service builder method
>> tests.mytapestrytest.services.AppModule.buildTestSymbolProvider(Collection)
>> (at AppModule.java:55) (for service 'TestSymbolProvider'): Error invoking
>> service contribution method
>> tests.mytapestrytest.services.AppModule.contributeTestSymbolProvider(Configuration,
>> ApplicationGlobals): Exception constructing service 'Alias': Construction of
>> service 'Alias' has failed due to recursion: the service depends on itself
>> in some way. Please check
>> org.apache.tapestry5.services.TapestryModule.buildAlias(Logger, String,
>> AliasManager, Collection) (at TapestryModule.java:411) for references to
>> another service that is itself dependent on service 'Alias'.
>>
>> The only interesting thing I see above is that "Alias" gets realized twice.
>> Is this normal behaviour?
>>
>> I _guess_ this has something to do with the ApplicationGlobals used. Do the
>> Alias service and the ApplicationGlobals depend on each other? When
>> searching for a solution, I found something similar, unfortunately I did not
>> find a solution. When I remove the ApplicationGlobals from
>> contributeTestSymbolProvider, the error is gone. Of course, so is my
>> possibility to access the servlet context for reading my configuration file
>> which in turn I need to contribute to the SymbolSource service.
>> And, like I said, the strange thing is that the error does not occur on
>> every start up.
>>
>> I got this behavior by starting from scratch with the Maven Tapestry
>> quickstart archetype, updating the tapestry version to 5.2.5 and writing the
>> minimal classes and interfaces to get this example running. So I would
>> consider this as a minimal example. But perhaps I did miss something all the
>> same, I dont know - and appreciaty your help :-)
>>
>> Best regards,
>>
>> Erik
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
>>
>>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org
Re: Tapestry IoC: Service "Alias" depends on itself?
Posted by Howard Lewis Ship <hl...@gmail.com>.
Well, the good news is that Alias is going away in 5.3 :-)
Contributing to TypeCoercer and SymbolSource can, too easily, lead to
these unintentional circular dependencies, as type coercion and
symbols are often present in other contributions.
public static void
contributeTestSymbolProvider(Configuration<Properties> conf,
ApplicationGlobals applicationGlobals) {
is the problem. You may need to add an @InjectService to
ApplicationGlobals to prevent the circular dependency.
Alternately, inject an ObjectLocator (this is a resource, not a
service, and is available to all services) and use its getObject()
method to resolve the ApplicationGlobals once you need it.
On Tue, Jun 7, 2011 at 2:15 AM, Erik Fäßler <er...@uni-jena.de> wrote:
> Hey all,
>
> First of all: I know this isn't new at all, but I couldn't find my exact
> case and no solution for it. So:
> I am currently building my own SymbolProvider for being able to configure my
> Tapestry 5.2.5 webapp more easily. I look for a file
> "/WEB-INF/configuration.properties" in the ServletContext and load it into a
> Properties object which in turn I then contribute to tapestry's SymbolSource
> service. As I want to be able to get configurations from several sources, I
> built a service "MySymbolProvider" which gets an UnorderedConfiguration of
> Properties. The only existing contribution is this one:
>
> public static void contributeTestSymbolProvider(Configuration<Properties>
> conf, ApplicationGlobals applicationGlobals) {
> Properties properties = null;
> InputStream is =
> applicationGlobals.getServletContext().getResourceAsStream("/WEB-INF/configuration.properties");
> properties = new Properties();
> try {
> properties.load(is);
> } catch (IOException e) {
> // TODO Auto-generated catch block
> e.printStackTrace();
> }
> properties.setProperty("my.value", "A value.");
> conf.add(properties);
> }
>
> Here the actual contribution to the SymbolSource service:
>
> public static void contributeSymbolSource(
> final OrderedConfiguration<SymbolProvider> configuration,
> @InjectService("TestSymbolProvider") SymbolProvider
> semedicoSymbolProvider) {
> configuration.add("TestSymbolProvider", semedicoSymbolProvider);
> }
>
> Here's the service definition:
>
> @ServiceId("TestSymbolProvider")
> public static SymbolProvider buildSemedicoSymbolProvider(
> final Collection<Properties> configurations) {
> Properties properties = null;
> Iterator<Properties> it = configurations.iterator();
> if (it.hasNext())
> properties = it.next();
> return new TestSymbolProvider(properties);
> }
>
> And a test service using the symbols provided by TestSymbolProvider (by
> @Inject@Value....)
>
> public static void bind(ServiceBinder binder) {
> binder.bind(ITestService.class, TestService.class).eagerLoad();
> }
>
> Now: After I do a "clean" on Jetty and published everything freshly,
> everything is fine. But then (not necessarily on 2nd try), _sometimes_
> starting up Jetty leads to these exceptions:
>
> [ERROR] ioc.Registry Construction of service 'Alias' has failed due to
> recursion: the service depends on itself in some way. Please check
> org.apache.tapestry5.services.TapestryModule.buildAlias(Logger, String,
> AliasManager, Collection) (at TapestryModule.java:411) for references to
> another service that is itself dependent on service 'Alias'.
> [ERROR] ioc.Registry Operations trace:
> [ERROR] ioc.Registry [ 1] Realizing service ServletApplicationInitializer
> [ERROR] ioc.Registry [ 2] Invoking
> org.apache.tapestry5.services.TapestryModule.buildServletApplicationInitializer(Logger,
> List, ApplicationInitializer) (at TapestryModule.java:1501)
> [ERROR] ioc.Registry [ 3] Constructing module class
> org.apache.tapestry5.services.TapestryModule
> [ERROR] ioc.Registry [ 4] Determining injection value for parameter #1
> (org.apache.tapestry5.ioc.services.PipelineBuilder)
> [ERROR] ioc.Registry [ 5] Resolving object of type
> org.apache.tapestry5.ioc.services.PipelineBuilder using MasterObjectProvider
> [ERROR] ioc.Registry [ 6] Realizing service Alias
> [ERROR] ioc.Registry [ 7] Invoking
> org.apache.tapestry5.services.TapestryModule.buildAlias(Logger, String,
> AliasManager, Collection) (at TapestryModule.java:411)
> [ERROR] ioc.Registry [ 8] Determining injection value for parameter #2
> (java.lang.String)
> [ERROR] ioc.Registry [ 9] Resolving object of type java.lang.String using
> MasterObjectProvider
> [ERROR] ioc.Registry [10] Realizing service TestSymbolProvider
> [ERROR] ioc.Registry [11] Invoking
> tests.mytapestrytest.services.AppModule.buildTestSymbolProvider(Collection)
> (at AppModule.java:55)
> [ERROR] ioc.Registry [12] Determining injection value for parameter #1
> (java.util.Collection)
> [ERROR] ioc.Registry [13] Collecting unordered configuration for service
> TestSymbolProvider
> [ERROR] ioc.Registry [14] Invoking method
> tests.mytapestrytest.services.AppModule.contributeTestSymbolProvider(Configuration,
> ApplicationGlobals) (at AppModule.java:39).
> [ERROR] ioc.Registry [15] Determining injection value for parameter #2
> (org.apache.tapestry5.services.ApplicationGlobals)
> [ERROR] ioc.Registry [16] Resolving object of type
> org.apache.tapestry5.services.ApplicationGlobals using MasterObjectProvider
> [ERROR] ioc.Registry [17] Realizing service Alias
> [ERROR] AppModule.TestSymbolProvider Construction of service
> TestSymbolProvider failed: Error invoking service builder method
> tests.mytapestrytest.services.AppModule.buildTestSymbolProvider(Collection)
> (at AppModule.java:55) (for service 'TestSymbolProvider'): Error invoking
> service contribution method
> tests.mytapestrytest.services.AppModule.contributeTestSymbolProvider(Configuration,
> ApplicationGlobals): Exception constructing service 'Alias': Construction of
> service 'Alias' has failed due to recursion: the service depends on itself
> in some way. Please check
> org.apache.tapestry5.services.TapestryModule.buildAlias(Logger, String,
> AliasManager, Collection) (at TapestryModule.java:411) for references to
> another service that is itself dependent on service 'Alias'.
>
> The only interesting thing I see above is that "Alias" gets realized twice.
> Is this normal behaviour?
>
> I _guess_ this has something to do with the ApplicationGlobals used. Do the
> Alias service and the ApplicationGlobals depend on each other? When
> searching for a solution, I found something similar, unfortunately I did not
> find a solution. When I remove the ApplicationGlobals from
> contributeTestSymbolProvider, the error is gone. Of course, so is my
> possibility to access the servlet context for reading my configuration file
> which in turn I need to contribute to the SymbolSource service.
> And, like I said, the strange thing is that the error does not occur on
> every start up.
>
> I got this behavior by starting from scratch with the Maven Tapestry
> quickstart archetype, updating the tapestry version to 5.2.5 and writing the
> minimal classes and interfaces to get this example running. So I would
> consider this as a minimal example. But perhaps I did miss something all the
> same, I dont know - and appreciaty your help :-)
>
> Best regards,
>
> Erik
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>
--
Howard M. Lewis Ship
Creator of Apache Tapestry
The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!
(971) 678-5210
http://howardlewisship.com
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org