6 Replies Latest reply on Jan 10, 2012 7:52 PM by meetoblivion

    Seam JCR module configuration

    jonne.deprez

      Hi,


      To inject a JackRabbit session into a bean, I need to specify the required parameters in the JcrConfiguration annotation. According to the documentation:



      @Inject @JcrConfiguration(name="org.apache.jackrabbit.repository.home", value="/usr/local/jboss/repository")
      private Session session;





      This works, but it is a bit annoying that in this way the value of the parameter is hard coded. Now we are forced to have the same locations for the repository in production and during development and while testing with arquillian. Moreover, if my colleague works with a different OS, the path may be invalid on his machine.


      Are there alternative ways to set that value for Seam JCR? Would it be possible to support EL expressions in the value?


      Thanks!

        • 1. Re: Seam JCR module configuration
          meetoblivion

          I think you should use seam config xml to configure the injection.


          otherwise, you can programmatically look up the repo by using a bean lookup.

          • 2. Re: Seam JCR module configuration
            jonne.deprez

            OK, but could someone then also explain how to do this? Because the @JcrConfiguration is not a qualifier, which means that



            @Inject @Any private Instance<Session> sessionInstance;
            
            ...
            
            session = sessionInstance.select(new JcrConfigurationLiteral("org.apache.jackrabbit.repository.home", "/usr/local/jboss/repository")).get();




            will not work.


            Any ideas?

            • 3. Re: Seam JCR module configuration
              jonne.deprez

              Found the solution in the testsuite bundled with the examples for Seam JCR:


              @Produces
              @ExtensionManaged
              @Named(ConfigParams.JCR_REPOSITORY_CONFIG_MAP)
              public Map<String, String> producesDefaultConfig() {
                 return Collections.singletonMap(JACKRABBIT_REPOSITORY_HOME, "/usr/local/jboss/repository");
              }



              • 4. Re: Seam JCR module configuration
                lightguard

                If you're using multiple repos, you'll want to create your own qualifier instead of using @Named, unless they have different names.

                • 5. Re: Seam JCR module configuration
                  jonne.deprez

                  Thanks for the info, Jason.


                  I noticed that the OCMHandler class, though, doesn't fully support this solution.


                  If I don't explicitly specify the JcrConfiguration parameters inside the JcrDao annotation, but rely on the abovementioned producer method, then the OCMHandler will add an empty parameter to the map of configuration parameters ("" -> ""), because it expects to find the parameters inside the annotation (line 71).


                  This may cause problems with Jackrabbit, whose RepositoryFactoryImpl caches Repository instances based on the map of configuration parameters. If I initialized the repository earlier on by injecting a Session or Repository in a bean, Jackrabbit keeps the handle to the Repository with just one parameter (the home directory of the repository in my case).
                  When the OCMHandler then needs access to the repository, the second empty parameter will cause JackRabbit to try to initialize the repository a second time, which it will refuse.


                  As a temporary workaround I'll also add an empty parameter to my producer, but it would be nice if this were solved in a next release.

                  • 6. Re: Seam JCR module configuration
                    meetoblivion

                    JOnne,


                    I think you're misinterpreting how that code is working around line 71.




                             JcrConfiguration sessionConfig = declaringClass.getAnnotation(JcrDao.class).value();
                             Map<String,String> defaults = null;
                             if(!configParameters.isUnsatisfied()) {
                                 defaults = configParameters.get();
                             }
                             session = resolver.createSessionFromParameters(sessionConfig, null,defaults);
                    
                    



                    defaults represent the default set of parameters, managed via @Named.  The configuration options in JcrDao will override the defaults as defined by your application.  I believe that sessionConfig is allowed to be null in this setup.