Search code examples
javaapache-cameljackrabbitjcr

The trouble about the JCR multi-valued property when using JCR_GET_BY_ID


I'm using the Apache Camle version 2.14.0 with Apache Jackrabbit 2.8.0 and have found some trouble about the camel-jcr with JCR_GET_BY_ID when the node contains multi-valued property as the following: -

2014-09-26 10:19:21.604 [Client Event Poller] [] ERROR o.a.c.processor.DefaultErrorHandler
       - 215 log Failed delivery for (
      MessageId: ID-CharleeCh-53350-1411701537295-3-1 on 
      ExchangeId: ID-CharleeCh-53350-1411701537295-3-12). 
      Exhausted after delivery attempt: 1 caught: 
      javax.jcr.ValueFormatException: property /my-parent3/my-child31/myMuliple 
      is a multi-valued property, so it's values can only be retrieved as an array

Stacktrace
javax.jcr.ValueFormatException: property /my-parent3/my-child31/myMuliple 
    is a multi-valued property, so it's values can only be retrieved as an array
at org.apache.jackrabbit.rmi.server.ServerObject.getRepositoryException(ServerObject.java:139) ~[jackrabbit-jcr-rmi-2.8.0.jar:na]
at org.apache.jackrabbit.rmi.server.ServerProperty.getValue(ServerProperty.java:62) ~[jackrabbit-jcr-rmi-2.8.0.jar:na]
at sun.reflect.GeneratedMethodAccessor12.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_65]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_65]
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322) ~[na:1.7.0_65]
at sun.rmi.transport.Transport$1.run(Transport.java:177) ~[na:1.7.0_65]
at sun.rmi.transport.Transport$1.run(Transport.java:174) ~[na:1.7.0_65]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_65]
at sun.rmi.transport.Transport.serviceCall(Transport.java:173) ~[na:1.7.0_65]
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556) ~[na:1.7.0_65]
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811) ~[na:1.7.0_65]
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670) ~[na:1.7.0_65]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) ~[na:1.7.0_65]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) ~[na:1.7.0_65]
at java.lang.Thread.run(Thread.java:745) ~[na:1.7.0_65]
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:275) ~[na:1.7.0_65]
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:252) ~[na:1.7.0_65]
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:161) ~[na:1.7.0_65]
at org.apache.jackrabbit.rmi.server.ServerProperty_Stub.getValue(Unknown Source) ~[jackrabbit-jcr-rmi-2.8.0.jar:na]
at org.apache.jackrabbit.rmi.client.ClientProperty.getValue(ClientProperty.java:164) ~[jackrabbit-jcr-rmi-2.8.0.jar:na]
at org.apache.camel.component.jcr.JcrProducer.process(JcrProducer.java:69) ~[camel-jcr-2.14.0.jar:2.14.0]

I also have a chance to investigate to the camel-jcr source code, the org.apache.camel.component.jcr.JcrProducer, and found that it use the following:-

        if (JcrConstants.JCR_INSERT.equals(operation)) {
            ...
            for (String key : headers.keySet()) {
                Value value = converter.convertTo(Value.class, 
                                                  exchange, 
                                                  message.getHeader(key));
                ...
            }
            ...
        } else if (JcrConstants.JCR_GET_BY_ID.equals(operation)) {
            ...
            while (properties.hasNext()) {
                Property property = properties.nextProperty();
                Class<?> aClass = classForJCRType(property);
                Object value = converter.convertTo(aClass, 
                                                   exchange, 
                                                   property.getValue());
                ...
            }
        } else {
            throw new RuntimeException("Unsupported operation: " + operation);
        }

Please correct me if I'm wrong. Since the code uses the Value.class and property.getValue() which is for the non-multi-valued. Does it mean that the camel-jcr does not provide the support to the multi-valued?

Do we have any workaround for supporting the multi-valued? At the moment I consider to replace the JcrProducer with my own interim fixing. Anyhow I thought that it may not be a proper way and would like your help to advise further


Solution

  • I've posted to the Camel User Group and found that it is a limitation for the current camel-jcr:2.14.0. I've fixed as the pull request.

    I hope this may help other who faces the same issue.