Expand my Community achievements bar.

SOLVED

RMI Connection to AEM 6.0 via JCR API

Avatar

Level 4

Hi,

AEM version: 6.0

Tried to make an rmi connection, from java application.

We followed the steps, as exactly as mentioned on the kb (https://helpx.adobe.com/experience-manager/kb/rmi-connection-crx-cq-561.html) and always we are getting the connection refused exception.

Apart from enabling RMI Connection listener, is we have to do anything at server level for enabling RMI?

In the code, we are referring to a parameter crx-application-name,  where we have to configure the same?

Kindly advice us on this.

error.log (After enabling rmi listener):

 *INFO* [CM Event Dispatcher (Fire ConfigurationEvent: pid=org.apache.sling.jcr.jackrabbit.server.RmiRegistrationSupport)] org.apache.sling.jcr.registration Using RMI Registry port 1199
 *INFO* [JcrInstaller.1] org.apache.sling.installer.provider.jcr.impl.JcrInstaller Registering resource with OSGi installer: [InstallableResource, priority=200, id=/apps/system/config/org.apache.sling.jcr.jackrabbit.server.RmiRegistrationSupport.config]

Code Snippet:

public static void main (String[] args){

        System.out.println("RMI to CRX Test Connection:");

        ClientRepositoryFactory factory = new ClientRepositoryFactory();

        Repository repository;

        String crxApplicationName = "virtual-crx";

        String repoUrl = "//localhost:1199/"+crxApplicationName;

        String workspace = "crx.default";

        String username = "admin";

        char [] password = "admin".toCharArray();

        try {

               repository = factory.getRepository(repoUrl);

               Session s = repository.login(new SimpleCredentials(username,password), workspace);

               System.out.println("Workspace: " + s.getWorkspace().getName());

               System.out.println("userId: "+s.getUserID());

        } catch (Exception e) {

               e.printStackTrace();

        }

 }

Exception:

RMI to CRX Test Connection:
Exception in thread "main" org.apache.jackrabbit.rmi.client.RemoteRuntimeException: java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: 
    java.net.ConnectException: Connection refused: connect
    at org.apache.jackrabbit.rmi.client.SafeClientRepository.getRemoteRepository(SafeClientRepository.java:85)
    at org.apache.jackrabbit.rmi.client.SafeClientRepository.<init>(SafeClientRepository.java:56)
    at org.apache.jackrabbit.rmi.client.ClientRepositoryFactory$1.<init>(ClientRepositoryFactory.java:90)
    at org.apache.jackrabbit.rmi.client.ClientRepositoryFactory.getRepository(ClientRepositoryFactory.java:90)
    at com.wbg.connectrepo.connectRepo.main(connectRepo.java:39)
Caused by: java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: 
    java.net.ConnectException: Connection refused: connect
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
    at sun.rmi.server.UnicastRef.newCall(Unknown Source)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at java.rmi.Naming.lookup(Unknown Source)
    at org.apache.jackrabbit.rmi.client.ClientRepositoryFactory$1.getRemoteRepository(ClientRepositoryFactory.java:95)
    at org.apache.jackrabbit.rmi.client.SafeClientRepository.getRemoteRepository(SafeClientRepository.java:83)
    ... 4 more

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

We also tried to make an rmi connection as mentioned on (http://dev.day.com/docs/en/crx/current/developing/accessing_the_crx.html#Accessing a Repository via RMI), in that case also we are getting the same exception

Code Snippet:

public static void main(String[] args) throws Exception{
        
        
            System.out.println("Test Rmi Connection.");
           
            Repository repository = JcrUtils.getRepository("rmi://localhost:1199/crx");

            SimpleCredentials creds = new SimpleCredentials("admin", "admin".toCharArray());
            Session session = null;
            
            
            session = repository.login(creds, "crx.default");
    }

Exception:

Exception in thread "main" javax.jcr.RepositoryException: Unable to access a repository with the following settings:
    org.apache.jackrabbit.repository.uri: rmi://localhost:1199/crx
The following RepositoryFactory classes were consulted:
    org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory: declined
    org.apache.jackrabbit.jcr2spi.Jcr2spiRepositoryFactory: declined
    org.apache.jackrabbit.commons.JndiRepositoryFactory: declined
    org.apache.jackrabbit.rmi.repository.RmiRepositoryFactory: failed
        because of RemoteRuntimeException: java.rmi.RemoteException: Failed to look up the RMI resource //localhost:1199/crx; nested exception is: 
    java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: 
    java.net.ConnectException: Connection refused: connect
        because of RemoteException: Failed to look up the RMI resource //localhost:1199/crx; nested exception is: 
    java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: 
    java.net.ConnectException: Connection refused: connect
        because of ConnectException: Connection refused to host: localhost; nested exception is: 
    java.net.ConnectException: Connection refused: connect
        because of ConnectException: Connection refused: connect
Perhaps the repository you are trying to access is not available at the moment.
    at org.apache.jackrabbit.commons.JcrUtils.getRepository(JcrUtils.java:223)
    at org.apache.jackrabbit.commons.JcrUtils.getRepository(JcrUtils.java:263)
    at com.wbg.connectrepo.connectRepo.main(connectRepo.java:21)

Thank,

Karthi

1 Accepted Solution

Avatar

Correct answer by
Employee
 
 

Thanks for the input Opkar!

Use Case: Connect crx remotely to execute query.

 

Is there any reason why it must be RMI? Could you not create a REST service for this request?

Regards,

Opkar

View solution in original post

11 Replies

Avatar

Employee

Try this AEM6 article: http://experience-aem.blogspot.de/2015/05/aem-6-sp2-accessing-crx-remotely-using-jcr-remoting-davex....

Accessing with WebDAV seems possible, but not with RMI. I'd get in touch with Daycare to find out the status of RMI access.

Avatar

Level 10

WHy not use JCR API from the Java client:

String aemUrl = "http://"+url +"/crx/server" ;
//Create a connection to the CQ repository running on local host
 Repository repository = JcrUtils.getRepository(aemUrl);

 //Create a Session
javax.jcr.Session session = repository.login( new SimpleCredentials("readonly", "readonly".toCharArray()));

This works perfectly from an external Java app.        

Avatar

Level 4

Thanks for the info Opkar Gill.

That will get work well with getting enabled "WEBDAV" on aem environments.

Ideally we won't enable webdav on production environments. So, we chose to go with RMI connection.

Any directions,  to fix that issue will be more helpful.

Thanks,

Karthi

Avatar

Level 4

Hi Scott,

Thanks for the inputs!

 But the same won't work, if we disable the WEBDAV on aem environments rite?

So in that case, how we will connect from java app?

Kindly advice us on this pls.

Use Case : Access crx remotely to execute query.

Thanks,

Karthi

Avatar

Employee

Hi Karthi,

it doesn't seem like it is currently possible. The last time I tried was with 5.6.1 and seem to remember issues with 6.x 

What is it you are trying to do via RMI?

 

You could contact daycare to see the current status of RMI support.

Regards,

Opkar

Avatar

Level 4

Opkar Gill wrote...

Hi Karthi,

it doesn't seem like it is currently possible. The last time I tried was with 5.6.1 and seem to remember issues with 6.x 

What is it you are trying to do via RMI?

 

You could contact daycare to see the current status of RMI support.

Regards,

Opkar

 

Thanks for the input Opkar!

Use Case: Connect crx remotely to execute query.

Avatar

Correct answer by
Employee
 
 

Thanks for the input Opkar!

Use Case: Connect crx remotely to execute query.

 

Is there any reason why it must be RMI? Could you not create a REST service for this request?

Regards,

Opkar

Avatar

Level 10

See this community article - its a Java Swing app that connects to AEM and pull in JCR Data:

[img]AAppSwing.png[/img]

https://helpx.adobe.com/experience-manager/using/java-swing-applications.html

Avatar

Level 4

I went through the article that you shared, in that also they are using same webdav approach Scott.

We disabled webdav on our environments for security reasons.

Is there any other way, to do the same. Please advice us.

getRepository method

In the getRepository method, a Session is created by using the JCR API.

//Retrieve member data from the JCR
public List<members> getRepository(String url)
{

    try {

        String aemUrl = "http://"+url +"/crx/server" ;

        //Create a connection to the CQ repository running on local host
        Repository repository = JcrUtils.getRepository(aemUrl);

         //Create a Session
        javax.jcr.Session session = repository.login( new SimpleCredentials("readonly", "readonly".toCharArray()));

Thanks,

Karthi

Avatar

Level 4

Hi Scott,

I tried something like below one to register rmi from my java app,

Is there any other way to get the crx repository instead of using jcrUtils (look on stroked line on the below code), because in that it requires to get the webdav enabled.

public static void main(String[] args) throws Exception{
        
        
    System.out.println("Test Rmi Connection.");
    Registry reg = LocateRegistry.createRegistry(2020);
           
    Repository repository = JcrUtils.getRepository("http://locahost:1010/crx/server");
            
    ServerAdapterFactory serverFactory = new ServerAdapterFactory();
    RemoteRepository remote = serverFactory.getRemoteRepository(repository2);
    reg.rebind("crx", remote);

    After hosting this  we are able to make rmi connection as below one

    Repository repos = JcrUtils.getRepository("rmi://localhost:1010/crx");

    }

Thanks,

Karthi

Avatar

Level 10

If RMI does not work - as suggested - you can log a bug. 

Another way to communicate from an external Java app (without using JCR or RMI) that would work is to write a series of custom Sling Servlets on AEM. The Sling Servlet can perform CRUD operations on the JCR. FRom within the Servlet - you can use the following code (which shows a more secure way to get data) that uses the getServiceResourceResolver API call.

Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, "datawrite");
ResourceResolver resolver = null;

try {
           
    //Invoke the adaptTo method to create a Session used to create a QueryManager
 resolver = resolverFactory.getServiceResourceResolver(param);
    session = resolver.adaptTo(Session.class);

You can use HTTP libs in the Java client to perform GET and POST operations. 

For example, the client can perform a GET, the servlet would get a result set and pass back the JCR data in JSON and the client would read the JSON and display. 

See this article as an example of a Java app using HTTP operations to interact with CQ (this posts files to a Sling Servlet): 

http://scottsdigitalcommunity.blogspot.ca/2014/03/creating-java-swing-applications-that.html