cancel
Showing results for 
Search instead for 
Did you mean: 

Alfresco Via RMI

rdanner
Champ in-the-making
Champ in-the-making
For those interested:

I have put alfresco behind the JCR-RMI library from jackrabbit.
All i had to do was make a simple bean to register the repository and then leverage their client on the remote end.


I have a build for just the RMI-JCR and the additional alfresco config and classes.

I had done a significant portion of an RMI wrapper before I ran in to jackrabbit (I should be looking a little harder before i leap).

Works like a charm.  Their library does not use remote activation which I would like to include for robustness sake.
62 REPLIES 62

rdanner
Champ in-the-making
Champ in-the-making
Russ,

I have it working now in Tomcat after following your updated WIKI pages.  I'd forgotten the rmiregistry.

Thanks.

no problem

last night I checked out HEAD and ran in to this TypeMismatch stuff.  I'll take a look at that.

Also it looks like there is someone having trouble getting the server running under Jboss.  When I worked with Jboss a while back I noticed that they run RMI/IIOP or RMI/JNP. Users should be using JNP.  RMI/IIOP requires a rmic with special options and in some cases modifications to the code.  Its not something I have put much thought into supporting.  I did discuss it briefly with the Jackrabbit author as there is some benifits concerning COM/.Net itegration.  I can't get too excited about it at the moment. 

once iECM web services are published its going to be difficult to really justify the use of RMI.

Ha… interesting stuff.  Depending on where you deploy things it looks like spring is getting confused.

Because I am oh so clever (… right …) I thought it would be a good idea to throw the extension in common so that you wouldnt have to wait for the WAR to explode, and you wouldnt have to compile the libs in to the war.  This would make it possible to plug the JCR-RMI extension in for a trial against a stock Alfresco download. Not good for production since these classes would bleed all over the place but good for people testing the extension.

Well I was coming up with all of the odd errors I just posted about.  Something about the classloader differences makes spring unable to match up the class to the interface. 

So much for clever… When I put the libs and config where they belong in the WAR everything works perfectly fine.

I guess Ill go update the wiki now and stop making problems for myself  Smiley Surprisedops:

Server level configuration (in all its forms) turns out to be a real missing element.  JBoss is has even less options then tomcat.

cchab
Champ in-the-making
Champ in-the-making
Hi Russ,
I tried JCR-RMI but I made a sample that does not work as I expected.

I tried to enumerate all nodes and properties using JCR-RMI but I have the following exception that is thrown. It is not always thrown at the same node or property. It seems to appear randomly.
"
net.sf.acegisecurity.AuthenticationCredentialsNotFoundException: A valid SecureContext was not provided in the RequestContext
at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:477)
at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:355)
at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:77)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:40)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
at $Proxy22.getCurrentUserName(Unknown Source)
at org.alfresco.jcr.util.JCRProxyFactory$SessionContextInvocationHandler.invoke(JCRProxyFactory.java:116)
at $Proxy69.getName(Unknown Source)
at org.apache.jackrabbit.rmi.server.ServerItem.getName(ServerItem.java:69)
at sun.reflect.GeneratedMethodAccessor159.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
at sun.rmi.transport.Transport$1.run(Transport.java:153)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:466)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:707)
at java.lang.Thread.run(Thread.java:595)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
at org.apache.jackrabbit.rmi.server.ServerProperty_Stub.getName(Unknown Source)
at org.apache.jackrabbit.rmi.client.ClientItem.getName(ClientItem.java:85)
at net.entropysoft.jcrrmi.DisplayRepository.displayProperties(DisplayRepository.java:38)
at net.entropysoft.jcrrmi.DisplayRepository.traverse(DisplayRepository.java:61)
at net.entropysoft.jcrrmi.DisplayRepository.traverse(DisplayRepository.java:64)
at net.entropysoft.jcrrmi.DisplayRepository.traverse(DisplayRepository.java:64)
at net.entropysoft.jcrrmi.DisplayRepository.main(DisplayRepository.java:94)
"
I created an issue about this problem : http://www.alfresco.org/jira/browse/AR-706

Thanks

rdanner
Champ in-the-making
Champ in-the-making
Hi Russ,
I tried JCR-RMI but I made a sample that does not work as I expected.

I tried to enumerate all nodes and properties using JCR-RMI but I have the following exception that is thrown. It is not always thrown at the same node or property. It seems to appear randomly.
"
net.sf.acegisecurity.AuthenticationCredentialsNotFoundException: A valid SecureContext was not provided in the RequestContext
at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:477)
at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:355)
at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:77)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:40)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
at $Proxy22.getCurrentUserName(Unknown Source)
at org.alfresco.jcr.util.JCRProxyFactory$SessionContextInvocationHandler.invoke(JCRProxyFactory.java:116)
at $Proxy69.getName(Unknown Source)
at org.apache.jackrabbit.rmi.server.ServerItem.getName(ServerItem.java:69)
at sun.reflect.GeneratedMethodAccessor159.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
at sun.rmi.transport.Transport$1.run(Transport.java:153)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:466)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:707)
at java.lang.Thread.run(Thread.java:595)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
at org.apache.jackrabbit.rmi.server.ServerProperty_Stub.getName(Unknown Source)
at org.apache.jackrabbit.rmi.client.ClientItem.getName(ClientItem.java:85)
at net.entropysoft.jcrrmi.DisplayRepository.displayProperties(DisplayRepository.java:38)
at net.entropysoft.jcrrmi.DisplayRepository.traverse(DisplayRepository.java:61)
at net.entropysoft.jcrrmi.DisplayRepository.traverse(DisplayRepository.java:64)
at net.entropysoft.jcrrmi.DisplayRepository.traverse(DisplayRepository.java:64)
at net.entropysoft.jcrrmi.DisplayRepository.main(DisplayRepository.java:94)
"
I created an issue about this problem : http://www.alfresco.org/jira/browse/AR-706

Thanks


I'll check out the ticket.  This doesn't sound like something that would be "random".  The exception is thrown at different places with in the same thread of execution – same "request" different properties?  or different request and different properties?

trupoet
Champ in-the-making
Champ in-the-making
So whats the latest info about this JCR-RMI bit?

I'm looking into this kind of access as well but found out that none of the JSR170 classes are Serializable and neither are the Alfresco 1.3 classes that implement them.

Is there an updated zip for this RMI project? And/or instructions on setting it up?

I heard someone mention a wiki page?

Would be cool if so.

rdanner
Champ in-the-making
Champ in-the-making
So whats the latest info about this JCR-RMI bit?

I'm looking into this kind of access as well but found out that none of the JSR170 classes are Serializable and neither are the Alfresco 1.3 classes that implement them.

Is there an updated zip for this RMI project? And/or instructions on setting it up?

I heard someone mention a wiki page?

Would be cool if so.

The JCR-RMI extension in the forge has been idle for some time.  There was only one planned functional deployement that did not get done.  I was going to provide the capability to put the configuration in the database and edit it with the gui.  I put that on the roadmap when I was looking for a reason to play with alfresco UI but I have become very busy with Liferay Portal and I let that fall away.

The JCR-RMI integration is very simple, its a class that gets the JCR repository from alfresco, uses Jackrabbit to wrap it and then binds it to a registry/directory.  Beyond that, all of the magic is done by Jackrabbit.

I recommend getting the latest jackrabbit libraries.  Also, you will likely run in to issues with the alfresco security and transactions.  JCR-RMI is not yet part of the product and because of that it is probably not unit tested.  Unit testing JCR-RMI could reuse the JCR unit tests if they do not make assumptions about how the get the JCR repository and other beans.


anyway here is the information you are looking for:
wiki: http://wiki.alfresco.com/wiki/JCR-RMI_Extension

forge: http://forge.alfresco.com/projects/jcr-rmi/

I really recommend that people read this (http://wiki.alfresco.com/wiki/Is_JCR-RMI_Right_for_Me%3F) which talks about a number of Afresco APIs, gives pros and cons.

RMI in combination with the fine-graned access provided by the JCR API can be very inefficient.  Make sure you think about what type of accesses you are doing and also who your clients will be and what kind of firewalls will be between your repository and them.

lfuller
Champ in-the-making
Champ in-the-making
Does anyone know if this issue has been corrected in Alfresco 2.0?

http://issues.alfresco.com/browse/AR-706

Until such time as this issue is corrected,  JCR-RMI shouldn't be used with Alfresco. 

Is the JNDI option mentioned in http://issues.alfresco.com/browse/AR-1131 any more stable?  If not, is there any way to effectively use the JSR 170 api with alfresco remotely?

rdanner
Champ in-the-making
Champ in-the-making
Does anyone know if this issue has been corrected in Alfresco 2.0?

http://issues.alfresco.com/browse/AR-706

Until such time as this issue is corrected,  JCR-RMI shouldn't be used with Alfresco. 

Is the JNDI option mentioned in http://issues.alfresco.com/browse/AR-1131 any more stable?  If not, is there any way to effectively use the JSR 170 api with alfresco remotely?

It's an interesting problem – annoying but interesting.  It's not somethign I ran into when I was playing with JCR-RMI but I wasnt doing much to stress the system and therfor maybe RMI was using the same server thread over and over – donno.   To be honest the whole Thread Local solution really needs to be thought out before its picked – seeems over used in by the java community to me.  It has huge downsides.

This JCR implementation seems to prefer the OSIV (open session in view) model which I think is rather limiting.  You have to work in the same thread that opened the session and you cannot open more than one sesion per thread. 

I think there a number of solutions we could look at.  One goal that I think we aught to strive for is to keep from having to compile our own version of the jackrabbit JCR RMI.  There is benifit in the fact that we don't have to compile, manage that distro – it has to work against the unit tests, benchmark harness but it really should remain packaged by the apache folks if possible.  I don't recall seeing any way (via some factory mechanism) that would allow us to register our own server implementation which could manage the thread issue on our side from the RMI perspective.  My interest is peaked, I am going to go dig this up when I get a chance.

Long term it might be helpful to create a mechanism to allow us to inject our own implementation and donate it back to apache.  In the short term it may be quicker / easier to consider other solutions:

One might be to create a session pool that sits above the Alfresco JCR interface and below the RMI interface  The worker threads in the pool would own the real JCR thread and the the secure context, tx managment etc while the JCR-RMI component would simply hook up to a proxy.  I can think of a number of drawbacks to that approach – complexity is one of them.

Anyway I agree – the issue renders JCR-RMI a invalid option until it is solved.  Not only are you likely to get errors when you are seved by a server thread that does not have the appropriate thread locals but you are also in danger of being served a "dirty" thread which is a security concern since that means you have access to someone elses content/profile etc.

rdanner
Champ in-the-making
Champ in-the-making
Does anyone know if this issue has been corrected in Alfresco 2.0?

http://issues.alfresco.com/browse/AR-706

Until such time as this issue is corrected,  JCR-RMI shouldn't be used with Alfresco. 

Is the JNDI option mentioned in http://issues.alfresco.com/browse/AR-1131 any more stable?  If not, is there any way to effectively use the JSR 170 api with alfresco remotely?

It's an interesting problem – annoying but interesting.  It's not somethign I ran into when I was playing with JCR-RMI but I wasnt doing much to stress the system and therfor maybe RMI was using the same server thread over and over – donno.   To be honest the whole Thread Local solution really needs to be thought out before its picked – seeems over used in by the java community to me.  It has huge downsides.

This JCR implementation seems to prefer the OSIV (open session in view) model which I think is rather limiting.  You have to work in the same thread that opened the session and you cannot open more than one sesion per thread. 

I think there a number of solutions we could look at.  One goal that I think we aught to strive for is to keep from having to compile our own version of the jackrabbit JCR RMI.  There is benifit in the fact that we don't have to compile, manage that distro – it has to work against the unit tests, benchmark harness but it really should remain packaged by the apache folks if possible.  I don't recall seeing any way (via some factory mechanism) that would allow us to register our own server implementation which could manage the thread issue on our side from the RMI perspective.  My interest is peaked, I am going to go dig this up when I get a chance.

Long term it might be helpful to create a mechanism to allow us to inject our own implementation and donate it back to apache.  In the short term it may be quicker / easier to consider other solutions:

One might be to create a session pool that sits above the Alfresco JCR interface and below the RMI interface  The worker threads in the pool would own the real JCR thread and the the secure context, tx managment etc while the JCR-RMI component would simply hook up to a proxy.  I can think of a number of drawbacks to that approach – complexity is one of them.

Anyway I agree – the issue renders JCR-RMI a invalid option until it is solved.  Not only are you likely to get errors when you are seved by a server thread that does not have the appropriate thread locals but you are also in danger of being served a "dirty" thread which is a security concern since that means you have access to someone elses content/profile etc.


Just thinking about this a little… we dont really need a way to injet the server  implementation we have one… we hcan provide the repository implementation of our choice… we would just need to as I was saying before provide something other than the basic JCR implementation… like a reference to an adaptor which would manage this issue.

I would avoid creating the session pool, its complicated and costly.  Maybe we could give each inbound session some sort of marker (or use one we have) to allow us to store credentials on the server side.)  we could then manage the security context on a per call basis…

call…
   look at marker in session
   get server cached security context for given id
   put it in the thread
   procede with call
   clean up the thread
   return our value

There are issues around this as well – we could be spoofed based on such a mechanism and there is still the possibility of someone causing a leak by never calling .logout().

just thinking out loud here….

lfuller
Champ in-the-making
Champ in-the-making
Thanks for the response!  That is an interesting suggestion for making JCR-RMI + Alfresco usable.  I'm not necessarily dedicated to using JCR-RMI, all I am looking for is a remote way to access Alfresco's JCR interface.  Is JCR-RMI the only available solution?

rdanner
Champ in-the-making
Champ in-the-making
Thanks for the response!  That is an interesting suggestion for making JCR-RMI + Alfresco usable.  I'm not necessarily dedicated to using JCR-RMI, all I am looking for is a remote way to access Alfresco's JCR interface.  Is JCR-RMI the only available solution?


Well.. I don't think there is any GREAT ways to get remote JCR access.  The only other option at the moment it the given in the ticket where Alfresco stiffs the reference in to JNDI and another application picks it out.  That solution has two issues:

The sense of remote becomes limited to remote web context, same JVM.

The other issue is that there is a race condition because alfresco and your application load in whatever order the server determines.  Therefore if your app loads before alfresco and requires the JCR interface on startup… you are in trouble.  It you don't need JCR until you the server begins serving pages you are in good shape.

One thing I'd like to see is the Alfresco repository Packaged as an MBean with all of its local interfaces available via JNDI.  That would mean that other applications would allow even the Web Client to act as a "detached"  head. 

That said, that may not be detached enough for the webclient – at some point they may want it to be able to talk to any alfresco regardless of JVM which would mean we would have to transition it to the webservice or REST api sets

Who knows.  For my needs, remote classloader (different web apps) is good enough any further partitioning is gravy.