DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Data Engineering
  3. Data
  4. EclipseLink JPA2 Distributed Cache Coordination

EclipseLink JPA2 Distributed Cache Coordination

Łukasz Budnik user avatar by
Łukasz Budnik
·
Jul. 17, 12 · Interview
Like (0)
Save
Tweet
Share
8.85K Views

Join the DZone community and get the full member experience.

Join For Free
In larger systems where processing of user requests is distributed you need some sort of cache coordination otherwise the results may be incorrect and/or user experience bad. In Qualitas system I have a front-end Spring web application which sends AMQP messages to a broker which are later on picked up by Apache Camel route. I had a problem with caching because the web application was showing old data. To fix this I decided to use distributed cache coordination. Read below to find out how to configure and run distributed cache coordination using EclipseLink JPA2. At the end of the article there is a link to working example.

The problem and the fix 

So, in my case both web and integration applications use the same data access layer (JPA2 and EclipseLink). But while Apache Camel route was updating statuses with every successfully completed step, the web application was still showing old statuses. I decided to use EclipseLink cache coordination over JMS (RMI and CORBA are supported as well). Ideally I would use AMQP instead of JMS, but still JMS is a better choice than RMI :)

Prerequisite

You need a JMS broker. We all know that ActiveMQ is the best option so go ahead and download it from here: http://activemq.apache.org/download.html. Below I used default settings so all you have to do is just start the ActiveMQ broker.

Updating persistence.xml

I had to add the following 3 lines to my persistence.xml file:

<property name="eclipselink.cache.coordination.protocol" value="jms" />
<property name="eclipselink.cache.coordination.jms.topic" value="jms/Qualitas.EclipseLinkCacheTopic" />
<property name="eclipselink.cache.coordination.jms.factory" value="jms/Qualitas.EclipseLinkCacheConnectionFactory" />

And that was all. Almost all, as then I had to configure JNDI contexts on both web application (easy) and Apache Camel (not that easy) ends.

Configuring JNDI context in Jetty

I'm using Jetty 7.6. First I had to create WEB-INF/jetty-env.xml file and define my resources:
 

<?xml version="1.0"?>
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
 <New id="eclipseLinkCacheConnectionFactory" class="org.eclipse.jetty.plus.jndi.Resource">
  <Arg>jms/Qualitas.EclipseLinkCacheConnectionFactory</Arg>
  <Arg>
   <New class="org.apache.activemq.ActiveMQConnectionFactory">
    <Arg>nio://localhost:61616</Arg>
   </New>
  </Arg>
 </New>
 <New id="eclipseLinkCacheTopic" class="org.eclipse.jetty.plus.jndi.Resource">
  <Arg>jms/Qualitas.EclipseLinkCacheTopic</Arg>
  <Arg>
   <New class="org.apache.activemq.command.ActiveMQTopic">
    <Arg>Qualitas.EclipseLinkCacheTopic</Arg>
   </New>
  </Arg>
 </New>
</Configure>

  Then I had to add proper mappings to my web.xml file:

<resource-ref>
 <res-ref-name>jms/Qualitas.EclipseLinkCacheConnectionFactory</res-ref-name>
 <res-type>javax.jms.QueueConnectionFactory</res-type>
 <res-auth>Container</res-auth>
</resource-ref>
<resource-env-ref>
 <resource-env-ref-name>jms/Qualitas.EclipseLinkCacheTopic</resource-env-ref-name>
 <resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
</resource-env-ref>

 As promised, configuring JNDI context in web application was easy. To be sure it actually worked I ran the web application and opened ActiveMQ web console. I saw Qualitas.EclipseLinkCacheTopic and I saw one active consumer.

Configuring JNDI in Apache Camel

This took me some time. To cut long story short, in order to configure JNDI and bind objects to it, you have to follow these steps:

1. Create factory and topic In your Spring configuration file copy and paste:

<amq:topic id="eclipseLinkCacheTopic" physicalName="Qualitas.EclipseLinkCacheTopic" />
<amq:connectionFactory id="eclipseLinkCacheConnectionFactory" brokerURL="nio://localhost:61616" /> 

2. Create JNDI context

To cut long story short. I first wanted to try Sun's reference implementation (as there are many sites in google that refer to it), but it's not a part of JDK any more. I also wanted to try Apache OpenEJB (as I'm a huge fan of Apache Geronimo), but I was scared with all the dependencies I saw in my console. After some googling I found a lightweight JNDI implementation from... Jetty :) Here's how to configure Spring's JndiTemplate with Jetty's JNDI implementation:

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
 <property name="environment">
  <props>
   <prop key="java.naming.factory.initial">org.eclipse.jetty.jndi.InitialContextFactory</prop>
   <prop key="java.naming.factory.url.pkgs">org.eclipse.jetty.jndi</prop>
  </props>
 </property>
</bean>

 3. Bind connection factory and topic to JNDI context

I had JNDI directory, next I had to bind my connection factory and topic to JNDI context. I wrote a pretty naive implementation using Spring's autowiring (it was naive because it would fail when there would be more autowire candidates, but was OK for me):

@Component
public class JndiBinder {
    @Autowired
    private JndiTemplate jndiTemplate;
    @Autowired
    private ConnectionFactory eclipseLinkCacheConnectionFactory;
    @Autowired
    private Topic eclipseLinkCacheTopic;
    @PostConstruct
    protected void bindEclipseLinkCacheResources() throws NamingException {
        jndiTemplate.bind("jms", new InitialContext());
        jndiTemplate.bind("jms/Qualitas.EclipseLinkCacheConnectionFactory", eclipseLinkCacheConnectionFactory);
        jndiTemplate.bind("jms/Qualitas.EclipseLinkCacheTopic", eclipseLinkCacheTopic);
    }
}

 That was all.

Running the sample 

When I started Jetty and Apache Camel, in ActiveMQ web console I saw two consumers attached to Qualitas.EclipseLinkCacheTopic. And when I uploaded a sample WS-BPEL process to my web application I saw UPLOADED status, but after a few splits of a second I saw PROCESSING status and after a few seconds I finally saw INSTALLED status. All worked like a charm.

If you're interested in full source code, Qualitas is hosted on both googlecode: http://code.google.com/p/qualitas/source/browse/ and GitHub: https://github.com/lukasz-budnik/qualitas. For now it's in master branch, but in one week time it will be a part of 0.0.5-SNAPSHOT release and will be tagged as 0.0.5-SNAPSHOT. This tag will be of course stable. Master branch may not be always stable. Before cloning master branch make sure CouldBees' Jenkins is saying that it's safe to do so: https://qualitas.ci.cloudbees.com/job/Qualitas/modules. Qualitas is a distributed system and a few things have to be configured in order to run it. Please refer to http://code.google.com/p/qualitas/wiki/BuildingTheProject and http://code.google.com/p/qualitas/wiki/RunningTheProject wiki pages.

Summary

Any comments most welcomed. It would be nice to have AMQP-based cache coordination in EclipseLink. I'm thinking about volounteering to implement this feature :)

Distributed cache Cache (computing) Web application EclipseLink Apache Camel

Published at DZone with permission of Łukasz Budnik, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Load Balancing Pattern
  • Top 10 Best Practices for Scaling Your Application: Expert Tips for Optimizing Performance and Ensuring Reliability
  • How to Create a Dockerfile?
  • GPT-3 Playground: The AI That Can Write for You

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: