7 Replies Latest reply on Jun 11, 2010 10:11 PM by Duy Do

    Seam3 XML Do we really need beans?

    John Ament Master

      So I read through the reference guide for Seam3 XML module, and it seems like it'll do what I want, kind of.


      I recently wrote up a way to create dynamic @Inject ResourceBundle resourceBundle; type code that will load resource bundles.  Now this works well, except if you want to try to use the ResourceBundle in a view, then you need to add in some Producers.  It seems like Seam3 XML requires there to be Beans to work.  This seems somewhat on par with the expectations of CDI, so not much of an argument from me.


      What I'm thinking though is to create a generic bean that can reproduce any the input bean of a method under a new qualifier.  I assume I'll need a new method/class to pull this off, but the code should be as simple as:




      public ResourceBundle produceCopyResourceBundle(ResourceBundle bundleIn) {
          return bundleIn;
      }



      from what I can tell, I can then define in Seam3 XML, a bean like this:




      <tad:BundleProducer>
      <tad:produceBundle>
      <s:Produces/>
      <tad:Bundle baseName="com.tad.some.base.name"/>
      </tad:produceBundle>
      </tad:BundleProducer>





      So if I want, I can then wire this bean into the above method like this:



      <tad:BundleCopier>
      <tad:produceCopyResourceBundle>
      <s:Produces/>
      <s:Named value="bundle1"/>
      <tad:Bundle baseName="com.tad.some.base.name"/>
      <s:Inject/>
      </tad:produceCopyResourceBundle>
      </tad:BundleCopier>




      The syntax seems a little odd to me, but is this about what would be expected?

        • 1. Re: Seam3 XML Do we really need beans?
          Stuart Douglas Master

          The actual syntax for the second example is:



          <tad:BundleCopier>
           <tad:produceCopyResourceBundle>
            <s:Produces/>
            <s:Named value="bundle1"/>
            <tad:Bundle baseName="com.tad.some.base.name"/>
            <parameters/>
              <tad:ResourceBundle>
               <s:Inject/>
              </tad:ResourceBundle>
            </parameters>
            </tad:produceCopyResourceBundle>
          </tad:BundleCopier>
          
          



          Of course you could put @Inject and @Produces on the actual bean class, and use the <extends/> tag like so:



          <tad:BundleCopier>
           <s:extends/>
           <tad:produceCopyResourceBundle>
            <s:Named value="bundle1"/>
            <tad:Bundle baseName="com.tad.some.base.name"/>
            </tad:produceCopyResourceBundle>
          </tad:BundleCopier>
          
          




          • 2. Re: Seam3 XML Do we really need beans?
            Stuart Douglas Master

            Something that I was considering implementing was factories. For example:


             <s:factory>
               <s:String/>
               <s:value>hello world</s:value>
               <s:Named>helloMessage</s:Named>
             </s:factory>
            
            



            The example above would make 'hello world' available in EL under the name 'helloMessage'.


             <s:factory>
              <tad:ResourceBundle/>
              <s:Named value="bundle1"/>
              <tad:Bundle baseName="com.tad.some.base.name"/>
             </s:factory>
            
            



            Would handle the situation above. If the value that we wanted to expose to the EL has qualifiers:


             <s:factory>
              <tad:ResourceBundle/>
              <s:Named value="bundle1"/>
              <tad:Bundle baseName="com.tad.some.base.name"/>
              <s:factoryValue>
                <tad:SomeQualifier/>
              </s:factoryValue/>
             </s:factory>
            
            



            The syntax is open to debate, but this would allow you to wire up stuff without creating extra classes.


            • 3. Re: Seam3 XML Do we really need beans?
              John Ament Master

              So let me back track a bit; as after reading the above I think I may have just started done the wrong path.


              My goal: Be able to bind java.util.ResourceBundles to Names dynamically.


              What I have done so far: Created a producer method that can create ResourceBundles based on optional @Bundle as well as taking into account the class they're in.


              What makes sense to me though is to take these ResourceBundles, and expose them as a Named bean.  The easiest thing I can think of is something like this:




              @Inject @Bundle("com.tad.bundles.Bundle1") ResourceBundle resourceBundle1;
              
              @Produces @Named("bundle1")
              public ResourceBundle produceBundle1() {
                  return resourceBundle1;
              }



              To me though, it makes sense to be able to do this without any code, so I figure that SeamXML should be able to help with this.  It seems like we're there almost.


              So a few things to try to understand, on my part


              1. @Bundle is not a qualifier, it's used more like @Category is in the Logger example.  In order to work with SeamXML, does it need to be?
              2. Thinking back to my original problem, I have the following producer:



                  @Produces
                  public ResourceBundle produceResourceBundle(InjectionPoint ip)



              I figure, I should be using the <extends/> or similar tag in seam xml to change what this produces to add the Named to the produces.  Does this sound about right?
              3. What does InjectionPoint resolve to when using SeamXML?
              4. Where do the Scopes end up in all of this?

              • 4. Re: Seam3 XML Do we really need beans?
                Stuart Douglas Master

                1) @Bundle should work even though it is not a qualifier. If it doesn't it is a bug.


                2) Yes


                3) Same thing it does normally. Seam XML add beans using BeforeBeanDiscovery.addAnnotatedType().


                4) You have to add scope annotations yourself, either in xml or on the bean that you are extending.



                • 5. Re: Seam3 XML Do we really need beans?
                  John Ament Master
                  Hrmm so clearly I'm doing something wrong, I figure.  First, any chance this topic can be moved to seam3 forum?

                  Second, I created a basic example, at least from what I understand of this topic:



                  `
                  <beans xmlns="http://java.sun.com/xml/ns/javaee"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:s="urn:java:seam:core"
                     xmlns:p="urn:java:com.tad.cdi.mods.properties"
                     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                        http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
                        <p:BundleProducer>
                            <p:produceResourceBundle>
                                <s:extends/>
                                <s:Named value="bundle1"/>
                                <p:Bundle baseName="com.tad.some.base.Name"/>
                            </p:produceResourceBundle>
                        </p:BundleProducer>
                  </beans>`






                  What this says (to me at least), I have a bean BundleProducer in the above mentioned package.  It has a method already annotated @Produces and has one argument, InjectionPoint.  I am extending it to produce @Named; however I need to be able to read from the InjectionPoint the <p:Bundle/> that goes with it.

                  However, I get the following stack trace:







                  `org.glassfish.deployment.common.DeploymentException: Injection point has unstatisfied dependencies. Injection point: field org.jboss.weld.environment.se.threading.RunnableDecorator.runnable; Qualifiers: javax.enterprise.inject.Default()
                  (skipping a bunch of lines)
                  Caused by: org.jboss.weld.DeploymentException: Injection point has unstatisfied dependencies. Injection point: field org.jboss.weld.environment.se.threading.RunnableDecorator.runnable; Qualifiers: [@javax.enterprise.inject.Default()]
                          at org.jboss.weld.Validator.validateInjectionPoint(Validator.java:232)
                          at org.jboss.weld.Validator.validateBean(Validator.java:80)
                          at org.jboss.weld.Validator.validateRIBean(Validator.java:100)
                          at org.jboss.weld.Validator.validateBeans(Validator.java:282)
                          at org.jboss.weld.Validator.validateDeployment(Validator.java:267)
                          at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:389)
                          at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:180)
                          ... 30 more`

                  I'm using a maven project and i built the xml module locally.

                  I also noticed that it brings in a bunch of weld dependencies.  I'm not particularly comfortable with that idea, mostly because i was hoping to use whatever CDI implementation is on the app server.  Is this in fact necessary? Do I need to have weld as my CDI for XML
                  • 6. Re: Seam3 XML Do we really need beans?
                    Stuart Douglas Master

                    Does your example work if you just put the annotations on directly? The error that you are getting does not really seem to be related to the bean you are configuring.


                    With regard to the weld dependencies, I have changed weld-core from scope compile to scope test. The only dependency that is required to use seam-xml is weld-extensions, which despite the name can be used with any CDI implementation.

                    • 7. Re: Seam3 XML Do we really need beans?
                      Duy Do Newbie

                      Like John, I could not deploy the Weld application (Wicket) under Glassfish v3.
                      The following exception is always thrown when deploy under Glassfish v3:


                      org.glassfish.deployment.common.DeploymentException: Injection point has unstatisfied dependencies. Injection point: field org.jboss.weld.environment.se.threading.RunnableDecorator.runnable; Qualifiers: javax.enterprise.inject.Default()
                      (skipping a bunch of lines)
                      Caused by: org.jboss.weld.DeploymentException: Injection point has unstatisfied dependencies. Injection point: field org.jboss.weld.environment.se.threading.RunnableDecorator.runnable; Qualifiers: [@javax.enterprise.inject.Default()]
                              at org.jboss.weld.Validator.validateInjectionPoint(Validator.java:232)
                              at org.jboss.weld.Validator.validateBean(Validator.java:80)
                              at org.jboss.weld.Validator.validateRIBean(Validator.java:100)
                              at org.jboss.weld.Validator.validateBeans(Validator.java:282)
                              at org.jboss.weld.Validator.validateDeployment(Validator.java:267)
                              at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:389)
                              at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:180)
                              ... 30 more



                      How could we fix this issue?