Posts Tagged ‘Java’
Why I Love Spring 2.5′s PropertyPlaceholderConfigurer
I have been a big fan of Spring’s PropertyPlaceholderConfigurer since 2006 when I could wire up a datasource bean, or any bean for that matter, with just some references to properties that I knew were going to be in place. A snippet from a Spring context file for example:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${my.db.driver}"/>
<property name="url" value="${my.db.url}"/>
<property name="username" value="${my.db.username}"/>
<property name="password" value="${my.db.password}"/>
</bean>
Now, I can provide PropertyPlaceholderConfigurer with a .properties file location(s) or I could depend on the properties existing as part of the runtime, like when using JBoss Application Server’s property service. Then one day, I ran into a bit of an issue. Well, now I have an application with a properties file that has datasource connection information for each development region, DEV, TEST and PROD and the region is a ‘prefix’ on each property.
Something like…
DEV.my.db.driver DEV.my.db.url DEV.my.db.username DEV.my.db.password TEST.my.db.driver TEST.my.db.url TEST.my.db.username TEST.my.db.password
… and so on. If you are packaging .properties files into your archive(.war, .jar, .ear), this does help your code be a bit more portable but I usually configure properties outside of an archive but we can’t always have our way. So, now we have a special class that reads the properties file and the region variable from SystemProperties as the region variable, SDLC_REGION, is set in each development region as a VM argument.
-DSDLC_REGION=DEV
And that works great. We can leave our Spring context alone and everything works like we need it to. But, I am always trying to reduce classes or utilities(.jar files) that are no longer needed in our applications. So, I took a look back into Spring 2.5′s PropertyPlaceholderConfigurer and low and behold, there is a better way to do things. Check it out. Here is my Spring context file now:
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${${SDLC_REGION}.my.db.driver}"/>
<property name="url" value="${${SDLC_REGION}.my.db.url}"/>
<property name="username" value="${${SDLC_REGION}.my.db.username}"/>
<property name="password" value="${${SDLC_REGION}.my.db.password}"/>
</bean>
Now, the VM argument, SDLC_REGION, exists in each environment and it can be a part of our PropertyPlaceholderConfigurer expression. We can now load the correct property for each development region from the packaged .properties file without depending on our utility class anymore. Really cool stuff and again, beautiful work from the people at SpringSource.
Java Is Dead
As we all have heard around the water cooler, Java is dead. Why is Java dead, I still have a job? Is it the language itself? Is it the Java Community Process (JCP)? Is it because Sun is no more? Is it the fragmentation of Java (IBM, Oracle, JBoss, Spring)? Is it because someone you follow posted it on Twitter? Is Java too complex? Is it the abundance of Java frameworks and tools? Is it the expensive conferences? Is it the books that are outdated before they are published? Is it because you are holding a hammer? Is it because the Oracle/Google patent lawsuit? It is because your IDE is still loading? Is it because your server is still down? Is it because I have a Rod Johnson bobble-head? It is because someone posted it to your local JUG mailing list? Is it because
public static void main(String[] args) {}
is just too much typing to actually start to get something done?
Has a language come along to take its place?
Groovy, C#, Ruby, PHP, Clojure, F#, Python, C++, R, Flex, VB.NET, Haskell, ActionScript, JavaScript, JavaFX, JRuby, Jython, etc. (Sorry if I left one of your favorites out.)
(inspired by real events on the Tampa JUG mailing list)
Intro to Hazelcast’s Distributed Query
When you decide to incorporate a distributed data grid as part of your application architecture, a product’s scalability, reliability, cost and performance are key considerations that will help you make your decision. Another key consideration will be the accessibility of the data. One nice feature of Hazelcast that I have been working with lately is distributed queries. In simple terms, distributed queries provide an API and syntax that allow a developer to query for entries that exist in a Hazelcast distributed map. Let’s look at a very simple example.
In the demo project (link at the bottom) I have one object, a test case and the Hazelcast 1.8.4 jar file as a project dependency. Below is the class that will be put into a distributed map, ReportData. Once we have a distributed map that is full of ReportData entries, we can use Hazelcast’s distributed query to find our ReportData entries.
package org.axiomaticit.model;
public class ReportData implements Serializable {
private static final long serialVersionUID = 2789198967473633902L;
private Long id;
private Boolean active;
private String reportName;
private String value;
private Date startDate;
private Date endDate;
public ReportData(Long id, Boolean active, String reportName, String value, Date startDate, Date endDate) {
this.id = id;
this.active = active;
this.reportName = reportName;
this.value = value;
this.startDate = startDate;
this.endDate = endDate;
}
// all the getters and setters
}
Nothing too complex in the code above. It is just an object that implements Serializable and that contains a few different types (String, Boolean and Date) of attributes. This class will work nicely to help demonstrate Hazelcast’s distributed query API and syntax. I omitted the getters and setters for brevity.
// get a "ReportData" distributed map
Map<Long, ReportData> reportDataMap = Hazelcast.getMap("ReportData");
// create a ReportData object
ReportData reportData = new ReportData(...);
// put it into our Hazelcast Distributed Map
reportDataMap.put(reportData.getId(), reportData);
In the test code, I created ~50,000 ReportData objects using a for loop and put them into the “ReportData” distributed map. I used the index, 0..50,000, for the ReportData’s id and the reportName is set to “Report ” + index. I did a few other things, so we could have a few different dates represented in our map’s entries. Check out the demo project for more detail.
Set<ReportData> reportDataSet = (Set<ReportData>) map.values(new SqlPredicate("active AND id > 990 AND reportName = 'Report 995'"));
The above code queries the distributed map for all ReportData objects where active is equal to true, the id is greater than 990 and the reportName is equal to “Report 995″.
Below the reportDataSet will contain all ReportData where active is equal to true and id is greater than 49985.
Set<ReportData> reportDataSet = (Set<ReportData>) map.values(new SqlPredicate("active AND id > 49985"));
Below, we have a case where we are building the predicate programmatically using the EntryObject to fetch all ReportData where the id is greater than 49900 and the endDate attribute of ReportData is between two dates, startDate and endDate. I included the code below to show how I am creating a few dates to use in the predicate that eventually gets passed into the map.values(predicate) method.
Calendar calendar1 = Calendar.getInstance();
calendar1.set(2010, 3, 1);
Calendar calendar2 = Calendar.getInstance();
calendar2.set(2010, 3, 31);
Date startDate = new Date(calendar1.getTimeInMillis());
Date endDate = new Date(calendar2.getTimeInMillis());
EntryObject e = new PredicateBuilder().getEntryObject();
Predicate predicate = e.get("id").greaterThan(new Long(49900)).and(e.get("endDate").between(startDate, endDate));
Set<ReportData> reportDataSet = (Set<ReportData>) map.values(predicate);
Getting data from your Hazelcast distributed map using the distributed query API and query syntax is pretty straight forward. Most of these queries ran for about 500 milliseconds to 2 seconds in my IDE. The power and performance comes from the ability to query objects or map entries that are in memory rather than always relying on a round trip to your RDBMS. Distributed queries are an important feature that make Hazelcast a great tool that can help offset the workload of your RDBMS. With Hazelcast and a good knowledge of your enterprise data, you can implement a simple and effective solution that will easily scale to as many Hazelcast nodes your hardware can support. The demo project can be downloaded here. For more information, check out Hazelcast’s website or visit the project’s home at Google Code.
Groovy Metaprogramming: propertyMissing
The other day, while working on a Java project, I realized that I could implement an application requirement quite quickly by extending a current domain object and adding an attribute. This is an enterprise wide, industry standard domain object model so I couldn’t just add the attribute to the domain object without cutting through some red tape. Plus, it was an attribute that I needed for my application and it would most likely have no use in other projects. So, I had something like this:
public class Policy {
private String policyNumber;
private Double value;
private Double interestRate;
/* getters and setters */
....
}
Then to get things done, I went ahead and created:
public class MyPolicy extends Policy {
private String myNewProperty;
private Policy p;
public MyPolicy(Policy policy) {
this.p = policy;
}
/* getters and setters */
....
}
Now, I could fulfill the requirement with ease because I now had a Policy object with the extra attribute I needed, myNewProperty, all in the MyPolicy object. I could now handle the Policy returned from the Web service call and pass it into the MyPolicy constructor, do some work to create an instance of MyPolicy with a Policy object, derive the value of myNewProperty and then send it on to a view for example. Nice, I think that will work for my application.
Later, I thought about how nice it would have been if the Policy object was implemented with Groovy. Then I could take advantage of Groovy’s metaprogramming features like propertyMissing. When I have propertyMissing in my languageĀ arsenal, I can create the Policy object like so:
class Policy {
def properties = Collections.synchronizedMap([:])
String policyNumber
Double value
Double interestRate
def propertyMissing(String name, value) { properties[name] = value }
def propertyMissing(String name) { properties[name] }
}
In the implementation above, the propertyMissing(String name, value) method is called when trying to set a value, myNewProperty, that doesn’t exist in the Policy object. The propertyMissing(String name) method is called when trying to get a property, myNewProperty, that doesn’t exist in the Policy object. By default, the propertyMissing(String name) will return null if the value was never initialized or never dynamically created. Yeah, it is an incredible feature. What is really nice is that I didn’t have to create the MyPolicy object at all! In the Groovy world I could write the following:
def p = new Policy() p.policyNumber = "12345678" p.value = 12000.00 p.interestRate = 2.3 println p.policyNumber println p.value println p.interestRate /* new property */ p.myNewProperty = "Active" println p.myNewProperty
Later on I could even write:
/* another new property */ p.myOtherNewProperty = "Wow" println p.myOtherNewProperty
This would save me some time and now because the Policy object is expandable, other applications that need to extend the Policy object, for application purposes, will be able to utilize these features. I am convinced, Groovy IS productivity for Java.