tag:blogger.com,1999:blog-22992201355185846152024-02-06T21:55:52.001-08:00Java™ and other animalsDror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.comBlogger13125tag:blogger.com,1999:blog-2299220135518584615.post-30288716086690829912011-05-25T13:57:00.000-07:002011-05-25T14:02:28.948-07:00Data Grids And The Race To The CloudTwo recent announcements from the past month are indicating that the Data Grid market is getting hot and that everybody needs one for their cloud offering:<br />
<ol><li><span style="font-size: small;"><a href="http://www.terracotta.org/news/pr/2011-05-23-terracotta-joins-software-ag">Software AG acquires Terracotta Inc., a leader in in-memory and cloud enabling technology</a></span> (May 23, 2011)</li>
<li><a href="http://www.redhat.com/about/news/prarchive/2011/Red-Hat-Introduces-JBoss-Enterprise-Data-Grid">Red Hat launches Early Access Program for New Offering; New Data Grid Solution Brings Cloud Scale and Agility to the Data-Tier</a> (May 03, 2011)</li>
</ol>The first announcement is by Software AG, a provider of BPM solutions with revenues of €1.1 billion in 2010, acquiring Terracotta, one of the leading providers of in-memory data grids (Ehcache, BigMemory).<br />
Software AG clearly states that Terracotta was acquired for supporting its cloud offering : <br />
<blockquote>The ability to scale the processing of massive loads of data across flexible, modular, geographically distributed architectures will also drive <b> cloud </b>adoption and transform Software AG into a full <b>Platform-as-a-Service</b> (PaaS) provider in the mid-term </blockquote><br />
The second announcement is by Red-Hat launching a new data grid solution based on <a href="http://www.jboss.org/infinispan">Infinispan</a>, a JBoss community project and one of the promising solutions in my opinion (lock free, MVCC). The term "cloud" repeats 7 times across this announcement + one occurrence of the term "PaaS".<br />
Red-Hat already launched a two cloud solutions <a href="http://www.redhat.com/solutions/cloud/cloudforms/">CloudForms</a> and <a href="http://www.redhat.com/solutions/cloud/openshift/">OpenShift</a> Platform as-a-Service (PaaS). Currently OpenShift provides support for Memcached (which is a distributed but not <a href="http://www.blogger.com/">elastic cache</a> solution), adding the new elastic data grid solution to the offering is a necessary addition to OpenShift.<br />
Another interesting point - the Red-Hat announcement also refers to a blog <a href="http://www.blogger.com/">post </a>by Forrester Research analyst Mike Gualtieri which, among other things, deals with the tight relation between "Elastic caching" and "Cloud computing". Mike Gualtieri deeply covered the topic of elastic caching in two blog posts which got a lot of attention from players in this market, not all mentioned in his post (<a href="http://blogs.oracle.com/OTechMusings/entry/elastic_versus_distributed_in">Oracle Coherence</a>, <a href="http://natishalom.typepad.com/nati_shaloms_blog/2010/06/wtf-is-elastic-data-grid-by-example.html">GigaSpaces</a>, <a href="http://www.blogger.com/">IBM</a> and now Red-Hat). <br />
If you want to read more details about the different classifications of cache solutions an the role of elastic caches in cloud based solution I recommend Nati Shalom's post - <a href="http://natishalom.typepad.com/nati_shaloms_blog/2010/06/wtf-is-elastic-data-grid-by-example.html">WTF is elastic data grid </a><br />
<br />
These two announcement adds to the recent acquisition of <a href="http://www.gemstone.com/products/gemfire">GemStone</a>, which develops distributed caching and database solutions, by <a href="http://www.blogger.com/">VMWare </a>(SpringSource) resulting with the addition of GemFire to the <a href="http://www.springsource.com/products/cloud-application-platform">vFabric </a>cloud application platform.<br />
<br />
So its seems that almost all ISV in the data grid market where acquired by the big players to serve their cloud strategy. <br />
If I'm not mistaken, <a href="http://www.blogger.com/">Gigaspaces </a>is the only serious independent player left in this domain (although its offering is much wider than just an elastic cache). I'm very interested to see if they will stay this way.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<span style="color: black;"><span style="font-family: Arial,sans-serif;"><br />
</span></span><br />
<ol></ol><ul style="font-family: inherit;"></ul>Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com0tag:blogger.com,1999:blog-2299220135518584615.post-37431552844149782872011-05-23T14:57:00.000-07:002011-05-24T08:21:37.066-07:00OpenShift Flex part 2 - Create, deploy and run a SeamForge application in less than 10 minutesIn my last <a href="http://drorbr.blogspot.com/2011/05/test-driving-red-hat-openshift-flex.html">post </a>I started reviewing OpenShift - the new PaaS offering by Red-Hat.<br />
After playing with the sample application provided with OpenShift, I wanted to check how to deploy my own application.<br />
I decided to go with a very basic application created using <a href="http://seamframework.org/Documentation/SeamForge">SeamForge</a>, a rapid application generation tool which is a part of the Seam framework. What's nice about SeamForge is that it also<a href="http://www.blogger.com/post-edit.g?blogID=2299220135518584615&postID=3743155284414978287" id="d0e19"> lets you to take an existing Java EE project and work-in new functionality</a>.<br />
Following the SeamForge <a href="http://docs.jboss.org/forge/1.0.0.Alpha3/reference/en-US/html/forge-generate.webapp.javaee.html">documentation </a>(7 simple steps and 9 commands) I generated a basic Java EE CRUD web-application.based on JSF, Facelets, Seam and <a href="http://metawidget.org/">Metawidget.</a><br />
By the way, there is an open <a href="https://issues.jboss.org/browse/SEAMFORGE-188">issue </a>at the SeamForge Jira for directly deploying Forge application to OpenShift.<br />
<br />
Next I went on to deploying an running the application on OpenShift:<br />
<br />
The first step was to create a new application (applications --> add application).<br />
<br />
<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqyuy-_KDVvo8bWnAe1Q0TopFqYs21Dtshpeb6lYFRHqFVRmFZmd5nYpmqQREX407fNMV5FtAlYkmwiyRFpD5FbGYrHFRDGdmnl1vbbnFkXbs9yC2e0gCUHKVCq6MNdC3zMx4OA9czcGJ7/s1600/openshift-newapp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqyuy-_KDVvo8bWnAe1Q0TopFqYs21Dtshpeb6lYFRHqFVRmFZmd5nYpmqQREX407fNMV5FtAlYkmwiyRFpD5FbGYrHFRDGdmnl1vbbnFkXbs9yC2e0gCUHKVCq6MNdC3zMx4OA9czcGJ7/s320/openshift-newapp.png" width="267" /></a></div><br />
Once the application is named and given a version, it is time to decide which infrastructure components are required for running the application. In order to do so, you need to choose the newly created application from the applications list and select the "Components" tab.<br />
In this case I only needed a JDK and a JBoss application server (version 6 or 7). There was no need for an external database since the application uses the JBoss default datasource.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3wO2KG8W2nsYSN5NTeW4MXHopZLFpVYLmTjE-L-xuc1fYG5z7tZ6zdSGluK7jfUtBqXDutIegnwCUhhh3CPoUM10f4Oa2OLZSSD1P1UXwt5pCVozHAoMdWV5_nrDNZ9yWo5TlgrDl7QBT/s1600/openshift-components.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3wO2KG8W2nsYSN5NTeW4MXHopZLFpVYLmTjE-L-xuc1fYG5z7tZ6zdSGluK7jfUtBqXDutIegnwCUhhh3CPoUM10f4Oa2OLZSSD1P1UXwt5pCVozHAoMdWV5_nrDNZ9yWo5TlgrDl7QBT/s320/openshift-components.png" width="320" /></a></div><br />
Next step is uploading the application files. Staying in my new application context, I switched to the "Files" tab and chose to upload the application war file. Notice that choosing to import an existing application requires a file in VPM format (and not a Java archive as I tried before RTFM).<br />
After uploading, OpenShift automatically extracted my war file. From the "Files" tab I can now view my application files and edit them (in a very simple editor). This is very useful if you want to make some configuration changes without sending filed back and forth to the server.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnN1bWFzJ0pDGCiFfA7yF3TrXxYrrzicqhdYK0ABO9WjpCy2ta3YYsGUI-avagKqviwjGWz9TViFxiykwn3Y23LX9n14t5jd0OMEF8963aLUM7fqqf8J4Qzh_xxXH3G1pzj9BaTa_LHmRO/s1600/openshift-ready-to-publish.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnN1bWFzJ0pDGCiFfA7yF3TrXxYrrzicqhdYK0ABO9WjpCy2ta3YYsGUI-avagKqviwjGWz9TViFxiykwn3Y23LX9n14t5jd0OMEF8963aLUM7fqqf8J4Qzh_xxXH3G1pzj9BaTa_LHmRO/s320/openshift-ready-to-publish.png" width="320" /></a></div>At this point OpenShift indicated that there are 42 changes to the application, which are actually all the files I imported. You can see the list of changes from the console and diff them with the previous versions of the files.<br />
Since I had nothing more to configure I went on to deploying the application.In a more realistic scenario this would be the time to perform some configuration tasks on the various infrastructure components. OpenShift provides a way to configure the component using a wizard, which is actually a form with all the major configuration details, or expert mode which allows you to directly edit the configuration files.<br />
<br />
So, last step was choosing to deploy all changes, which actually meant deploying the application to JBoss.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCR5tcaKreY6u7RjA73dfyPaKnCj_dxmvOYJD872bRc03f_AwdbzeR6ntB2GIPWnacj2NxIIztKqKVkl0rmla8t0VYKid07mo4i6PFWs3EvGc40eYQWHinFhuCCuT-veMuutvlWSHbZdig/s1600/openshift-deploying.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="162" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCR5tcaKreY6u7RjA73dfyPaKnCj_dxmvOYJD872bRc03f_AwdbzeR6ntB2GIPWnacj2NxIIztKqKVkl0rmla8t0VYKid07mo4i6PFWs3EvGc40eYQWHinFhuCCuT-veMuutvlWSHbZdig/s320/openshift-deploying.png" width="320" /></a></div><br />
<br />
After the last step I had a deployed application which can be tested.<br />
The "Overview" tab of the "Applications" section has all the information required for accessing your application.<br />
<br />
Latest step was checking the application is actually working<br />
<br />
<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwO6XZ6Al0oZmjtKzNq3X10QmxP8BELgmevsxmvVLBOBK68X0iyEFXnh43j1E-UN5f2ukoITGzm4haUUvs54iS3-ZXOMABlVWVCysbrUY4M4LlpTVmVYg0BeTQXDez0fb83OAQDFcHvX37/s1600/openshift-app.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="130" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwO6XZ6Al0oZmjtKzNq3X10QmxP8BELgmevsxmvVLBOBK68X0iyEFXnh43j1E-UN5f2ukoITGzm4haUUvs54iS3-ZXOMABlVWVCysbrUY4M4LlpTVmVYg0BeTQXDez0fb83OAQDFcHvX37/s320/openshift-app.png" width="320" /></a></div>So, using SeamForge and OpenShift I had a simple web application created, deployed an running in less than 10 minutes.<br />
<br />
Of course this is a very simple application and not a real life scenario, and yet it shows a little about the power of RAD + PaaS.Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com1tag:blogger.com,1999:blog-2299220135518584615.post-51488242509965100252011-05-18T12:51:00.000-07:002011-05-24T08:21:37.067-07:00Test Driving Red Hat OpenShift Flex<div style="font-family: inherit;"><a href="https://openshift.redhat.com/app/">OpenShift </a>is a new new platform-as-a-service offering by Red-Hat announced on May 4th.</div><div style="font-family: inherit;">OpenShift will be available in Express, Flex and Power modes. The Express and Flex offerings were made availability in developer preview and the Power option is coming soon.</div><div style="font-family: inherit;">The new platform is aimed for Java, Ruby, PHP, and Python applications, and has support for the MySQL and MongoDB databases.</div><div style="font-family: inherit;">OpenShift express offers free hosting while OpenShift Flex offers a greater degree of control and choice over the middleware components with built-in versioning, monitoring and auto scaling.<br />
The OpenShift platform is based on code by Makara (a cloud start-up company acquired by Red-Hat in 2010) plus some RHEL isolation features, the JBoss EE runtime and some other components.<br />
For now OpenShift is not open-sourced, but Red-Hat has promised to make the code available.<br />
<div style="background-color: transparent; border: medium none; color: black; overflow: hidden; text-align: left; text-decoration: none;"></div></div><br />
<div style="font-family: inherit;">I decided to give the OpenShift Flex version a try. </div><div style="font-family: inherit;">In order to try OpenShift you have to <a href="https://openshift.redhat.com/app/user/new/flex">register </a>as a new user. After you a registered and logged in you can start using the Flex Console.<br />
At the beginning you will have to follow a few initial setup steps including setting up a cloud provider (currently only Amazon EC2) , creating a cluster of servers and deploying a sample application. Notice that you need an active Amazon EC2 account and you will be required to provide your account access keys (can be found in the <a href="https://console.aws.amazon.com/s3/home">AWS management console</a>).</div><div style="font-family: inherit;">The first 3 steps are part of an 8 steps self guided tour to OpenShift. You can come back to this guide whenever you want.</div><div style="font-family: inherit;">The Flex console is, surprisingly, a Flex based graphical user interface for provisioning cloud resources, governing the size and location of your cloud servers and managing the lifecycle of your cloud deployed applications.</div><div style="font-family: inherit;">The console is designed as a portal with a tab panel containing all major functionality of the console. The major areas of the console are:<br />
<br />
The "INTRO" tab allows your to take the self guided tour and provides links to some how-to guides (PDF format).</div><div style="font-family: inherit;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvx6HnSTydsHWZG9g3aEyiK_ycC08jAbk9K0BpTzeFqx8GJtqWgY6q_uzz6qSppFYDQ51SjnuZOr6tQmnchyDxjQnRVbHWwu8XLGT0cWPv2_SX-c4j41tWRQOg7Qy6mHVI0vbmwu2VlFtS/s1600/openshift-tab-panel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="14" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvx6HnSTydsHWZG9g3aEyiK_ycC08jAbk9K0BpTzeFqx8GJtqWgY6q_uzz6qSppFYDQ51SjnuZOr6tQmnchyDxjQnRVbHWwu8XLGT0cWPv2_SX-c4j41tWRQOg7Qy6mHVI0vbmwu2VlFtS/s320/openshift-tab-panel.png" width="320" /></a></div><div style="font-family: inherit;"><br />
</div><div style="font-family: inherit;">The "CLOUDS" tab allows you to manage the cloud accounts which are used for hosting your applications.</div><div style="font-family: inherit;">Once you have a cloud account setup you can move on to the "CLUSTERS" tab for creating a cluster of servers and defining basic cluster characteristics such as number of servers, number of cores, memory and disk space and more advanced ones related to auto scaling. Additionaly this area contains functionality for importing/exporting database and setting email preferences.<br />
Creating a new cluster will result with creating cloud servers and installing necessary software one them.</div><div style="font-family: inherit;"></div><div style="font-family: inherit;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbM2ipvFxtFFQ62EWk_Cj4g8A5d_KixLWgJZz1mtMFPeV6KDvh9lVUQgEKEn_5wy-7iqU85Rfz8sQyMpFD7Wn_mtzf1W2P0B7mRR3TgSPSuf5JzOgq8BO7Hxl4EexOxgLtvMBURS4kOeVH/s1600/openshift-clusters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbM2ipvFxtFFQ62EWk_Cj4g8A5d_KixLWgJZz1mtMFPeV6KDvh9lVUQgEKEn_5wy-7iqU85Rfz8sQyMpFD7Wn_mtzf1W2P0B7mRR3TgSPSuf5JzOgq8BO7Hxl4EexOxgLtvMBURS4kOeVH/s320/openshift-clusters.png" width="320" /></a></div><div style="font-family: inherit;"><br />
</div><div style="font-family: inherit;">The "SERVERS" tab view information about the cloud servers in your cluster including basic resource utilization statistics. It also allows you to join/unjoin servers to a cluster. </div><div style="font-family: inherit;">Applications are added and managed in the "APPLICATIONS" tab. At this area you can control various aspects of the application lifecycle from build to deployment, view the application files, configure it and allocate various software components (JDK, web server, app server, database, cache and more). It is also possible to view various changes made to the application files, diff them with previous versions and deploy them to production.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH77HiR7742QewtPK8cTU3aE83RRDTeAy0RdNFR6ziPYKG7kpC8jPt2wlqDoHIgbPN4CLpRQRCLK5P4srQJ2MYm9h4v65eFER3vwTqHKxU3AnGZO2HBRiLHqYc8Neal24dq4EBYq_5Kv9V/s1600/openshift-servers.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="104" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH77HiR7742QewtPK8cTU3aE83RRDTeAy0RdNFR6ziPYKG7kpC8jPt2wlqDoHIgbPN4CLpRQRCLK5P4srQJ2MYm9h4v65eFER3vwTqHKxU3AnGZO2HBRiLHqYc8Neal24dq4EBYq_5Kv9V/s320/openshift-servers.png" width="320" /></a></div><br />
<br />
The "PERFORMANCE" tab is used for performance monitoring and contains a lot of nicely displayed visual information about the performance of various components of the application from the underlying server to the application code.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD573CgisoVm-Jg12H62Z677LEjKrT9EbEpqF-9X8ZgBa1vs7rtTslsEzFI_JTJVFW6sIMwH59oX3tQEXG1ppKGWEFpebDYjCkJ0lLXMGtqXp4alsEI4Artw9R5L9F5niot4j6jat5qxvH/s1600/openshift-performance.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="202" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD573CgisoVm-Jg12H62Z677LEjKrT9EbEpqF-9X8ZgBa1vs7rtTslsEzFI_JTJVFW6sIMwH59oX3tQEXG1ppKGWEFpebDYjCkJ0lLXMGtqXp4alsEI4Artw9R5L9F5niot4j6jat5qxvH/s320/openshift-performance.png" width="320" /></a></div><br />
</div><div style="font-family: inherit;">Additionally there are tabs for viewing various logs and events.</div><div style="font-family: inherit;"><br />
</div><div style="font-family: inherit;">My first experience with the console is OK, a little buggy and the UI still needs improvement, especially when some actions takes time and you do not get visual indication, while are actions leaves you stuck with a rotating clock indicator which never disappears. I also encountered some connectivity and stability issues, but after all this is only a developers preview version for now.</div><div style="font-family: inherit;">Next steps will be to test the more interesting features provided by OpenShift such as auto scaling and deploying my own applications on it (not the samples provided by Red-Hat).</div><div style="font-family: inherit;"><br />
</div><div style="font-family: inherit;">At next posts I will dive deeper into the various functionality provided by OpenShift and my personal experience with it.</div><div style="font-family: inherit;"></div>Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com4tag:blogger.com,1999:blog-2299220135518584615.post-52680555988184820152010-02-19T14:38:00.000-08:002010-02-21T06:25:52.642-08:00Migrating a Spring/Hibernate application to MongoDB - Part 1<span style="font-size: small;"><b>Backgorund</b></span><br />
<br />
For the past few years ORM have been the de facto solution for bridging the gap between object oriented programming languages and relational databases.Well, most of the developers using ORM care about writing less persistence code and SQL than they care about the <a href="http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch">object-relational impedance mismatch</a>. As time passed and more experience gained, some <a href="http://pab-data.blogspot.com/2008/02/is-orm-dead-end.html">people </a>started to claim that maybe ORM is <a href="http://codemonkeyism.com/orms/">not the best solution available</a>.<br />
Another option for storing your objects, which have been there for quite some time, are non-SQL databases. With recent explosion of non-relational databases and the <a href="http://nosql-databases.org/">NoSQL </a>movement ("Not Only SQL") this option is becoming more and more viable.<br />
<br />
There are a lot of examples showing how to develop a new application based on a non-relational database. But what if you already have an application using a relational database + ORM and you want to migrate it to a non-relational database?<br />
<br />
In the next few posts I will try to suggest a migration path for a Spring/Hibernate (JPA) application to MongoDB.<br />
<a href="http://www.mongodb.org/">MongoDB</a> is a scalable, high-performance, open source, <a href="http://blog.mongodb.org/post/119945109/why-schemaless">schema-free</a>, <a href="http://en.wikipedia.org/wiki/Document-oriented_database">document-oriented</a> database and is one of the interesting non-relational databases available today (together with <a href="http://incubator.apache.org/cassandra/">Cassandra</a>, <a href="http://hadoop.apache.org/hbase/">HBase</a>, <a href="http://code.google.com/p/redis/">Redis</a> and others).<br />
<br />
<b>The application</b><br />
<br />
The example application is a very simple blogging engine implemented using the Spring/Hibernate (JPA) stack.<br />
The two main entities are Blogger and BlogPost. There are data access objects (DAO) with matching interfaces for both entities.<br />
<br />
<b>Setting up and connecting to MongoDB</b><br />
<br />
Setting up MongoDB is a pretty simple procedure. The MongoDB <a href="http://www.mongodb.org/display/DOCS/Quickstart">quickstart</a> and <a href="http://www.mongodb.org/display/DOCS/Getting+Started">getting started</a> pages contains all the required details.<br />
In order to connect to MongoDB we will need to use the <a href="http://www.mongodb.org/display/DOCS/Java+Language+Center">Mongo Java driver</a> :<br />
<br />
<pre style="border: thin solid; color: black; font-family: monospace; font-style: normal; font-weight: normal; padding: 5px;overflow: scroll;"><span style="color: navy;"><</span><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">dependency</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;">></span>
<span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="color: navy;"><</span></span><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">groupId</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;">></span><span style="color: black; font-style: normal; font-weight: bold;">org.mongodb</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="color: navy;"><</span></span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">/groupId</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;">></span>
<span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="color: navy;"><</span></span><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">artifactId</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;">></span><span style="color: black; font-style: normal; font-weight: bold;">mongo</span><span style="color: black; font-style: normal; font-weight: bold;">-java-driver</span></span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="color: navy;"><</span></span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">/</span></span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">artifactId</span><span style="color: black;">></span>
<span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><</span><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">version<span style="color: black;">></span></span><span style="color: black; font-style: normal; font-weight: bold;">1.2.1</span></span></span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="color: navy;"><</span></span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">/</span></span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">version</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;">></span>
<span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><</span><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">dependency</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;">></span></span></span></span></pre><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><br />
</span></span></span><br />
Next step is adding a new Spring service that will provide MongoDB connections. This is a basic implementation which uses the default configuration.<br />
<br />
<pre style="border: thin solid; color: black; font-family: monospace; font-style: normal; font-weight: normal; padding: 5px;overflow: scroll;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="color: maroon; font-style: normal; font-weight: normal;">3 </span><span style="color: navy; font-style: normal; font-weight: bold;">import</span> com.mongodb.DB;
<span style="color: maroon; font-style: normal; font-weight: normal;">4 </span><span style="color: navy; font-style: normal; font-weight: bold;">import</span> com.mongodb.Mongo;
<span style="color: maroon; font-style: normal; font-weight: normal;">5 </span><span style="color: navy; font-style: normal; font-weight: bold;">import</span> java.net.UnknownHostException;
<span style="color: maroon; font-style: normal; font-weight: normal;">6 </span>
<span style="color: maroon; font-style: normal; font-weight: normal;">7 </span><span style="color: navy; font-style: normal; font-weight: bold;">public</span> <span style="color: navy; font-style: normal; font-weight: bold;">class</span> <span style="color: black; font-style: normal; font-weight: normal;">Mongo</span>Service {
<span style="color: maroon; font-style: normal; font-weight: normal;">8 </span> <span style="color: navy; font-style: normal; font-weight: bold;">private</span> <span style="color: navy; font-style: normal; font-weight: bold;">final</span> Mongo <span style="color: #660e7a; font-style: normal; font-weight: bold;">mongo</span>;
<span style="color: maroon; font-style: normal; font-weight: normal;">9 </span> <span style="color: navy; font-style: normal; font-weight: bold;">private</span> <span style="color: navy; font-style: normal; font-weight: bold;">final</span> DB <span style="color: #660e7a; font-style: normal; font-weight: bold;">db</span>;
<span style="color: maroon; font-style: normal; font-weight: normal;">10 </span>
<span style="color: maroon; font-style: normal; font-weight: normal;">11 </span> <span style="color: navy; font-style: normal; font-weight: bold;">public</span> <span style="color: black; font-style: normal; font-weight: normal;">Mongo</span>Service(<span style="color: navy; font-style: normal; font-weight: bold;">final</span> String dbName) <span style="color: navy; font-style: normal; font-weight: bold;">throws</span> UnknownHostException {
<span style="color: maroon; font-style: normal; font-weight: normal;">12 </span> <span style="color: #660e7a; font-style: normal; font-weight: bold;">mongo</span> = <span style="color: navy; font-style: normal; font-weight: bold;">new</span> Mongo(); <span style="color: grey; font-style: italic; font-weight: normal;">// </span><span style="color: grey; font-style: italic; font-weight: normal;">Mongo</span><span style="color: grey; font-style: italic; font-weight: normal;">DB server (localhost:27017) </span>
<span style="color: maroon; font-style: normal; font-weight: normal;">13 </span> <span style="color: #660e7a; font-style: normal; font-weight: bold;">db</span> = <span style="color: #660e7a; font-style: normal; font-weight: bold;">mongo</span>.getDB(dbName); <span style="color: grey; font-style: italic; font-weight: normal;">// Connect to database</span>
<span style="color: maroon; font-style: normal; font-weight: normal;">14 </span> }
<span style="color: maroon; font-style: normal; font-weight: normal;">15 </span>
<span style="color: maroon; font-style: normal; font-weight: normal;">16 </span> <span style="color: navy; font-style: normal; font-weight: bold;">public</span> Mongo <span style="color: grey; font-style: normal; font-weight: normal;">get</span><span style="color: grey; font-style: normal; font-weight: normal;">Mongo</span>() {
<span style="color: maroon; font-style: normal; font-weight: normal;">17 </span> <span style="color: navy; font-style: normal; font-weight: bold;">return</span> <span style="color: #660e7a; font-style: normal; font-weight: bold;">mongo</span>;
<span style="color: maroon; font-style: normal; font-weight: normal;">18 </span> }
<span style="color: maroon; font-style: normal; font-weight: normal;">19 </span>
<span style="color: maroon; font-style: normal; font-weight: normal;">20 </span> <span style="color: navy; font-style: normal; font-weight: bold;">public</span> DB getDb() {
<span style="color: maroon; font-style: normal; font-weight: normal;">21 </span> <span style="color: navy; font-style: normal; font-weight: bold;">return</span> <span style="color: #660e7a; font-style: normal; font-weight: bold;">db</span>;
<span style="color: maroon; font-style: normal; font-weight: normal;">22 </span> }
<span style="color: maroon; font-style: normal; font-weight: normal;">23 </span>}
</span></span></span></pre><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><br />
</span></span></span><br />
The <a href="http://api.mongodb.org/java/1.2/com/mongodb/Mongo.html">Mongo</a> class is responsible for the database connection and contains a connection pool. The default pool size has 10 connections per host. You can configure the pool size by using the <span style="font-family: "Courier New",Courier,monospace;">MONGO.POOLSIZE</span> system property or by passing a <a href="http://api.mongodb.org/java/1.2/com/mongodb/MongoOptions.html">MongoOptions</a> parameter to the Mongo constructor.<br />
The <a href="http://api.mongodb.org/java/1.2/com/mongodb/DB.html">DB</a> class represents a logical database on the MongoDB server. We will use a database names "blog" for the blogging application.<br />
<br />
<pre style="border: thin solid; color: black; font-family: monospace; font-style: normal; font-weight: normal; padding: 5px;overflow: scroll;"><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><</span><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">bean</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"> </span><span style="background-color: #efefef; color: blue; font-style: normal; font-weight: bold;">id=</span><span style="background-color: #efefef; color: green; font-style: normal; font-weight: bold;">"</span><span style="background-color: #efefef; color: green; font-style: normal; font-weight: bold;">mongo</span><span style="background-color: #efefef; color: green; font-style: normal; font-weight: bold;">"</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"> </span><span style="background-color: #efefef; color: blue; font-style: normal; font-weight: bold;">class=</span><span style="background-color: #efefef; color: green; font-style: normal; font-weight: bold;">"my.demo.blog.services.MongoService"</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;">></span>
<span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"><</span><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">constructor-arg</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"> </span><span style="background-color: #efefef; color: blue; font-style: normal; font-weight: bold;">index=</span><span style="background-color: #efefef; color: green; font-style: normal; font-weight: bold;">"0"</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"> </span><span style="background-color: #efefef; color: blue; font-style: normal; font-weight: bold;">value=</span><span style="background-color: #efefef; color: green; font-style: normal; font-weight: bold;">"</span><span style="background-color: #efefef; color: green; font-style: normal; font-weight: bold;">blog</span><span style="background-color: #efefef; color: green; font-style: normal; font-weight: bold;">"</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;">/></span>
<span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;"></</span><span style="background-color: #efefef; color: navy; font-style: normal; font-weight: bold;">bean</span><span style="background-color: #efefef; color: black; font-style: normal; font-weight: normal;">></span>
</pre><br />
<b>Entities and Documents</b><br />
<br />
MongoDB stores data in <a href="http://www.mongodb.org/display/DOCS/Collections">collections</a> of <a href="http://www.mongodb.org/display/DOCS/BSON">BSON documents</a>. Documents may contain any number of fields of any length and type. Usually you should store documents of the same structure within collections. MongoDB collections are essentially named groupings of documents.<br />
The Mongo Java driver provides a <a href="http://api.mongodb.org/java/1.2/com/mongodb/DBObject.html">DBObject</a> interface to save custom objects to the database.<br />
The DBOject is very similar to a Map with String keys. You can put/get document element by their String key and get a list of all available keys.<br />
In order to save our entities in MongoDB we will create an adapter which implements the DBObject interface. <br />
<br />
<pre style="border: thin solid; color: black; font-family: monospace; font-style: normal; font-weight: normal; padding: 5px;overflow: scroll;"><span style="color: navy; font-style: normal; font-weight: bold;">public</span> <span style="color: navy; font-style: normal; font-weight: bold;">class</span> DbObjectAdapter <span style="color: navy; font-style: normal; font-weight: bold;">implements</span> DBObject {
<span style="color: navy; font-style: normal; font-weight: bold;">private</span> <span style="color: navy; font-style: normal; font-weight: bold;">final</span> BeanUtilsBean <span style="color: #660e7a; font-style: normal; font-weight: bold;">beanUtils</span>;
<span style="color: navy; font-style: normal; font-weight: bold;">private</span> <span style="color: navy; font-style: normal; font-weight: bold;">final</span> Object <span style="color: #660e7a; font-style: normal; font-weight: bold;">entity</span>;
<span style="color: navy; font-style: normal; font-weight: bold;">private</span> <span style="color: navy; font-style: normal; font-weight: bold;">final</span> Set<String> <span style="color: #660e7a; font-style: normal; font-weight: bold;">keySet</span>;
<span style="color: navy; font-style: normal; font-weight: bold;">public</span> DbObjectAdapter(Object entity) {
<span style="color: navy; font-style: normal; font-weight: bold;">if</span> (entity == <span style="color: navy; font-style: normal; font-weight: bold;">null</span>) {
<span style="color: navy; font-style: normal; font-weight: bold;">throw</span> <span style="color: navy; font-style: normal; font-weight: bold;">new</span> IllegalArgumentException(<span style="color: green; font-style: normal; font-weight: bold;">"Entity must not be null"</span>);
}
<span style="color: navy; font-style: normal; font-weight: bold;">if</span> (!entity.getClass().isAnnotationPresent(<span style="color: olive; font-style: normal; font-weight: normal;">Entity</span>.<span style="color: navy; font-style: normal; font-weight: bold;">class</span>)) {
<span style="color: navy; font-style: normal; font-weight: bold;">throw</span> <span style="color: navy; font-style: normal; font-weight: bold;">new</span> IllegalArgumentException(<span style="color: green; font-style: normal; font-weight: bold;">"Entity class must have annotation javax.persistence.Entity present"</span>);
}
<span style="color: navy; font-style: normal; font-weight: bold;">this</span>.<span style="color: #660e7a; font-style: normal; font-weight: bold;">entity</span> = entity;
<span style="color: navy; font-style: normal; font-weight: bold;">this</span>.<span style="color: #660e7a; font-style: normal; font-weight: bold;">beanUtils</span> = <span style="color: navy; font-style: normal; font-weight: bold;">new</span> BeanUtilsBean();
<span style="color: navy; font-style: normal; font-weight: bold;">this</span>.<span style="color: #660e7a; font-style: normal; font-weight: bold;">keySet</span> = <span style="color: navy; font-style: normal; font-weight: bold;">new</span> HashSet<String>();
initKeySet();
}
<span style="color: olive; font-style: normal; font-weight: normal;">@Override</span>
<span style="color: navy; font-style: normal; font-weight: bold;">public</span> Object put(String name, Object value) {
<span style="color: navy; font-style: normal; font-weight: bold;">try</span> {
<span style="color: #660e7a; font-style: normal; font-weight: bold;">beanUtils</span>.setProperty(<span style="color: #660e7a; font-style: normal; font-weight: bold;">entity</span>, name, value);
} <span style="color: navy; font-style: normal; font-weight: bold;">catch</span> (Exception e) {
<span style="color: navy; font-style: normal; font-weight: bold;">return</span> <span style="color: navy; font-style: normal; font-weight: bold;">null</span>;
}
<span style="color: navy; font-style: normal; font-weight: bold;">return</span> value;
}
<span style="color: olive; font-style: normal; font-weight: normal;">@Override</span>
<span style="color: navy; font-style: normal; font-weight: bold;">public</span> Object get(String name) {
<span style="color: navy; font-style: normal; font-weight: bold;">try</span> {
<span style="color: navy; font-style: normal; font-weight: bold;">return</span> <span style="color: #660e7a; font-style: normal; font-weight: bold;">beanUtils</span>.getProperty(<span style="color: #660e7a; font-style: normal; font-weight: bold;">entity</span>, name);
} <span style="color: navy; font-style: normal; font-weight: bold;">catch</span> (Exception e) {
<span style="color: navy; font-style: normal; font-weight: bold;">return</span> <span style="color: navy; font-style: normal; font-weight: bold;">null</span>;
}
}
</pre><br />
In order to decide which members of the entity we would like to store in MongoDB, we create and new annotation - @MongoElement - and annotate the selected getter methods.<br />
<br />
<pre style="border: thin solid; color: black; font-family: monospace; font-style: normal; font-weight: normal; padding: 5px;overflow: scroll;"><span style="color: olive; font-style: normal; font-weight: normal;"> @MongoElement</span>
<span style="color: navy; font-style: normal; font-weight: bold;">public</span> String getDisplayName() {
<span style="color: navy; font-style: normal; font-weight: bold;">return</span> <span style="color: #660e7a; font-style: normal; font-weight: bold;">displayName</span>;
}
</pre><br />
The DbObjectAdapter creates the document key set by looking for the annotated methods.<br />
<br />
<pre style="border: thin solid; color: black; font-family: monospace; font-style: normal; font-weight: normal; padding: 5px;overflow: scroll;"><span style="color: olive; font-style: normal; font-weight: normal;"> @Override</span>
<span style="color: navy; font-style: normal; font-weight: bold;">public</span> Set<String> keySet() {
<span style="color: navy; font-style: normal; font-weight: bold;">return</span> <span style="color: #660e7a; font-style: normal; font-weight: bold;">keySet</span>;
}
<span style="color: navy; font-style: normal; font-weight: bold;">private</span> <span style="color: navy; font-style: normal; font-weight: bold;">void</span> initKeySet() {
<span style="color: navy; font-style: normal; font-weight: bold;">final</span> PropertyDescriptor[] descriptors = <span style="color: #660e7a; font-style: normal; font-weight: bold;">beanUtils</span>.getPropertyUtils().getPropertyDescriptors(<span style="color: #660e7a; font-style: normal; font-weight: bold;">entity</span>);
<span style="color: navy; font-style: normal; font-weight: bold;">for</span> (PropertyDescriptor <span style="color: black; font-style: normal; font-weight: normal;">desc</span> : descriptors) {
<span style="color: navy; font-style: normal; font-weight: bold;">final</span> Method readMethod = desc.getReadMethod();
<span style="color: olive; font-style: normal; font-weight: normal;">Mongo</span><span style="color: olive; font-style: normal; font-weight: normal;">Element</span> annotation;
<span style="color: navy; font-style: normal; font-weight: bold;">if</span> ((annotation = readMethod.getAnnotation(<span style="color: olive; font-style: normal; font-weight: normal;">MongoElement</span>.<span style="color: navy; font-style: normal; font-weight: bold;">class</span>)) != <span style="color: navy; font-style: normal; font-weight: bold;">null</span>) {
<span style="color: #660e7a; font-style: normal; font-weight: bold;">keySet</span>.add(desc.getName());
}
}
}
</pre><br />
After having the DbObjectAdapter we can create a base DAO class for storing entities in MongoDB<br />
<br />
<pre style="border: thin solid; color: black; font-family: monospace; font-style: normal; font-weight: normal; padding: 5px;overflow: scroll;"><span style="color: navy; font-style: normal; font-weight: bold;">public</span> <span style="color: navy; font-style: normal; font-weight: bold;">abstract</span> <span style="color: navy; font-style: normal; font-weight: bold;">class</span> Base<span style="color: black; font-style: normal; font-weight: normal;">Mongo</span>Dao<S> <span style="color: navy; font-style: normal; font-weight: bold;">implements</span> BaseDao<S> {
<span style="color: navy; font-style: normal; font-weight: bold;">private</span> <span style="color: black; font-style: normal; font-weight: normal;">Mongo</span>Service <span style="background-color: #f6ebbc; color: grey; font-style: normal; font-weight: bold;">mongo</span>;
<span style="color: navy; font-style: normal; font-weight: bold;">private</span> DBCollection <span style="color: #660e7a; font-style: normal; font-weight: bold;">collection</span>;
<span style="color: olive; font-style: normal; font-weight: normal;">@Override</span>
<span style="color: navy; font-style: normal; font-weight: bold;">public</span> S find(Object id) {
<span style="color: navy; font-style: normal; font-weight: bold;">final</span> DBObject dbObject = <span style="color: #660e7a; font-style: normal; font-weight: bold;">collection</span>.findOne(<span style="color: navy; font-style: normal; font-weight: bold;">new</span> ObjectId((String) id));
<span style="color: navy; font-style: normal; font-weight: bold;">final</span> DbObjectAdapter adapter = <span style="color: navy; font-style: normal; font-weight: bold;">new</span> DbObjectAdapter(getEntityClass());
adapter.putAll(dbObject);
<span style="color: navy; font-style: normal; font-weight: bold;">return</span> <span style="background-color: #f6ebbc; color: black; font-style: normal; font-weight: normal;">(S) adapter.getEntity()</span>;
}
<span style="color: olive; font-style: normal; font-weight: normal;">@Override</span>
<span style="color: navy; font-style: normal; font-weight: bold;">public</span> <span style="color: navy; font-style: normal; font-weight: bold;">void</span> save(S entity) {
<span style="color: #660e7a; font-style: normal; font-weight: bold;">collection</span>.save(<span style="color: navy; font-style: normal; font-weight: bold;">new</span> DbObjectAdapter(entity));
}
<span style="color: olive; font-style: normal; font-weight: normal;">@Autowired</span>
<span style="color: navy; font-style: normal; font-weight: bold;">public</span> <span style="color: navy; font-style: normal; font-weight: bold;">void</span> set<span style="color: black; font-style: normal; font-weight: normal;">Mongo</span>(<span style="color: black; font-style: normal; font-weight: normal;">Mongo</span>Service <span style="color: black; font-style: normal; font-weight: normal;">mongo</span>) {
<span style="color: navy; font-style: normal; font-weight: bold;">this</span>.<span style="color: #660e7a; font-style: normal; font-weight: bold;">mongo</span> = mongo;
<span style="color: grey; font-style: italic; font-weight: normal;">// use the entity class name as the collection name</span>
<span style="color: navy; font-style: normal; font-weight: bold;">this</span>.<span style="color: #660e7a; font-style: normal; font-weight: bold;">collection</span> = mongo.getDb().getCollection(getEntityClass().getSimpleName());
}
<span style="color: grey; font-style: italic; font-weight: normal;">/**</span>
<span style="color: grey; font-style: italic; font-weight: normal;"> * </span>
<span style="color: grey; font-style: italic; font-weight: normal;"> * </span><span style="color: grey; font-style: italic; font-weight: bold;">@return</span><span style="color: grey; font-style: italic; font-weight: normal;"> the entity class this DAO handles</span>
<span style="color: grey; font-style: italic; font-weight: normal;"> */</span>
<span style="color: navy; font-style: normal; font-weight: bold;">public</span> <span style="color: navy; font-style: normal; font-weight: bold;">abstract</span> Class getEntityClass();
}
</pre><br />
Notice that there is no need to create the collections, the database creates it automatically on the first insert.<br />
<br />
<b>Next part</b><br />
<br />
So far we've seen how to setup MongoDB and how to store our entities in it.<br />
In the next parts of this series we will discuss the following migration topics:<br />
<ul><li>Identifiers</li>
<li>Relations</li>
<li>Queries</li>
<li>Data migration</li>
</ul>Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com6tag:blogger.com,1999:blog-2299220135518584615.post-34050777073737968052010-02-17T08:03:00.000-08:002011-05-24T08:20:15.242-07:00Why you should look at the exceptions tab when profilingWhen profiling an application I always like to take a look at the Exceptions tab (I use <a href="http://www.yourkit.com/">Yourkit </a>Java profiler). Frequent exceptions may show that something is going wrong and you don't know about it since someone preferred to swallow the exception and hope for the best.<br />
Today, while trying to figure out a performance issue related to Classloader synchronization in Weblogic I noticed that <i>IndexOutOfBoundsException </i>is frequently thrown by the business layer of the application.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4BwMmFcVVnCSSd5I-1yBkZoMmBY2tXC9MXUloSoJEusXj2in1H3JuCqcMnTLOagtTmM08O_j0yqr4BaFRJAJSHIxpm-4nB4pBzW-a7zp6GojYRHmphQO35bpjWzaOrlyzkZGHgAEi8qFF/s1600-h/IndexOutOfBoundException.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="52" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4BwMmFcVVnCSSd5I-1yBkZoMmBY2tXC9MXUloSoJEusXj2in1H3JuCqcMnTLOagtTmM08O_j0yqr4BaFRJAJSHIxpm-4nB4pBzW-a7zp6GojYRHmphQO35bpjWzaOrlyzkZGHgAEi8qFF/s400/IndexOutOfBoundException.png" width="400" /></a> </div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">The code clearly speaks for itself:</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;"> <span style="font-family: "Courier New",Courier,monospace;">public Object getObject1() {</span> </div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> try{</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> return (Object )<wbr></wbr>getObjectList().<wbr></wbr>get(0);</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> }</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> catch(<wbr></wbr>IndexOutOfBoundsException e){</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> return null;</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> }</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> }</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"><br />
</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> public Object getObject2() {</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> try{</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> return (Object )getObjectList().<wbr></wbr>get(1);</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> }</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> catch(<wbr></wbr>IndexOutOfBoundsException e){</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> return null;</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> }</div><div class="MsoNormal" style="font-family: "Courier New",Courier,monospace;"> }</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">* Method and class names where altered </div><div class="separator" style="clear: both; text-align: left;"></div>Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com0tag:blogger.com,1999:blog-2299220135518584615.post-22558141596870023142010-02-07T07:21:00.000-08:002011-05-24T08:20:53.989-07:00JBoss, Java6, InstanceNotFoundException and Yourkit profilerToday I spent a few hours trying to realize why all of a sudden JBoss starts with annoying InstanceNotFoundException messages.<br />
There where two changes done from the previous working configuration:<br />
<ul><li>Switched to Java 6.0 (found out I was using 5.0 by mistake)</li>
<li>A new MBean was added</li>
</ul>The problem did you reoccur when switching back to Java 5.0, but it did not help me much.<br />
Cursing the entire worlds and blaming the guy who wrote the new MBean did not solve the issue so I started checking other things. It turned out that when removing the Yourkit profiler agent from the JBoss start script prevented this issue.<br />
Digging into the <a href="http://www.yourkit.com/docs/80/help/additional_agent_options.jsp">Yourkit startup options</a> I've found out that the profiler light-weight telemetry may clash with some JavaEE application servers MBeans implementation. The Yourkit J2EE integration wizard (which I did not use) adds a startup option which starts the telemetry with a delay - "delay=10000".<br />
Adding the delay option solved my problems !Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com0tag:blogger.com,1999:blog-2299220135518584615.post-71711194857740998382010-02-05T02:15:00.000-08:002011-05-24T08:19:26.113-07:00Beware of Hibernate's read/write cache startegy with memcachedRecently I've been working on improving the performance of an application which involves massive data processing. The application is a JavaEE application using Hibernate for persistence and <a href="http://code.google.com/p/hibernate-memcached/">Memcached</a> as its 2nd level cache. Almost all of the entities are cached to reduce the load on the database.<br />
My immediate goal was improving performance without radically changing the system architecture (I'm well aware of better technologies to use for such an application).<br />
<br />
While profiling the application I noticed that while a bunch of new threads start processing data they get in blocking state one after the other and remain like this for 30-60 seconds.<br />
Looking at the their stacks I immediately saw the their are all blocking on Hibernate's <a href="http://docs.jboss.org/hibernate/stable/core/api/org/hibernate/cache/ReadWriteCache.html">ReadWriteCache</a> put/get methods.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: left;"> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK6YHmp2Qd_93spMFTWlr_fVQkJ3JXyertJKyO6LsiErHuhb50XUfRkOiTwhgVB_-utrYSJnShRSqvP2gbMchkY5vfefXZcnvWRz3XnoSKXTNfh6-WkiIlWTAUWgVAwzrgqS-oznETDC74/s1600-h/profiler.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="331" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK6YHmp2Qd_93spMFTWlr_fVQkJ3JXyertJKyO6LsiErHuhb50XUfRkOiTwhgVB_-utrYSJnShRSqvP2gbMchkY5vfefXZcnvWRz3XnoSKXTNfh6-WkiIlWTAUWgVAwzrgqS-oznETDC74/s640/profiler.jpg" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div>Apparently most of the entities where cached with a <a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-cache-readwrite">read/write strategy</a>.<br />
A read/write cache should prevent two thread from updating the same cache element concurrently or updating and reading concurrently - so it makes sense to see locks. But it turns out Hibernate uses method level synchronization which also prevent two threads for reading the same cache element concurrently.<br />
Now, when using a local cache this issue is probably less noticed, but when using a distributed caching solution such as Memcached, cache access time is longer and so more thread are waiting for each other. <br />
The cache access time is even longer when you ask for an entity which is not in the cache, then you have to wait for the cache to say the entity is not there, get it from the database and put it into the cache. For whole this time the thread keep the monitor preventing other thread from working with the cache.<br />
A better way to handle this, would have been using<b> </b><a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html">java.util.concurrent.locks.ReentrantReadWriteLock</a> which enables more fine grained locking (read lock for the get method and write lock for the put method).<br />
<br />
Another issue is cache regions. Hibernate creates a ReadWriteCache instance per region, if not regions are defined than only a single instance of ReadWriteCache is used which makes the synchronization even a bigger problem.<br />
<br />
The solution for this issue was switching to a nonstrict <a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-cache-nonstrict">read/write strategy</a> wherever possible and creating a cache region per entity. This reduced the locking effect dramatically.Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com3tag:blogger.com,1999:blog-2299220135518584615.post-6902051065795707142010-01-17T05:47:00.001-08:002011-05-24T08:18:44.105-07:00Fantom on the JVM Devoxx09 BOFDevoxx09 Fantom BOF: <div style="width:425px;text-align:left" id="__ss_2617711"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/drorbr/fantom-on-the-jvm-devoxx09-bof" title="Fantom on the JVM Devoxx09 BOF">Fantom on the JVM Devoxx09 BOF</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=fanonthejvm-091130154923-phpapp02&stripped_title=fantom-on-the-jvm-devoxx09-bof" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=fanonthejvm-091130154923-phpapp02&stripped_title=fantom-on-the-jvm-devoxx09-bof" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/drorbr">Dror Bereznitsky</a>.</div></div>Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com0tag:blogger.com,1999:blog-2299220135518584615.post-29855043692171878632010-01-17T05:46:00.001-08:002010-02-02T13:22:03.257-08:00The Actor Model - Towards Better ConcurrencyJavaEdge 2009 presentation: <div style="width:425px;text-align:left" id="__ss_2932312"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/drorbr/the-actor-model-towards-better-concurrency" title="The Actor Model - Towards Better Concurrency">The Actor Model - Towards Better Concurrency</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=theactormodel-towardsbetterconcurrency-100117032144-phpapp01&stripped_title=the-actor-model-towards-better-concurrency" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=theactormodel-towardsbetterconcurrency-100117032144-phpapp01&stripped_title=the-actor-model-towards-better-concurrency" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/drorbr">Dror Bereznitsky</a>.</div></div>Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com0tag:blogger.com,1999:blog-2299220135518584615.post-76792453269630409232009-04-06T00:48:00.000-07:002010-02-02T13:21:37.194-08:00IntelliJ plugin for Fan programming languageFor the past couple of months I've been working, together with <a href="http://freddy33.blogspot.com/">Fred Simon</a>, on an IntelliJ <a href="http://wiki.jfrog.org/confluence/display/FANP/Home">plugin</a> for the <a href="http://www.fandev.org/">Fan programming language</a>.<br /><br />Fan is a general purpose object-oriented programming language designed from the ground up to support functions as first class objects. Fan applications can seamlessly run on both the Java VM and the .NET CLR.<br />Fan offers goodies such as: static and dynamic typing, built-in 'JSON like' serialization, Actor concurrency, built-in immutability, modularity, closures, mixins and more.<br />The thing I found most appealing in Fan is that it is designed as a practical programming language and not as an academic language to explore bleeding edge theories.<br />If you like to know more about Fan you should probably start <a href="http://www.fandev.org/doc/docIntro/StartHere.html">here</a>.<br /><br />Yesterday, we released <a href="http://wiki.jfrog.org/confluence/display/FANP/Release+Notes+-+Fan+Idea+Plugin+-+Version+0.0.2">version 0.0.2</a> of the plugin. Although it is still a pre-alpha version it already have a good amount of functionality including: syntax highlighting, structure view, hierarchical view, synchronization between module build script (build.fan) and IntelliJ module and more. For more info about the plugin take a look <a href="http://wiki.jfrog.org/confluence/display/FANP/Home">here</a>.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDXijz9mX0_-PuvzzDufy1cPukRi814b_BmWKXCHXfLQpPVgYosy6hdxnAR3hAohLq7aSbwliSWDsTwJsy-yXWxdqYSqbx4CvYUsozC8oEI8bdGhizpErntApdcQNeE037jRRKYNAINqaQ/s1600-h/plugin-screenshot.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 250px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDXijz9mX0_-PuvzzDufy1cPukRi814b_BmWKXCHXfLQpPVgYosy6hdxnAR3hAohLq7aSbwliSWDsTwJsy-yXWxdqYSqbx4CvYUsozC8oEI8bdGhizpErntApdcQNeE037jRRKYNAINqaQ/s320/plugin-screenshot.jpg" alt="" id="BLOGGER_PHOTO_ID_5321498231694292642" border="0" /></a>Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com4tag:blogger.com,1999:blog-2299220135518584615.post-71338391298920890162008-12-26T06:00:00.001-08:002010-02-02T13:22:36.510-08:00So You Want To Write Your Own BenchmarkMy JavaEdge 2008 presentation is now available on slideshare.net<div style="width: 425px; text-align: left;" id="__ss_870900"><a style="margin: 12px 0pt 3px; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; display: block; text-decoration: underline;" href="http://www.slideshare.net/drorbr/so-you-want-to-write-your-own-benchmark-presentation?type=powerpoint" title="So You Want To Write Your Own Benchmark">So You Want To Write Your Own Benchmark</a><object style="margin: 0px;" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=so-you-want-to-write-your-own-benchmark-1230151287556351-2&stripped_title=so-you-want-to-write-your-own-benchmark-presentation"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=so-you-want-to-write-your-own-benchmark-1230151287556351-2&stripped_title=so-you-want-to-write-your-own-benchmark-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View SlideShare <a style="text-decoration: underline;" href="http://www.slideshare.net/drorbr/so-you-want-to-write-your-own-benchmark-presentation?type=powerpoint" title="View So You Want To Write Your Own Benchmark on SlideShare">presentation</a> or <a style="text-decoration: underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own. (tags: <a style="text-decoration: underline;" href="http://slideshare.net/tag/microbenchmarking">microbenchmarking</a> <a style="text-decoration: underline;" href="http://slideshare.net/tag/benchmarking">benchmarking</a>)</div></div>Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com1tag:blogger.com,1999:blog-2299220135518584615.post-52355870561774537572008-12-20T03:29:00.000-08:002010-02-02T13:22:42.930-08:00JavaEdge 2008<div align="center"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM3Uw0OTT2C35I_XjnxxHPeqKOlLIXJdV4HUDVU586ethDfFY95aPA_MtY6rBQrHC82OJrW5er5eQU6-FvCyxrDFWDTO0MQTqVfo2otcZNnoEuatZF-IYNnglPvIVwiCe2raUjsBSc7dK_/s1600-h/javaedge-banner.jpg"><img style="margin: 0pt 10px 10px 0pt; float: none; cursor: pointer; width: 367px; height: 97px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM3Uw0OTT2C35I_XjnxxHPeqKOlLIXJdV4HUDVU586ethDfFY95aPA_MtY6rBQrHC82OJrW5er5eQU6-FvCyxrDFWDTO0MQTqVfo2otcZNnoEuatZF-IYNnglPvIVwiCe2raUjsBSc7dK_/s320/javaedge-banner.jpg" alt="" id="BLOGGER_PHOTO_ID_5282217350761746722" border="0" /></a><br /></div>Last Thursday (18.12.2008) 6 months of hard work resulted wit the <a href="http://www.javaedge.net/">JavaEdge 2008</a> event which took place in Israel. JavaEdge is a yearly Java seminar conducted by <a href="http://www.alphacsp.com/">AlphaCSP</a>, which I proudly work for. This year we had more than 500 participants, 2 assembly speeches by <a href="http://www.jroller.com/scolebourne/">Stephen Colebourne</a> (keynote) and <a href="http://freddy33.blogspot.com/">Frederic Simon</a>, 3 tracks with 5 <a href="http://www.javaedge.net/sessions.html">sessions</a> each. Sessions where presented by AlphaCSP workers and guests including <a href="http://blog.arendsen.net/">Alef Arendsen</a> from SpringSource and Dmitry Jemerov from JetBrains. Sessions covered topics such as OSGi, Android, JavaFX, Java for the cloud, Comet, DSLs and more.<br /><br />During his keynote speech, Stephen presented 10 possible language changes for JDK7, and asked the audience to vote on them. More than 300 people cast their votes. The detailed results are presented in <a href="http://www.jroller.com/scolebourne/entry/jdk_7_language_changes_javaedge">Stephen's blog</a>.Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com0tag:blogger.com,1999:blog-2299220135518584615.post-47188130565273764582008-11-27T11:48:00.000-08:002011-05-24T08:17:39.474-07:00"java.lang.OutOfMemoryError: PermGen space" with a twistThere are a lot of posts out there about the "java.lang.OutOfMemoryError: PermGen space" exception. A <a href="http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java">good description</a> of the problem can be found in Frank Kieviet's blog.<br />One of the main causes for this error is a classloader not being garbage collected when you undeploy an application. A few days ago I encountered this problem but with a certain twist causing it to become even worse.<br /><div style="text-align: left;"><br />It all started with JBoss servers suffering from PermGen bloat which lead eventually to a "java.lang.OutOfMemoryError: PermGen space" exception.<br />Analyzing a heap dump from one of the servers using <a href="http://java.sun.com/javase/6/docs/technotes/tools/share/jhat.html">jhat</a> we saw a long list of about 2000 $Proxy classes which where the immediate suspects for the situation<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp62B6tno3NRCQ6zXioflx6bp68yvzYDxpygBdJkyRTFoq61lTSj0rT8z9ZxlY-OwKk_UKxr-Fod2IyRLRxGEWTaZ1R4eyiNjDpb_EEidqOqkq_VTBAHKCadjWvAbkwsCQoFjoxYHVvU3U/s1600-h/ProxyClasses.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 247px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp62B6tno3NRCQ6zXioflx6bp68yvzYDxpygBdJkyRTFoq61lTSj0rT8z9ZxlY-OwKk_UKxr-Fod2IyRLRxGEWTaZ1R4eyiNjDpb_EEidqOqkq_VTBAHKCadjWvAbkwsCQoFjoxYHVvU3U/s320/ProxyClasses.png" alt="" id="BLOGGER_PHOTO_ID_5274770961731206402" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />After some checking some of these proxies we could determine two things:<br /><ol><li>They have no instances</li><li>They are loaded by instances of JBoss RemotingClassLoader</li></ol><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0lyQoQpbkI_CQS3TvljcEcZLCX8nxpJAfEpYzFWZSZ11WVEMfHUXK0jT230DGdNGvgyPSVUTss6TADvJqLybD9bL_7Gs2v32efdr7LSgyWC7pjMHa5ZhoENEg9gkNrWJqIKgOg7vbrSxT/s1600-h/Proxy1208.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 173px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0lyQoQpbkI_CQS3TvljcEcZLCX8nxpJAfEpYzFWZSZ11WVEMfHUXK0jT230DGdNGvgyPSVUTss6TADvJqLybD9bL_7Gs2v32efdr7LSgyWC7pjMHa5ZhoENEg9gkNrWJqIKgOg7vbrSxT/s320/Proxy1208.png" alt="" id="BLOGGER_PHOTO_ID_5274771247842167538" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />Some more digging showed that there are 819 instances of the JBoss RemotingClassLoader all of them loading only $Proxy classes. This seemed to be a little odd so we used <a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jmap.html">jmap</a> with the "-permstat" option to look at the current status of one of the servers and what we got was a long list of JBoss RemotingClassLoaders - <span style="font-weight: bold;">they where all dead</span> <span style="font-weight: bold;">!</span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik9bNq5geUsBI6auDDX5PyMRY2xD4g8z0-4ZwpyuNej0IiMS2X9vtduMxSbJoVwWO0VnUFMjVic1m2Rz-9OMHiVlplKAOIR_O3O-zrN4BLAGQJ_qCPiwUoTxe-PW4-j2-NPCfg3kF3nEcM/s1600-h/jmap.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 182px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik9bNq5geUsBI6auDDX5PyMRY2xD4g8z0-4ZwpyuNej0IiMS2X9vtduMxSbJoVwWO0VnUFMjVic1m2Rz-9OMHiVlplKAOIR_O3O-zrN4BLAGQJ_qCPiwUoTxe-PW4-j2-NPCfg3kF3nEcM/s320/jmap.png" alt="" id="BLOGGER_PHOTO_ID_5274771713680880834" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />OK, we have a list of dead classloaders loading proxy classes this is definitely the cause for the leak, but why?<br />Back to jhat we checked the reference chains to one of the proxies. The result showed a suspect that may be causing the leak: a static field named "classesToGetAndSetters" in Wicket's PropertyResolver class.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpSG8gSCAqz-36Q_fQVYiXcVbbZsPZZRsclnD0qXoK3uX__1yTH_XGGfM1qUE5iA9223mGb7DquO83Vi3IeOM2xM2c0mYJEwdLaTfgdHmqiKNPfCNR9ErQ6LQw0baJ_s53W84-8x_yHVTF/s1600-h/RootsetReferencesToClassProxy1208.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 174px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpSG8gSCAqz-36Q_fQVYiXcVbbZsPZZRsclnD0qXoK3uX__1yTH_XGGfM1qUE5iA9223mGb7DquO83Vi3IeOM2xM2c0mYJEwdLaTfgdHmqiKNPfCNR9ErQ6LQw0baJ_s53W84-8x_yHVTF/s320/RootsetReferencesToClassProxy1208.png" alt="" id="BLOGGER_PHOTO_ID_5274771893381473138" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />A quick pick into the Wicket source code discovered that classesToGetAndSetters is a map caching getters and setters. The problem is that Class objects are used as keys and that this is an unbounded cache with no eviction policy. Now, as long as you put "regular" (non Proxy) classes into this cache you will only encounter the usual classloader leak problem when unloading the application. This was already taken care by wicket, but we have a different problem.<br />In our case for each Proxy instance there is also a new $Proxy class filling up this cache. To add more complexity all these proxies where retrieved using JBoss remoting. A new RemotingClassLoader was created each time but never released since the cached $Proxy class is still referencing it.<br />The solution for such an issue is using a bound cache with some sort of eviction policy or something like google-collections ReferenceMap.<br /><br /><br /><br /><br /><br /></div>Dror Bereznitskyhttp://www.blogger.com/profile/13989642290911883201noreply@blogger.com6