Proper way to load content from JSON into a JCR_JACKRABBIT-backed AemContext

1,313 views
Skip to first unread message

tomasz.k....@gmail.com

unread,
Jan 21, 2015, 5:17:11 AM1/21/15
to wcm-i...@googlegroups.com
Hello,

I have recently come across the wcm.io Testing library and I'm trying to write some integration tests for a set of classes that write data into the repository using the JCR API. In order to be able to verify that the data is written properly, I selected JCR_JACKRABBIT as the resource resolver type when creating my AemContext.

I have content retrieved from an actual AEM instance (I had it returned in JSON format by Sling by adding the .infinity selector and the .json extension) on my classpath as a JSON file. I can easily load it when I use JCR_MOCK or RESOURCERESOLVER_MOCK resource resolver types but as soon as I switch to JCR_JACKRABBIT, I get a NullPointerException.

Please see this thread on Stackoverflow for a neatly formatted summary with code snippets: http://stackoverflow.com/q/28021585/1407656

As per a suggestion I got as an answer, I added the following lines to my setUp method:

Session session = aemContext.resourceResolver().adaptTo(Session.class);
RepositoryUtil.registerNodeType(session, getClass().getResourceAsStream("/nodetypes/types.cnd"));

just before aemContext.load().json("/jcrdata/myPage.json", "/etc/mystuff/myTool");

types.cnd is a file on my classpath that contains the node type definitions as found in the CRX repository on my AEM instance.

This allowed me to get rid of the NPE but for some reason the cq:Page and cq:PageContent node types do not get recognized. This results in a PersistenceException being thrown upon calling aemContext.load().json("/jcrdata/myPage.json", "/etc/mystuff/myTool");

The problem seems to be that the cq:Page and cq:PageContent node types still cannot be found despite the fact that I explicitly add them in my types.cnd file. I took the definitions of these two types from http://docs.adobe.com/docs/en/cq/current/developing/custom_node_types.html and I made sure to include the namespace prefixes used in those definitions.

Here's an example stack trace that appears when I havea cq:Page in my content JSON: https://gist.github.com/toniedzwiedz/7571edffb2d44bc0a764


I can, however, successfully import the content as soon as I replace all cq:Page and cq:PageContent types with nt:unstructured
This allows me to execute my code against the repository and read the content that my tested class writes there but I'm a bit concerned that the fact my test content has different node types than its real counterpart might affect the test results in some cases.

I must say I'm a little surprised with how difficult this is to do and I'd expect an AEM-dedicated library to support the node types used by AEM out of the box. Is there something I'm missing here? Is there an easier way?

Kind regards,
Tomek

Stefan Seifert

unread,
Jan 21, 2015, 5:33:44 AM1/21/15
to wcm-i...@googlegroups.com
hello tomek.

before going into the details - why did you choose the JCR_JACKRABBIT backend? its market as "experimental" in the sling-mock project exactly because all those problems with registering problems, which is possible to solve but very tedios to get it right for all those complex node types as AEM uses.

so our recommendation is:

- use RESOURCERESOLVER_MOCK when you do not need JCR API but only sling CRUD API

- use JCR_MOCK when you need JCR API as well

- use JCR_JACKRABBIT only if you need special features not supported by JCR_MOCK, e.g. eventing, versioning etc. but only then, it’s the most heavyweight and most inperformant choice and not used much currently. we did some small improvements on this integration in the current trunk of sling-mock-jackrabbit in sling, esp. concering the content loader and special properties that cannot be imported, but this is not released yet.

stefan
>--
>You received this message because you are subscribed to the Google Groups
>"wcm-io Developers" group.
>To unsubscribe from this group and stop receiving emails from it, send an
>email to wcm-io-dev+...@googlegroups.com.
>To view this discussion on the web visit
>https://groups.google.com/d/msgid/wcm-io-dev/dc3c9669-ab1b-4b47-b07a-
>3ba468af9835%40googlegroups.com.
>For more options, visit https://groups.google.com/d/optout.

tomasz.k....@gmail.com

unread,
Jan 21, 2015, 5:52:51 AM1/21/15
to wcm-i...@googlegroups.com
Hi Stefan,

thanks for the lightning-fast answer.

While the JCR_MOCK resource resolver type allows me to mock calls made to the JCR API, I don't think I have a way of verifying that the data I'm trying to save actually makes it into the repository. As far as I know, no actual data will be stored anywhere when I invoke methods like Node.setProperty or JcrUtil.createPath when JCR_MOCK is used. I can't run my tested class against the mock repository and verify that what it writes into it is what I expect it to. Please correct me if I'm wrong.

I'm looking for a way to test some code that is largely based on void methods modifying the state of the repository. It leaves a lot to be desired when it comes to testability but I have reasons not to rewrite it.

A possible flow I'm thinking of is to:

1. Set up a repository and load the content that my tested class needs to read from a JSON file in the classpath
2. Run my tested class against the repository
3. Read the state of the repository to confirm that the tested functionality works as expected

Stefan Seifert

unread,
Jan 21, 2015, 5:57:54 AM1/21/15
to wcm-i...@googlegroups.com
hello tomek.

it is corrrect that JCR_MOCK does not persist what is written to it during the unit test. with every unit test you get a clean/empty mocked JCR repository.
but you can of course validate what was written to the mocked JCR at the end of you unit test by using the sling or JCR API. it fully supports read and write as long as the mocked JCR repository is in memory.

stefan

>-----Original Message-----
>From: wcm-i...@googlegroups.com [mailto:wcm-i...@googlegroups.com] On
>Behalf Of tomasz.k....@gmail.com
>Sent: Wednesday, January 21, 2015 11:53 AM
>To: wcm-i...@googlegroups.com
>Subject: Re: Proper way to load content from JSON into a JCR_JACKRABBIT-backed
>AemContext
>
>--
>You received this message because you are subscribed to the Google Groups
>"wcm-io Developers" group.
>To unsubscribe from this group and stop receiving emails from it, send an
>email to wcm-io-dev+...@googlegroups.com.
>To view this discussion on the web visit
>https://groups.google.com/d/msgid/wcm-io-dev/5011fa8d-ed5e-4178-aab4-
>9a77b6a465d8%40googlegroups.com.

tomasz.k....@gmail.com

unread,
Jan 21, 2015, 6:45:09 AM1/21/15
to wcm-i...@googlegroups.com
I see. I decided to switch to JCR_JACKRABBIT after my attempts to read previously written data from the repository had failed, which led me to mistake my own errors for a characteristic of the implementation I was using.

I just managed to get my test working with the JCR_MOCK resource resolver type so it seems I will not need the JCR_JACKRABBIT implementation at all for this specific case.

While I don't need this problem to be solved at this time, I think this problem might be of interest to those who want to use JCR_JACKRABBIT for the eventing and versioning support. I'll be glad to check out the new version once it's released.

Thanks a lot and have a nice day,
Tomek

Reply all
Reply to author
Forward
0 new messages