11 Replies Latest reply on Dec 2, 2009 6:16 AM by asookazian

    Observes ContainerInitialized

    asookazian
      public class Main {
           
           void start(@Observes ContainerInitialized ci, Session session) {...}



      so in the case like above, SE java app (i.e. no servlet), how exactly does this work?  How/when is the container actually initialized if you are not deploying this as a WAR to JBoss, for example?

        • 1. Re: Observes ContainerInitialized
          nickarls

          Haven't looked at the could but I guess when execution has proceeded to the point where deployment is done and you can start working with the container

          • 2. Re: Observes ContainerInitialized
            asookazian

            This is my guess:


            @Observes ContainerInitialized in CDI is equivalent to (or very similar in that both refer to system startup time essentially):


            @Startup in Seam: Specifies that an instance of this component is created at system initialization time for an application scoped component, or when a session is started for a session scoped component. May only be applied to APPLICATION or SESSION scoped components.


            API doc for org.jboss.weld.environment.se.events.ContainerInitialized:



            The event that is fired when the Weld CDI container is initialized and ready for applications to take control, which it may do by observing this event.

            seems the difference is that with ContainerInitialized, something happens rather than an instance is definitely created like with @Startup...

            • 3. Re: Observes ContainerInitialized
              asookazian

              It's covered actually pretty well here: http://in.relation.to/Bloggers/WeldInJavaSE but after reading that article, I'm still not sure exactly how to run that app.  There are certain CDI/Weld classes that need to be in your classpath, correct?


              ok, so you create a JAR with the HelloWorld class and beans.xml in the META-INF directory.


              Run by issuing following cmd line cmd:


              java org.jboss.weld.environments.se.StartMain foo


              So how does StartMain know to execute a method in our HelloWorld class?  Or I guess you don't explicitly need to tell it which class due to the observer pattern.  So what then, the HelloWorld class just needs to be in your classpath?  So any Weld class in your classpath with @Observes ContainerInitialized foo will be executed on container startup which is essentially defined as the....


              nevermind, it becomes more obvious when you read the src for StartMain:


              /**
               * This is the main class that should always be called from the command line for
               * a Weld SE app. Something like: <code>
               * java -jar MyApp.jar org.jboss.weld.environment.se.StarMain arguments
               * </code>
               * 
               * @author Peter Royle
               * @author Pete Muir
               */
              public class StartMain
              {
              
                 private static final String BOOTSTRAP_IMPL_CLASS_NAME = "org.jboss.weld.bootstrap.WeldBootstrap";
                 private final Bootstrap bootstrap;
                 private final BeanStore applicationBeanStore;
                 public static String[] PARAMETERS;
                 private WeldManager manager;
              
                 public StartMain(String[] commandLineArgs)
                 {
                    PARAMETERS = commandLineArgs;
                    try
                    {
                       bootstrap = Reflections.newInstance(BOOTSTRAP_IMPL_CLASS_NAME, Bootstrap.class);
                    }
                    catch (Exception e)
                    {
                       throw new IllegalStateException("Error loading Weld bootstrap, check that Weld is on the classpath", e);
                    }
                    this.applicationBeanStore = new ConcurrentHashMapBeanStore();
                 }
              
                 public BeanManager go()
                 {
                    SEWeldDeployment deployment = new SEWeldDeployment()
                    {
                    };
                    bootstrap.startContainer(Environments.SE, deployment, this.applicationBeanStore);
                    final BeanDeploymentArchive mainBeanDepArch = deployment.getBeanDeploymentArchives().get(0);
                    this.manager = bootstrap.getManager(mainBeanDepArch);
                    bootstrap.startInitialization();
                    bootstrap.deployBeans();
                    WeldManagerUtils.getInstanceByType(manager, ShutdownManager.class).setBootstrap(bootstrap);
                    bootstrap.validateBeans();
                    bootstrap.endInitialization();
              
                    this.manager.fireEvent(new ContainerInitialized());
                    return this.manager;
                 }
              
                 /**
                  * The main method called from the command line.
                  * 
                  * @param args the command line arguments
                  */
                 public static void main(String[] args)
                 {
                    new StartMain(args).go();
                 }
              
                 public static String[] getParameters()
                 {
                    // TODO(PR): make immutable
                    return PARAMETERS;
                 }
              
              }
              



              note: java -jar MyApp.jar org.jboss.weld.environment.se.StarMain arguments


              ok, now it is making sense...

              • 4. Re: Observes ContainerInitialized
                peteroyle.howardmoon.hitcity.com.au

                Arbi, have you read the Java SE section of the Weld documentation? If so was it before or after you made these posts? http://docs.jboss.org/weld/reference/1.0.0/en-US/html/environments.html#d0e5064

                • 5. Re: Observes ContainerInitialized
                  asookazian

                  I just read this section: 18.4.1. CDI SE Module.


                  So for this sample class:


                  @ApplicationScoped
                  
                  public class HelloWorld
                  
                  {
                  
                     @Inject @Parameters List<String> parameters;
                  
                  
                     public void printHello(@Observes ContainerInitialized event) {
                  
                         System.out.println("Hello " + parameters.get(0));
                  
                     }
                  
                  }



                  You JAR it up with beans.xml in META-INF and place it where exactly in the file system/classpath?


                  With a SE app (console app), there is no web container so it's not like you drop it in the JBoss server/default/deploy directory.


                  So the point is, when you issue this cmd: java org.jboss.weld.environments.se.StartMain <args>, how does the Weld container find my HelloWorld class?  Does it not matter as long as it's somewhere on the classpath?


                  Also, in this error from StartMain: Error loading Weld bootstrap, check that Weld is on the classpath, which Weld JARs are required to be on the classpath?  just weld-se.jar?

                  • 6. Re: Observes ContainerInitialized
                    asookazian

                    Ok................. :(


                    Just realized after couple hours today of trying like an idiot to add the weld-se.jar and weld-servlet.jar to my foo.jar that you can't do this b/c Java doesn't support JARs in JARs!


                    http://forums.sun.com/thread.jspa?threadID=583158


                    What an idiot.  I don't know why the Eclipse JAR export wizard shows that it will include the referenced JARs in the lib folder in my new JAR.


                    So I have a foo.jar with the HelloWorld class in the root of the JAR and a META-INF folder with beans.xml and MANIFEST.MF.


                    So.......................


                    Win7 cmd line:


                    C:\Projects\weld-console>java -cp C:\java\weld-1.0.0.SP1\artifacts\weld\weld-se.
                    jar;C:\java\weld-1.0.0.SP1\artifacts\weld-servlet.jar -jar C:\java\weld-1.0.0.SP
                    1\artifacts\weld\weld-se.jar org.jboss.weld.environments.se.StartMain fred
                    Failed to load Main-Class manifest attribute from
                    C:\java\weld-1.0.0.SP1\artifacts\weld\weld-se.jar



                    I don't see how this simpler cmd line: java org.jboss.weld.environments.se.StartMain Gavin from http://in.relation.to/Bloggers/WeldInJavaSE would work exactly in my case.


                    I didn't create an executable JAR, just a regular JAR.


                    This fails as well:


                    C:\java\weld-1.0.0.SP1\artifacts\weld>java org.jboss.weld.environments.se.StartM
                    ain Gavin
                    Exception in thread "main" java.lang.NoClassDefFoundError: org/jboss/weld/enviro
                    nments/se/StartMain



                    So what am I doing wrong?

                    • 7. Re: Observes ContainerInitialized
                      asookazian

                      should I be using weld-servlet.jar?  this is not a web app after all...

                      • 8. Re: Observes ContainerInitialized
                        peteroyle.howardmoon.hitcity.com.au
                        Hi Arbi,

                        It sounds like your application jar is configured correctly, it's definitely a classpath issue. You're about to see why...

                        There are quite a few jars that need to be on the classpath to run a Weld SE app. At the moment, setting that classpath up without the help of Maven is quite hard, which is something I'm working on solving right now.

                        In the meantime, if you've built weld-se using maven you will have all the necessary dependencies in your local maven repositoy (HOME/m2.repository), so you should be able to run your app by first setting up a CLASSPATH environment variable to point to the necessary jars from your local repository:

                        $ export CLASSPATH=~/.m2/repository/org/jboss/weld/weld-core/1.0.0/weld-core-1.0.0.jar:~/.m2/repository/org/jboss/weld/weld-se/1.0.0-SNAPSHOT/weld-se-1.0.0-SNAPSHOT.jar:~/.m2/repository/javax/enterprise/cdi-api/1.0/cdi-api-1.0.jar:~/.m2/repository/org/jboss/weld/weld-spi/1.0/weld-spi-1.0.jar:~/.m2/repository/org/slf4j/slf4j-api/1.5.9.RC1/slf4j-api-1.5.9.RC1.jar:~/.m2/repository/org/slf4j/slf4j-simple/1.5.9.RC1/slf4j-simple-1.5.9.RC1.jar:~/.m2/repository/org/slf4j/slf4j-ext/1.5.9.RC1/slf4j-ext-1.5.9.RC1.jar:~/.m2/repository/ch/qos/cal10n/cal10n-api/0.7.2/cal10n-api-0.7.2.jar:~/.m2/repository/com/google/collections/google-collections/1.0-rc3/google-collections-1.0-rc3.jar:~/.m2/repository/javax/el/el-api/2.1.2-b04/el-api-2.1.2-b04.jar:~/.m2/repository/javassist/javassist/3.11.0.GA/javassist-3.11.0.GA.jar:~/.m2/repository/org/jboss/interceptor/jboss-interceptor-api/1.1/jboss-interceptor-api-1.1.jar:~/.m2/repository/javax/inject/inject-api/1.0.0-PRD/inject-api-1.0.0-PRD.jar:~/.m2/repository/org/jboss/interceptor/jboss-interceptor/1.0.0-CR8/jboss-interceptor-1.0.0-CR8.jar::~/.m2/repository/javax/ejb/ejb-api/3.0/ejb-api-3.0.jar:weld-se-hello-world-1.0.0-SNAPSHOT.jar

                        Told you there were a few! Notice that the last entry, weld-se-hello-world-1.0.0-SNAPSHOT.jar in this example is the application jar and should be replaced with your application's jar.

                        Then you can start your app using:

                        $ java org.jboss.weld.environment.se.StartMain Possums
                        65 [main] INFO Weld/Version - WELD-000900 1.0 (0)94 [main] INFO Weld/Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
                        Hello Possums
                        $

                        In this example, 'Possums' is the command line argument passed to the application, and 'Hello Possums' is the output of the app.

                        Hope this helps. Let me know.

                        Pete.
                        • 9. Re: Observes ContainerInitialized
                          asookazian

                          ok, thx.  man that's a long altered classpath.  there's got to be a simpler way.  and the docs/blogs need to be updated to indicate the classpath requirements as such...

                          • 10. Re: Observes ContainerInitialized
                            peteroyle.howardmoon.hitcity.com.au

                            Arbi Sookazian wrote on Dec 02, 2009 00:25:

                            there's got to be a simpler way.


                            There is: https://jira.jboss.org/jira/browse/WELDX-51

                            • 11. Re: Observes ContainerInitialized
                              asookazian

                              maven shade plugin.  you learn something new everyday...