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