25 May 2009

Spring Extension Jcr 0.9 Released

A new version (0.9) was released, add the following xml to use in pom.xml:

Dependency:


org.springframework
se-jcr
0.9



Repository:


se-jcr-repo
se-jcr-repo
https://src.springframework.org/svn/se-jcr/repo/



Release Notes - SX Spring JCR extension - Version 0.9

Bug

  • [SEJCR-1] - JCR Factory register the listeners before registering the namespaces

  • [SEJCR-4] - mark jcr implementation related dependencies as optional in pom

  • [SEJCR-7] - Documentation can be updated

  • [SEJCR-10] - JackRabbitUserTransaction swallows Jacrabbit and DB exceptions

  • [SEJCR-11] - JcrSessionFactory registers listeners even when returning already created session

  • [SEJCR-12] - Reregistering Node Types for Jackrabbit

Improvement

  • [SEJCR-2] - add spring 2.0 schema to JCR support

  • [SEJCR-6] - Allow the SessionFactory to register the CND file by pointing to it in the sessionFactory Spring bean

  • [SEJCR-8] - RollbackException still swallows Cause-XAException

  • [SEJCR-9] - Jcr sample shouldn't use hard coded paths

  • [SEJCR-15] - Use SLF4J instead of Commons-Logging

12 comments:

Вячеслав said...

Hi!
In maven pom file for release 0.9 https://src.springframework.org/svn/se-jcr/repo/org/springframework/se-jcr/0.9/se-jcr-0.9.pom you have a lot of dependencies to jackrabbit 1.5.0, org.slf4j 1.5.6, spring-webmvc 2.5.6 etc. Because you are using specific versions of those it become impossible to use your extension with different versions of jackrabbit, slf4j. It also leads to unexpected errors because in some projects we use for example Apache commons that rely on older versions of jars than you are using.
Do you really think that for your extension you need all of those dependencies or you just copied all of them from some parent projects? For example I don't see any use of spring-webmvc for JCR extension but maven is downloading it when it is building my application.
Please consider some cleanup for pom.xml

bdusauso said...

Hi,

I totally agree with the latest comment : it seems that some dependencies cleanup could be made.

Willie Wheeler said...

Yup.

<dependency>
<groupId>org.springframework</groupId>
<artifactId>se-jcr</artifactId>

<!-- Yuck, have to exclude all this manually. But see http://jira.springframework.org/browse/SEJCR-4 -->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-jca</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-jcr-commons</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-jcr-rmi</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>geronimo-spec</groupId>
<artifactId>geronimo-spec-j2ee-connector</artifactId>
</exclusion>
<exclusion>
<groupId>geronimo-spec</groupId>
<artifactId>geronimo-spec-jta</artifactId>
</exclusion>
</exclusions>
</dependency>

the |eek said...
This comment has been removed by the author.
Salvatore Incandela said...

It's strange because the https://src.springframework.org/svn/se-jcr/repo/org/springframework/se-jcr/0.9/

folder exist and the jars are in there

Can you post the error please?

the |eek said...

I've added the repository like this :

<repository>
<id>se-jcr-repo</id>
<name>se-jcr-repo</name>
<url>https://src.springframework.org/svn/se-jcr/repo</url>
</repository>

but no way to get the dependency like this :

<dependency>
<groupId>org.springframework</groupId>
<artifactId>se-jcr</artifactId>
<version>0.9</version>
</dependency>

Can someone help me please?

the |eek said...

[ERROR] BUILD ERROR
[INFO] ------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) org.springframework:se-jcr:jar:0.9

Try downloading the file manually from the project website.


etc ..

Salvatore Incandela said...

Hello, I have tried removing my local dependency simulating the problem, but maven has compiled without errors.

rm ~ / .m2/repository/org/springframework/se-jcr/0.9 / *

mvn clean compile

Alek83 said...

Hi!

What about the future of project?
And current situation?
There are JCR 2 and JackRabbit 2.2... can I use your solution for new libraries?

Thx

Anonymous said...

From the Jira Roadmap, it looks like version 1.0 of SX JCR is out. However, I can't seem to find either a Git or SVN repository with the code. Could you please let us know the repository from which we can pull your latest?

ABAM said...

Hi Salvatore



I am triyin to use se-jcr with out succes let me explain to you.





What I have?

I have a Spring MVC 3.1, Jackrabbit 2 (jcr 283)

Now I am using JCR but I am using it in the controller like follow:



repository = RepositoryAccessServlet.getRepository(request.getSession().getServletContext();

jcrSession = repository.login(new SimpleCredentials("admin","admin".toCharArray()));





What I like to do?



In order to follow a good MVC architecture I like to make all the jackrabbit interaction in the DAO layer and not in the controller layer, there is where I need se-jcr.



Like is not a good idea to sent the session from the controller to the services and from the services to the DAO I like to get the session in the DAO like follow:



web.XML first context-param



<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/applicationContext.xml</param-value>

</context-param>





applicationContext.xml

...spring security stuff

<beans:bean id="repository" class="org.springframework.extensions.jcr.jackrabbit.RepositoryFactoryBean"

p:configuration ="classpath:/repository.xml"

p:homeDir="file:./target/repo" >

</beans:bean>



<beans:bean id="jcrSessionFactory" class="org.springframework.extensions.jcr.JcrSessionFactory">

     <beans:property name="repository" ref="repository"/>

        <beans:property name="credentials">

         <beans:bean class="javax.jcr.SimpleCredentials">

             <beans:constructor-arg index="0" value="bogus"/>

                <beans:constructor-arg index="1" value="pass"/>

            </beans:bean>

     </beans:property>

</beans:bean>



<beans:bean id="jcrTemplate" class="org.springframework.extensions.jcr.JcrTemplate">

<beans:property name="sessionFactory" ref="jcrSessionFactory"/>

<beans:property name="allowCreate" value="true"/>

</beans:bean>



As as test I trying to get the session not in the DAO but in the service



Controller class:

AbstractRepositoryController has the returnJson method and json declaration as a JsonObject



@Controller

public class NewController extends AbstractRepositoryController{

private ProductDaoImpl daoImpl;

  

  @Autowired

  private NewController(ProductDaoImpl daoImpl){

  this.daoImpl = daoImpl;

  }





@RequestMapping("main/test1")

protected void test1(HttpServletRequest request, HttpServletResponse response){

try {

daoImpl.saveSmth();

json.put("ok", "todoOk");

} catch (Exception e) {

e.printStackTrace();

}

returnJson(json.toString(), response);

}

}





Service class:



@Service

public class ProductDaoImpl extends JcrDaoSupport {



    public void saveSmth() throws DataAccessException{



        Session session = getSession();

        try {

                Node root = session.getRootNode();

                Node sample = root.addNode("sample node");

                sample.setProperty("sample property", "bla bla");

                session.save();

        }

        catch (RepositoryException ex) {

            throw convertJcrAccessException(ex);

        }

    }

}





....Continue this on other post becuase max lenth issues...

ABAM said...

What is going on?

When spring is starting check at NewController and try to get ProductDaoImpl then it fails, with the following output:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'newController' [.../controllers/main/NewController.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [...services.ProductDaoImpl]: : Error creating bean with name 'productDaoImpl' defined in file [.../services/ProductDaoImpl.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: sessionFactory or jcrTemplate is required;

The line above is the first line of the exception but kind of say where the problem is, as I understand it ProductDaoImpl could not be created because there are not sessionFactory or jcrTemplate.
Here is where I do not get the problem, I did define the sessionFactory and jcrTemplate in the applicationContext.xml.

Then I thought could it be that when spring is starting there is not session? I mean it make sense because is just starting no request have yet arrive to the controller, so what I did was remove the Autowired tag and the code looks like follow:

Controller class:

@Controller
public class NewController extends AbstractRepositoryController{


private ProductDaoImpl daoImpl;


@RequestMapping("main/test1")
protected void test1(HttpServletRequest request, HttpServletResponse response){
daoImpl = new ProductDaoImpl();
try {
daoImpl.saveSmth();
json.put("ok", "todoOk");
} catch (Exception e) {
e.printStackTrace();
}
returnJson(json.toString(), response);
}
}

Service class:
public class ProductDaoImpl extends JcrDaoSupport {

public void saveSmth() throws DataAccessException{

Session session = getSession();
try {
Node root = session.getRootNode();
Node sample = root.addNode("sample node");
sample.setProperty("sample property", "bla bla");
session.save();
}
catch (RepositoryException ex) {
throw convertJcrAccessException(ex);
}
}
}

And it keeps falling but this time is not at spring start up is when I make the URL request and the controller try to make a ProductDaoImpl instance, the output is the following:

java.lang.NullPointerException
at org.springframework.extensions.jcr.support.JcrDaoSupport.getSession(JcrDaoSupport.java:96)
at com.test.ok.services.ProductDaoImpl.saveSmth(ProductDaoImpl.java:16)
at com.test.ok.controllers.main.NewController.test1(NewController.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

...So I do not know what else to do I need your expert help to have this running or undertand what I am doing wrong.

Thanks a lot!