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 Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Java Topics

article thumbnail
Allowing Duplicate Keys in Java Collections
Java Collections allows you to add one or more elements with the same key by using the MultiValueMap class, found in the Apache org.apache.commons.collections package (http://commons.apache.org/collections/): package multihashmap.example; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.collections.map.MultiValueMap; public class MultiHashMapExample { public static void main(String[] args) { List list; MultiValueMap map = new MultiValueMap(); map.put("A", 4); map.put("A", 6); map.put("B", 7); map.put("C", 1); map.put("B", 9); map.put("A", 5); Set entrySet = map.entrySet(); Iterator it = entrySet.iterator(); System.out.println(" Object key Object value"); while (it.hasNext()) { Map.Entry mapEntry = (Map.Entry) it.next(); list = (List) map.get(mapEntry.getKey()); for (int j = 0; j < list.size(); j++) { System.out.println("\t" + mapEntry.getKey() + "\t " + list.get(j)); } } } } Since Java Core does’t come with some solutions for supporting multiple keys, using the org.apache.commons.collections seems to be a proper way to deal with multiple keys. And the output is: From http://e-blog-java.blogspot.com/2012/02/how-to-allow-duplicate-key-in-java.html
March 3, 2012
by A. Programmer
· 100,425 Views · 5 Likes
article thumbnail
Creating a build pipeline using Maven, Jenkins, Subversion and Nexus.
for a while now, we had been operating in the wild west when it comes to building our applications and deploying to production. builds were typically done straight from the developer’s ide and manually deployed to one of our app servers. we had a manual process in place, where the developer would do the following steps. check all project code into subversion and tag build the application. archive the application binary to a network drive deploy to production update our deployment wiki with the date and version number of the app that was just deployed. the problem is that there were occasionally times where one of these steps were missed, and it always seemed to be at a time when we needed to either rollback to the previous version, or branch from the tag to do a bugfix. sometimes the previous version had not been archived to the network, or the developer forgot to tag svn. we were already using jenkins to perform automated builds, so we wanted to look at extending it further to perform release builds. the maven release plug-in provides a good starting point for creating an automated release process. we have also just started using the nexus maven repository and wanted to incorporate that as well to archive our binaries to, rather than archiving them to a network drive. the first step is to set up the project’s pom file with the deploy plugin as well as include configuration information about our nexus and subversion repositories. org.apache.maven.plugins maven-release-plugin 2.2.2 http://mks:8080/svn/jrepo/tags/frameworks/siestaframework the release plugin configuration is pretty straightforward. the configuration takes the subversion url of the location where the tags will reside for this project. the next step is to configure the svn location where the code will be checked out from. scm:svn:http://mks:8080/svn/jrepo/trunk/frameworks/siestaframework http://mks:8080/svn the last step in configuring the project is to set up the location where the binaries will be archived to. in our case, the nexus repository. lynden-java-release lynden release repository http://cisunwk:8081/nexus/content/repositories/lynden-java-release the project is now ready to use the maven release plug-in. the release plugin provides a number of useful goals. release:clean – cleans the workspace in the event the last release process was not successful. release: prepare – performs a number of operations checks to make sure that there are no uncommitted changes. ensures that there are no snapshot dependencies in the pom file, changes the version of the application and removes snapshot from the version. ie 1.0.3-snapshot becomes 1.0.3 run project tests against modified poms commit the modified pom tag the code in subersion increment the version number and append snapshot. ie 1.0.3 becomes 1.0.4-snapshot commit modified pom release: perform – performs the release process checks out the code using the previously defined tag runs the deploy maven goal to move the resulting binary to the repository. putting it all together the last step in this process is to configure jenkins to allow release builds on-demand, meaning we want the user to have to explicitly kick off a release build for this process to take place. we have download and installed the release jenkins plug-in in order to allow developers to kick off release builds from jenkins. the release plug-in will execute tasks after the normal build has finished. below is a screenshot of the configuration of one of our projects. the release build option for the project is enabled by selecting the “configure release build” option in the “build environment” section. the maven release plug-in is activated by adding the goals to the “after successful release build” section. (the –b option enables batch mode so that the release plug-in will not ask the user for input, but use defaults instead.) once the release option has been configured for a project there will be a “release” icon on the left navigation menu for the project. selecting this will kick off a build and then the maven release process, assuming the build succeeds. finally a look at svn and nexus verifies that the build for version 1.0.4 of the siesta-framework project has been tagged in svn and uploaded to nexus. the next steps for this project will be to generate release notes for release builds, and also to automate a deployment pipeline, so that developers can deploy to our test, staging and production servers via jenkins rather than manually from their development workstations. twitter: @robterp blog: http://rterp.wordpress.com
February 29, 2012
by Rob Terpilowski
· 86,957 Views
article thumbnail
High Performance Libraries in Java
There is an increasing number of libraries which are described as high performance and have benchmarks to back that claim up. Here is a selection that I am aware of.
February 13, 2012
by Peter Lawrey
· 37,652 Views · 1 Like
article thumbnail
JavaFX NumberTextField and Spinner Control
I recently spent some time learning JavaFX and doing a custom control is a good practice to dive a little bit deeper into the concepts of a new gui library. Having some background in financial software I did of course miss the equivalent of a JFormattedTextField and a JSpinner control in the current 2.0 release. So going down that road seemed like a good choice to me. And here are my controls: a NumberTextField, that can be configured with an arbitrary NumberFormat a Spinner field that also can also be configured with an arbitrary NumberFormat and controlled with the arrow keys or arrow buttons, that are part of the control The controls and an example can be downloaded as a netbeans project.The example also includes a css file that styles the spinner with either straight or rounded corners. NumberTextField The NumberTextField was pretty easy and I wouldn't even consider this a custom control as I only changed the behaviour of an already existing control. It extends a normal TextField, adds a NumberProperty that serves as the model and holds a BigDecimal (for financial applications we need exact types) and does some formatting and parsing.That's it, no big deal. package de.thomasbolz.javafx; import java.math.BigDecimal; import java.text.NumberFormat; import java.text.ParseException; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.control.TextField; /** * Textfield implementation that accepts formatted number and stores them in a * BigDecimal property The user input is formatted when the focus is lost or the * user hits RETURN. * * @author Thomas Bolz */ public class NumberTextField extends TextField { private final NumberFormat nf; private ObjectProperty number = new SimpleObjectProperty<>(); public final BigDecimal getNumber() { return number.get(); } public final void setNumber(BigDecimal value) { number.set(value); } public ObjectProperty numberProperty() { return number; } public NumberTextField() { this(BigDecimal.ZERO); } public NumberTextField(BigDecimal value) { this(value, NumberFormat.getInstance()); initHandlers(); } public NumberTextField(BigDecimal value, NumberFormat nf) { super(); this.nf = nf; initHandlers(); setNumber(value); } private void initHandlers() { // try to parse when focus is lost or RETURN is hit setOnAction(new EventHandler() { @Override public void handle(ActionEvent arg0) { parseAndFormatInput(); } }); focusedProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) { if (!newValue.booleanValue()) { parseAndFormatInput(); } } }); // Set text in field if BigDecimal property is changed from outside. numberProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue obserable, BigDecimal oldValue, BigDecimal newValue) { setText(nf.format(newValue)); } }); } /** * Tries to parse the user input to a number according to the provided * NumberFormat */ private void parseAndFormatInput() { try { String input = getText(); if (input == null || input.length() == 0) { return; } Number parsedNumber = nf.parse(input); BigDecimal newValue = new BigDecimal(parsedNumber.toString()); setNumber(newValue); selectAll(); } catch (ParseException ex) { // If parsing fails keep old number setText(nf.format(number.get())); } } } NumberSpinner The NumberSpinner is only slightly more complicated. It builds upon the NumberTextField and adds an increment and decrement button, that increments and decrements the value in the field by a stepwidth. Initial value, stepwidth and underlying NumberFormat are set in the constructor. The textfield and the size of the buttons are scaled according to the font size that can be - for example - set in the .css file. package de.thomasbolz.javafx; import java.math.BigDecimal; import java.text.NumberFormat; import javafx.beans.binding.NumberBinding; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.scene.shape.LineTo; import javafx.scene.shape.MoveTo; import javafx.scene.shape.Path; import javax.swing.JSpinner; /** * JavaFX Control that behaves like a {@link JSpinner} known in Swing. The * number in the textfield can be incremented or decremented by a configurable * stepWidth using the arrow buttons in the control or the up and down arrow * keys. * * @author Thomas Bolz */ public class NumberSpinner extends HBox { public static final String ARROW = "NumberSpinnerArrow"; public static final String NUMBER_FIELD = "NumberField"; public static final String NUMBER_SPINNER = "NumberSpinner"; public static final String SPINNER_BUTTON_UP = "SpinnerButtonUp"; public static final String SPINNER_BUTTON_DOWN = "SpinnerButtonDown"; private final String BUTTONS_BOX = "ButtonsBox"; private NumberTextField numberField; private ObjectProperty stepWitdhProperty = new SimpleObjectProperty<>(); private final double ARROW_SIZE = 4; private final Button incrementButton; private final Button decrementButton; private final NumberBinding buttonHeight; private final NumberBinding spacing; public NumberSpinner() { this(BigDecimal.ZERO, BigDecimal.ONE); } public NumberSpinner(BigDecimal value, BigDecimal stepWidth) { this(value, stepWidth, NumberFormat.getInstance()); } public NumberSpinner(BigDecimal value, BigDecimal stepWidth, NumberFormat nf) { super(); this.setId(NUMBER_SPINNER); this.stepWitdhProperty.set(stepWidth); // TextField numberField = new NumberTextField(value, nf); numberField.setId(NUMBER_FIELD); // Enable arrow keys for dec/inc numberField.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler() { @Override public void handle(KeyEvent keyEvent) { if (keyEvent.getCode() == KeyCode.DOWN) { decrement(); keyEvent.consume(); } if (keyEvent.getCode() == KeyCode.UP) { increment(); keyEvent.consume(); } } }); // Painting the up and down arrows Path arrowUp = new Path(); arrowUp.setId(ARROW); arrowUp.getElements().addAll(new MoveTo(-ARROW_SIZE, 0), new LineTo(ARROW_SIZE, 0), new LineTo(0, -ARROW_SIZE), new LineTo(-ARROW_SIZE, 0)); // mouse clicks should be forwarded to the underlying button arrowUp.setMouseTransparent(true); Path arrowDown = new Path(); arrowDown.setId(ARROW); arrowDown.getElements().addAll(new MoveTo(-ARROW_SIZE, 0), new LineTo(ARROW_SIZE, 0), new LineTo(0, ARROW_SIZE), new LineTo(-ARROW_SIZE, 0)); arrowDown.setMouseTransparent(true); // the spinner buttons scale with the textfield size // TODO: the following approach leads to the desired result, but it is // not fully understood why and obviously it is not quite elegant buttonHeight = numberField.heightProperty().subtract(3).divide(2); // give unused space in the buttons VBox to the incrementBUtton spacing = numberField.heightProperty().subtract(2).subtract(buttonHeight.multiply(2)); // inc/dec buttons VBox buttons = new VBox(); buttons.setId(BUTTONS_BOX); incrementButton = new Button(); incrementButton.setId(SPINNER_BUTTON_UP); incrementButton.prefWidthProperty().bind(numberField.heightProperty()); incrementButton.minWidthProperty().bind(numberField.heightProperty()); incrementButton.maxHeightProperty().bind(buttonHeight.add(spacing)); incrementButton.prefHeightProperty().bind(buttonHeight.add(spacing)); incrementButton.minHeightProperty().bind(buttonHeight.add(spacing)); incrementButton.setFocusTraversable(false); incrementButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent ae) { increment(); ae.consume(); } }); // Paint arrow path on button using a StackPane StackPane incPane = new StackPane(); incPane.getChildren().addAll(incrementButton, arrowUp); incPane.setAlignment(Pos.CENTER); decrementButton = new Button(); decrementButton.setId(SPINNER_BUTTON_DOWN); decrementButton.prefWidthProperty().bind(numberField.heightProperty()); decrementButton.minWidthProperty().bind(numberField.heightProperty()); decrementButton.maxHeightProperty().bind(buttonHeight); decrementButton.prefHeightProperty().bind(buttonHeight); decrementButton.minHeightProperty().bind(buttonHeight); decrementButton.setFocusTraversable(false); decrementButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent ae) { decrement(); ae.consume(); } }); StackPane decPane = new StackPane(); decPane.getChildren().addAll(decrementButton, arrowDown); decPane.setAlignment(Pos.CENTER); buttons.getChildren().addAll(incPane, decPane); this.getChildren().addAll(numberField, buttons); } /** * increment number value by stepWidth */ private void increment() { BigDecimal value = numberField.getNumber(); value = value.add(stepWitdhProperty.get()); numberField.setNumber(value); } /** * decrement number value by stepWidth */ private void decrement() { BigDecimal value = numberField.getNumber(); value = value.subtract(stepWitdhProperty.get()); numberField.setNumber(value); } public final void setNumber(BigDecimal value) { numberField.setNumber(value); } public ObjectProperty numberProperty() { return numberField.numberProperty(); } public final BigDecimal getNumber() { return numberField.getNumber(); } // debugging layout bounds public void dumpSizes() { System.out.println("numberField (layout)=" + numberField.getLayoutBounds()); System.out.println("buttonInc (layout)=" + incrementButton.getLayoutBounds()); System.out.println("buttonDec (layout)=" + decrementButton.getLayoutBounds()); System.out.println("binding=" + buttonHeight.toString()); System.out.println("spacing=" + spacing.toString()); } } number_spinner.css Last but not least the control can be styled in the css file. I played around with two looks, rounded corners and straight corners (see attached screenshots). You can switch between them by changing the border/background-radiuses in #NumberField, #ButtonBox, #SpinnerButtonUp and #SpinnerButtonDown. .root{ -fx-font-size: 24pt; /* -fx-base: rgb(255,0,0);*/ /* -fx-background: rgb(50,50,50);*/ } #NumberField { -fx-border-width: 1; -fx-border-color: lightgray; -fx-background-insets:1; -fx-border-radius:3 0 0 3; /* -fx-border-radius:0 0 0 0;*/ } #NumberSpinnerArrow { -fx-fill: gray; -fx-stroke: gray; /* -fx-effect: innershadow( gaussian , black , 2 , 0.6 , 1 , 1 )*/ } #ButtonsBox { -fx-border-color:lightgray; -fx-border-width: 1 1 1 0; -fx-border-radius: 0 3 3 0; /* -fx-border-radius: 0 0 0 0;*/ } #SpinnerButtonUp { -fx-background-insets: 0; -fx-background-radius:0 3 0 0; /* -fx-background-radius:0;*/ } #SpinnerButtonDown { -fx-background-insets: 0; -fx-background-radius:0 0 3 0; /* -fx-background-radius:0;*/ } Conclusion Doing custom controls in JavaFX is really no big deal although the examples above are really easy ones. JavaFX being a pure Java API since 2.0 now integrates even better than before with languages like groovy where BigDecimal is a first class citizen. This makes it an almost perfect couple for financial desktops applications.
February 8, 2012
by Thomas Bolz
· 81,584 Views · 4 Likes
article thumbnail
Separating Integration and Unit Tests with Maven, Sonar, Failsafe, and JaCoCo
Execute the slow integration tests separately from unit tests and show as much information about them as possible in Sonar.
February 8, 2012
by Jakub Holý
· 57,087 Views · 1 Like
article thumbnail
Java.lang.VerifyError: Expecting a stackmap frame at branch target – JDK 7
Right now, when I try to persist an object in Google App Engine, I’m facing the error “Java.lang.VerifyError: Expecting a stackmap frame at branch target“. I’m using JDK 7 and it seems like the problem lies with this JDK. After googling a bit, I found that there seems to be two solutions to fix this problem. Solution 1: Change to JDK 6 As simple as is, change your JDK to version 6 and you won’t be bugged by this exception anymore. Well, in my case, I have to use JDK 7. So, moving on to the solution 2. Solution 2: Configure JVM Go to Windows -> Preferences -> Installed JREs. Select the default JVM and click edit. Then add this parameter as VM argument “-XX:-UseSplitVerifier” as seen below. This should solve the issue. From http://veerasundar.com/blog/2012/01/java-lang-verifyerror-expecting-a-stackmap-frame-at-branch-target-jdk-7/
February 6, 2012
by Veera Sundar
· 47,746 Views
article thumbnail
Why does my Maven build suddenly fail?
i want to share something a software developer or operations guy every now and then encounters. and which i did yesterday. it all started with our nightly maven build failing last saturday jan 28 on a java.lang.noclassdeffounderror: javax/xml/bind/validationeventlocator the interesting snippet from the concole output from this build looked like this: [info] [jaxb2:generate {execution: xxx-schema-gen}] [fatal error] org.jvnet.mjiip.v_2.xjc2mojo#execute() caused a linkage error (java.lang.noclassdeffounderror) and may be out-of-date. check the realms: [fatal error] plugin realm = app0.child-container[org.jvnet.jaxb2.maven2:maven-jaxb2-plugin] urls[0] = file:/home/hudson/.m2/repository/org/jvnet/jaxb2/maven2/maven-jaxb2-plugin/0.8.1/maven-jaxb2-plugin-0.8.1.jar urls[1] = file:/home/hudson/.m2/repository/org/jvnet/jaxb2/maven2/maven-jaxb2-plugin-core/0.8.1/maven-jaxb2-plugin-core-0.8.1.jar urls[2] = file:/home/hudson/.m2/repository/com/sun/org/apache/xml/internal/resolver/20050927/resolver-20050927.jar urls[3] = file:/home/hudson/.m2/repository/org/sonatype/plexus/plexus-build-api/0.0.7/plexus-build-api-0.0.7.jar urls[4] = file:/home/hudson/.m2/repository/org/codehaus/plexus/plexus-utils/1.5.15/plexus-utils-1.5.15.jar urls[5] = file:/home/hudson/.m2/repository/org/jfrog/maven/annomojo/maven-plugin-anno/1.3.1/maven-plugin-anno-1.3.1.jar urls[6] = file:/home/hudson/.m2/repository/org/jvnet/jaxb2/maven2/maven-jaxb22-plugin/0.8.1/maven-jaxb22-plugin-0.8.1.jar urls[7] = file:/home/hudson/.m2/repository/com/sun/xml/bind/jaxb-impl/2.2.5-b10/jaxb-impl-2.2.5-b10.jar urls[8] = file:/home/hudson/.m2/repository/com/sun/xml/bind/jaxb-xjc/2.2.5-b10/jaxb-xjc-2.2.5-b10.jar [fatal error] container realm = plexus.core.maven [info] ------------------------------------------------------------------------ [error] fatal error [info] ------------------------------------------------------------------------ [info] javax/xml/bind/validationeventlocator [info] ------------------------------------------------------------------------ [info] trace java.lang.noclassdeffounderror: javax/xml/bind/validationeventlocator at com.sun.tools.xjc.reader.internalizer.domforestscanner.scan(domforestscanner.java:84) it seems that the maven-jaxb2-plugin –we use for jaxb to generate java sources for a certain schema–suddenly triggers a (missing or incompatible?) dependency. the weird thing is the “suddenly” part, since the last commit was done on friday after which the normal continuous builds ran fine and the even the nightly build on midnight friday to saturday. we use maven to take care of these things right? always have a known set of dependencies, each part of the process? ofcourse at the time things didn’t seem so obvious. first thing i wondered, could it have something do to with a java 5 vs 6 problem? as a matter of fact, on our project we’re trying to go to java 6 after a long time, but i’m the only one which already upgraded my local developer machine to work with jdk6 for a while and see if nothing strange happens. you know, keeping a lot of files from your workspace in a special “do not commit” working set or hidden from view, in order to prevent it from prematurely ending up in version control so naturally, i first explored all changesets leading up to the failed build to see if i by accident committed a file i shouldn’t have. but i couldn’t find anything. next i thought: could hudson be configured incorrectly last week by a parting co-worker (which had a somewhat unofficial ownership of our ci infrastructure until he left) which now surfaced, because e.g. a server was restarted or hudson was upgraded? checked a few things out: our hudson startup.sh looked like /usr/java/latest/bin/java -jar hudson.war --httpport=9090 --ajp13port=9091 --deamon --logfile=hudson.log & where /usr/java/latest/bin/java pointed to “java(tm) se runtime environment (build 1.6.0 _24-b07)” while normal “java” on the command-line pointed to “java(tm) 2 runtime environment, standard edition (build 1.5.0 _22-b03)” . could it be that the “latest” directory pointed earlier to java 5 en (by some mysterious upgrade on the server) now suddenly links to java 6. could the java version we start hudson with affect the java version we use for our hudson jobs? i don’t hope so! consequently, i checked the hudson configuration itself: what kind of jdk’s did we configure? luckily, only one: named “1_5_0″ with java_home pointing to “/usr/java/default”. but again not clear from the path to what java version it points, until i figured out this symlink leads to “/usr/java/jdk1.5.0_22″. good, jdk 5 should be used as default for all our maven builds. to verify i added a 2nd bogus jdk entry in the hudson configuration, so i was able to explicitly choose it in the job configuration – and after triggering a new build i was sure hudson was configured correctly jdk-wise. man, how one can digress! so let’s take a look at the offending library at hand. from the stacktrace one can spot the maven-jaxb2-plugin artefact from the group org.jvnet.jaxb2.maven2 . did something happen to this dependency itself? i opened up our nexus console, searched for it and saw the screen below: wait a minute! why do we have two versions of this plugin? in nexus i opened up the tab artefact information on the 0.8.1 version and saw that the uploaded date listed last saturday 28th of jan. i know we shouldn’t have more than one version of this plugin in nexus. did a small check on the jira release notes page of this plugin… well then. so a new release of the plugin was published online last saturday and the nightly build triggered the download of a new version 0.8.1 – which seemed to be compiled against java 6 now which caused the java.lang.noclassdeffounderror . this naturally lead me to the offending part in our pom.xml : org.jvnet.jaxb2.maven2 maven-jaxb2-plugin argh. no version! changed it into: org.jvnet.jaxb2.maven2 maven-jaxb2-plugin 0.8.0 i committed the pom.xml and triggerd a manual build – and… it worked. ofcourse. in conclusion there are some lessons to be learned i think: when debugging a problem, always try to reason about possible paths which come to mind to follow first and don’t get hung on your very first idea which pops up. this got me i think sidetracked too long on finding out whether or not i accidentally committed java 6 files or whether or not hudson got accidentally misconfigured into not using java 5 anymore somehow. troubleshooting skills are highly dependent of previous experience in a field and ofcourse, if ever a similar problem arises i’d be able to recognize it faster now. write it down – so a collegue or yourself can find it back more easily later on. explicity set dependency versions in your pom.xml! don’t blame maven for everything does anyone else have a troubleshooting-tale of going in the wrong direction? original posting: http://tedvinke.wordpress.com/2012/02/01/why-does-my-maven-build-fail
February 4, 2012
by Ted Vinke
· 16,257 Views
article thumbnail
Marshalling / Unmarshalling Java Objects: Serialization vs Externalization
We all know the Java platform allows us to create reusable objects in memory. However, all of those objects exist only as long as the Java virtual machine remains running. It would be nice if the objects we create could exist beyond the lifetime of the virtual machine. Well, with object serialization, you can flatten your objects and reuse them in powerful ways. Object serialization is the process of saving an object’s state to a sequence of bytes, as well as the process of rebuilding those bytes into a live object at some future time. The Java Serialization API provides a standard mechanism for developers to handle object serialization. The API is small and easy to use, provided the classes and methods are understood. By implementating java.io.Serializable, you get “automatic” serialization capability for objects of your class. No need to implement any other logic, it’ll just work. The Java runtime will use reflection to figure out how to marshal and unmarshal your objects. In earlier version of Java, reflection was very slow, and so serializaing large object graphs (e.g. in client-server RMI applications) was a bit of a performance problem. To handle this situation, the java.io.Externalizable interface was provided, which is like java.io.Serializable but with custom-written mechanisms to perform the marshalling and unmarshalling functions (you need to implement readExternal and writeExternal methods on your class). This gives you the means to get around the reflection performance bottleneck. In recent versions of Java (1.3 onwards, certainly) the performance of reflection is vastly better than it used to be, and so this is much less of a problem. I suspect you’d be hard-pressed to get a meaningful benefit from Externalizable with a modern JVM. Also, the built-in Java serialization mechanism isn’t the only one, you can get third-party replacements, such as JBoss Serialization, which is considerably quicker, and is a drop-in replacement for the default. A big downside of Externalizable is that you have to maintain this logic yourself – if you add, remove or change a field in your class, you have to change your writeExternal/readExternal methods to account for it. In summary, Externalizable is a relic of the Java 1.1 days. There’s really no need for it any more. References http://java.sun.com/developer/technicalArticles/Programming/serialization http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html http://docs.oracle.com/javase/6/docs/api/java/io/Externalizable.html From http://singztechmusings.in/marshalling-unmarshalling-java-objects-serialization-vs-externalization/
February 1, 2012
by Singaram Subramanian
· 45,316 Views · 1 Like
article thumbnail
Gentle introduction to WADL (in Java)
WADL (Web Application Description Language) is to REST what WSDL is to SOAP. The mere existence of this language causes a lot of controversy (see: Do we need WADL? and To WADL or not to WADL). I can think of few legitimate use cases for using WADL, but if you are here already, you are probably not seeking for yet another discussion. So let us move forward to the WADL itself. In principle WADL is similar to WSDL, but the structure of the language is much different. Whilst WSDL defines a flat list of messages and operations either consuming or producing some of them, WADL emphasizes the hierarchical nature of RESTful web services. In REST, the primary artifact is the resource. Each resource (noun) is represented as an URI. Every resource can define both CRUD operations (verbs, implemented as HTTP methods) and nested resources. The nested resource has a strong relationship with a parent resource, typically representing an ownership. A simple example would be http://example.com/api/books resource representing a list of books. You can (HTTP) GET this resource, meaning to retrieve the whole list. You can also GET the http://example.com/api/books/7 resource, fetching the details of 7th book inside books resource. Or you can even PUT new version or DELETE the resource altogether using the same URI. You are not limited to a single level of nesting: GETting http://example.com/api/books/7/reviews?page=2&size=10 will retrieve the second page (up to 10 items) of reviews of 7th book. Obviously you can also place other resources next to books, like http://example.com/api/readers The requirement arose to formally and precisely describe every available resource, method, request and response, just like WSDL guys were able to do. WADL is one of the options to describe “available URIs", although some believe that well-written REST service should be self-descriptive (see HATEOAS). Nevertheless here is a simple, empty WADL document: Nothing fancy here. Note that the tag defines base API address. All named resources, which we are just about to add, are relative to this address. Also you can define several tags to describe more than one APIs. So, let's add a simple resource: This defines resource under http://example.com/api/books with two methods possible: GET to retrieve the whole list and POST to create (add) new item. Depending on your requirements you might want to allow DELETE method as well (to delete all items), and it is the responsibility of WADL to document what is allowed. Remember our example at the beginning: /books/7? Obviously 7 is just an example and we won't declare every possible book id in WADL. Instead there is a handy placeholder syntax:There are two important aspects you should note: first, The {bookId} place-holder was used in place of nested resource. Secondly, to make it clear, we are documenting this place-holder using tag. We will see soon how it can be used in combination with methods. Just to make sure you are still with me, the document above describes GET /books and GET /books/some_id resources. The web service is getting complex, however it describes quite a lot of operations. First of all GET /books/42/reviews is a valid operation. But the interesting part is the nested tag. As you can see we can describe parameters of each method independently. In our case optional query parameters (as opposed to template parameters used previously for URI place-holders) were defined. This gives the client additional knowledge about acceptable page and size query parameters. This means that /books/7/reviews?page=2&size=10 is a valid resource identifier. And did I mention that every resource, method and parameter can have documentation attached as per the WADL specification? We will stop here and only mention about remaining pieces of WADL. First of all, as you have probably guessed so far, there is also a child tag possible for each . Both request and response can define exact grammar (e.g. in XML Schema) that either the request or the response must follow. The response can also document possible HTTP response codes. But since we will be using the knowledge you have gained so far in a code-first application, I intentionally left the definition. WADL is agile and it allows you to define as little (or as much) information as you need. So we know the basics of WADL, now we would like to use it, maybe as a consumer or as a producer in a Java-based application. Fortunately there is a wadl.xsd XML Schema description of the language itself, which we can use to generate JAXB-annotated POJOs to work with (using xjc tool in the JDK): $ wget http://www.w3.org/Submission/wadl/wadl.xsd $ xjc wadl.xsd And there it... hangs! The life of a software developer is full of challenges and non-trivial problems. And sometimes it is just an annoying network filter that makes suspicious packets (together with half hour of your life) disappear. It is not hard to spot the problem, once you recall that article written around 2008: W3C’s Excessive DTD Traffic: Accessing xml.xsd from the browser returns an HTML page instantly, but xjc tool waits forever. Downloading this file locally and correcting the schemaLocation attribute in wadl.xsd helped. It's always the little things... $ xjc wadl.xsd parsing a schema... compiling a schema... net/java/dev/wadl/_2009/_02/Application.java net/java/dev/wadl/_2009/_02/Doc.java net/java/dev/wadl/_2009/_02/Grammars.java net/java/dev/wadl/_2009/_02/HTTPMethods.java net/java/dev/wadl/_2009/_02/Include.java net/java/dev/wadl/_2009/_02/Link.java net/java/dev/wadl/_2009/_02/Method.java net/java/dev/wadl/_2009/_02/ObjectFactory.java net/java/dev/wadl/_2009/_02/Option.java net/java/dev/wadl/_2009/_02/Param.java net/java/dev/wadl/_2009/_02/ParamStyle.java net/java/dev/wadl/_2009/_02/Representation.java net/java/dev/wadl/_2009/_02/Request.java net/java/dev/wadl/_2009/_02/Resource.java net/java/dev/wadl/_2009/_02/ResourceType.java net/java/dev/wadl/_2009/_02/Resources.java net/java/dev/wadl/_2009/_02/Response.java net/java/dev/wadl/_2009/_02/package-info.java Since we'll be using these classes in a maven based project (and I hate committing generated classes to source repository), let's move xjc execution to maven lifecycle: org.codehaus.mojo jaxb2-maven-plugin 1.3 net.java.dev.jaxb2-commons jaxb-fluent-api 2.0.1 com.sun.xml jaxb-xjc xjc -Xfluent-api bindings.xjb net.java.dev.wadl Well, pom.xml isn't the most concise format ever... Never mind, this will generate WADL XML classes during every build, before the source code is compiled. I also love the fluent-api plugin that adds with*() methods along with ordinary setters, returning this to allow chaining. Pretty convenient. Finally we define more pleasant package name for generated artifacts (if you find net.java.dev.wadl._2009._02 package name pleasant enough, you can skip this step) and add Wadl prefix to all generated classes bindings.xjb file: We are now ready to produce and consume WADL in XML format using JAXB and POJO classes. Equipped with that knowledge and the foundation we are ready to develop some interesting library – which will be the subject of the next article. From http://nurkiewicz.blogspot.com/2012/01/gentle-introduction-to-wadl-in-java.html
January 31, 2012
by Tomasz Nurkiewicz
· 29,847 Views
article thumbnail
Mapping Mongodb ISODate to Spring Roo Entity
I have been inserting log4j entries into a mongodb database and each entry has been given an ISODate timestamp: "timestamp" : ISODate("2012-01-17T22:30:19.839Z") To create a mapping for this, I had to manually add the timestamp as Spring Roo did not allow timestamp to be used as it was a reserved word. So I manually added: @DateTimeFormat(style="MM/dd/yyyy") private java.util.Date timestamp; But I started getting the following error: Invalid style specification: MM/dd/yyyy The stack trace for that error was: org.joda.time.format.DateTimeFormat.createFormatterForStyle(DateTimeFormat.java:702) org.joda.time.format.DateTimeFormat.patternForStyle(DateTimeFormat.java:212) com.comcast.uivr.web.LoggingController_Roo_Controller.ajc$interMethod$com_comcast_uivr_web_LoggingController_Roo_Controller$com_comcast_uivr_web_LoggingController$addDateTimeFormatPatterns(LoggingController_Roo_Controller.aj:98) com.comcast.uivr.web.LoggingController.ajc$interMethodDispatch2$com_comcast_uivr_web$addDateTimeFormatPatterns(LoggingController.java:1) com.comcast.uivr.web.LoggingController_Roo_Controller.ajc$interMethodDispatch1$com_comcast_uivr_web_LoggingController_Roo_Controller$com_comcast_uivr_web_LoggingController$addDateTimeFormatPatterns(LoggingController_Roo_Controller.aj) com.comcast.uivr.web.LoggingController_Roo_Controller.ajc$interMethod$com_comcast_uivr_web_LoggingController_Roo_Controller$com_comcast_uivr_web_LoggingController$list(LoggingController_Roo_Controller.aj:66) com.comcast.uivr.web.LoggingController.list(LoggingController.java:1) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597) org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:212) org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126) org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) javax.servlet.http.HttpServlet.service(HttpServlet.java:617) javax.servlet.http.HttpServlet.service(HttpServlet.java:717) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857) org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) java.lang.Thread.run(Thread.java:662) To fix this I attempted to add the ISO date format for the @DateTimeFormat @DateTimeFormat(style="yyyyMMdd'T'HHmmss.SSSZ") private java.util.Date timestamp; Which still did not work and had the error. To resolve this I shitched to use ISO.DATE_TIME as the style: @DateTimeFormat(iso=ISO.DATE_TIME) private java.util.Date timestamp; From http://www.baselogic.com/blog/development/springframework/mapping-mongodb-isodate-spring-roo-entity/
January 30, 2012
by Mick Knutson
· 23,954 Views · 2 Likes
article thumbnail
Visualize Maven Project Dependencies with dependency:tree and Dot Diagram Output
The dependency:tree goal of the Maven plugin dependency supports various graphical outputs from the version 2.4 up. This is how you would create a diagram showing all dependencies in the com.example group in the dot format: mvn dependency:tree -Dincludes=com.example-DappendOutput=true -DoutputType=dot -DappendOutput=true -DoutputFile=/path/to/output.dot To actually produce an image from .dot you can use one of .dot renderers, f.ex. this online dot renderer (paste into the right text box, press enter). You could also generate the output f.ex. in the graphml format & visualize it in Eclipse. From http://theholyjava.wordpress.com/2012/01/13/visualize-maven-project-dependencies-with-dependencytree-and-dot-diagram-output/
January 25, 2012
by Jakub Holý
· 31,715 Views
article thumbnail
Modular Java Apps - A Microkernel Approach
Software Engineering is all about reuse. We programmers therefore love to split applications up into smaller components so that each of them can be reused or extended in an independent manner. A keyword here is "loose coupling". Slightly simplified, this means, each component should have as few dependencies to other components as possible. Most important, if I have a component B which relies on component A, I don't want that A needs to know about B. The component A should just provide a clean interface which could be used and extended by B. In Java there are many frameworks which provide this exact functionality: JavaEE, Spring, OSGI. However, each of those frameworks come with their own way to do things and provide lots and lots of additional functionality - whether you want it or not! Since we here at scireum love modularity (we build 4 products out of a set of about 10 independet modules) we built our own little framework. I factored out the most important parts and now have a single class with less than 250 lines of code+comments! I call this a microkernel approach, since it nicely compares to the situation we have with operating systems: There are monolithic kernels like the one of Linux with about 11,430,712 lines of code. And there is a concept called a microkernel, like to one of Minix with about 6,000 lines of executable kernel code. There is still an ongoing discussion which of the two solituons is better. A monolithic kernel is faster, a microkernel has way less critical code (critical code means: a bug there will crash the complete system. If you haven't already, you should read more about mikrokernels on Wikipedia. However one might think about operating systems - when it comes to Java I prefer less dependencies and if possible no black magic I don't understand. Especially if this magic involves complex ClassLoader structures. Therefore, here comes Nucleus... How does this work? The framework (Nucleus) solves two problems of modular applications: I want provide a service to other components - but I only want to show an interface and they should be provided with my implementation at runtime without knowning(referencing) it. I want to provide a service or callback for other components. I provide an interface, and I want to know all classes implementig it, so I can invoke them. Ok, we probably need examples for this. Say we want to implement a simple timer service. It provides an interface: public interface EveryMinute { void runTimer() throws Exception; } All classes implementing this interface should be invoked every minute. Additionally we provide some infos - namely, when was the timer executed last. public interface TimerInfo { String getLastOneMinuteExecution(); } Ok, next we need a client for our services: @Register(classes = EveryMinute.class) public class ExampleNucleus implements EveryMinute { private static Part timerInfo = Part.of(TimerInfo.class); public static void main(String[] args) throws Exception { Nucleus.init(); while (true) { Thread.sleep(10000); System.out.println("Last invocation: " + timerInfo.get().getLastOneMinuteExecution()); } } @Override public void runTimer() throws Exception { System.out.println("The time is: " + DateFormat.getTimeInstance().format(new Date())); } } The static field "Part timerInfo" is a simple helper class which fetches the registered instance from Nucleus on the first call and loads it into a private field. So accessing this part has almost no overhead to a normal field access - yet we only reference an interface, not an implementation. The main method first initializes Nucleus (this performs the classpath scan etc.) and then simply goes into an infinite loop, printing the last execution of our timer every ten seconds. Since our class wears a @Register annotation, it will be discovered by a special ClassLoadAction (not by Nucleus itself) instantiated and registered for the EveryMinute interface. Its method runTimer will then be invoced by our timer service every minute. Ok, but how would our TimerService look like? @Register(classes = { TimerInfo.class }) public class TimerService implements TimerInfo { @InjectList(EveryMinute.class) private List everyMinute; private long lastOneMinuteExecution = 0; private Timer timer; public TimerService() { start(); } public void start() { timer = new Timer(true); // Schedule the task to wait 60 seconds and then invoke // every 60 seconds. timer.schedule(new InnerTimerTask(), 1000 * 60, 1000 * 60); } private class InnerTimerTask extends TimerTask { @Override public void run() { // Iterate over all instances registered for // EveryMinute and invoke its runTimer method. for (EveryMinute task : everyMinute) { task.runTimer(); } // Update lastOneMinuteExecution lastOneMinuteExecution = System.currentTimeMillis(); } } @Override public String getLastOneMinuteExecution() { if (lastOneMinuteExecution == 0) { return "-"; } return DateFormat.getDateTimeInstance().format( new Date(lastOneMinuteExecution)); } } This class also wears a @Register annotation so that it will also be loaded by the ClassLoadAction named above (the ServiceLoadAction actually). As above it will be instantiated and put into Nucleus (as implementation of TimerInfo). Additionally it wears an @InjectList annotation on the everyMinute field. This will be processed by another class named Factory which performs simple dependency injection. Since its constructur starts a Java Timer for the InnerTimerTask, from that point on all instances registered for EveryMinute will be invoced by this timer - as the name says - every minute. How is it implemented? The good thing about Nucleus is, that it is powerful on the one hand, but very simple and small on the other hand. As you could see, there is no inner part for special or privileged services. Everything is built around the kernel - the class Nuclues. Here is what it does: It scans the classpath and looks for files called "component.properties". Those need to be in the root folder of a JAR or in the /src folder of each Eclipse project respectively. For each identified JAR / project / classpath element, it then collects all contained class files and loads them using Class.forName. For each class, it checks if it implements ClassLoadAction, if yes, it is put into a special list. Each ClassLoadAction is instanciated and each previously seen class is sent to it using: void handle(Class clazz) Finally each ClassLoadAction is notified, that nucleus is complete so that final steps (like annotation based dependency injection) could be performed. That's it. The only other thing Nucleus provides is a registry which can be used to register and retrieve objects for a class. (An in-depth description of the process above, can be found here: http://andreas.haufler.info/2012/01/iterating-over-all-classes-with.html). Now to make this framework useable as shown above, there is a set of classes around Nucleus. Most important is the class ServiceLoadAction, which will instantiate each class which wears a @Register annoation, runs Factory.inject (our mini DI tool) on it, and throws it into Nucleus for the listed classes. Whats important: The ServiceLoadActions has no specific rights or privileges, you can easily write your implementation which does smarter stuff. Next to some annotations, there are three other handy classes when it comes to retrieving instances from Nucleus: Factory, Part and Parts. As noted above, the Factory is a simple dependency injector. Currently only the ServiceLoadAction autmatically uses the Factory, as all classes wearing the @Register annotation are scanned for required injections. You can however use this factory to run injections on your own classes or other ClassLoadActions to do the same as ServiceLoadAction. If you can't or don't want to rely in annotation based dependency magic, you can use the two helper classes Part and Parts. Those are used like normal fields (see ExampleNucleus.timerInfo above) and fetch the appropriate object or list of objects automatically. Since the result is cached, repeated invocations have almost no overhead compared to a normal field. Nucleus and the example shown above is open source (MIT-License) and available here: https://github.com/andyHa/scireumOpen/blob/master/src/examples/ExampleNucleus.java https://github.com/andyHa/scireumOpen/tree/master/src/com/scireum/open/nucleus If you're interested in using Nucleus, I could put the relevant souces into a separater repository and also provide a release jar - just write a comment below an let me know. This post is the fourth part of the my series "Enterprisy Java" - We share our hints and tricks how to overcome the obstacles when trying to build several multi tenant web applications out of a set of common modules.
January 23, 2012
by Andreas Haufler
· 9,772 Views · 1 Like
article thumbnail
Datatype Conversion in Java: XMLGregorianCalendar to java.util.Date / java.util.Date to XMLGregorianCalendar
package singz.test; import java.util.Date; import java.util.GregorianCalendar; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; /** * A utility class for converting objects between java.util.Date and * XMLGregorianCalendar types * */ public class XMLGregorianCalendarConversionUtil { // DatatypeFactory creates new javax.xml.datatype Objects that map XML // to/from Java Objects. private static DatatypeFactory df = null; static { try { df = DatatypeFactory.newInstance(); } catch(DatatypeConfigurationException e) { throw new IllegalStateException( "Error while trying to obtain a new instance of DatatypeFactory", e); } } // Converts a java.util.Date into an instance of XMLGregorianCalendar public static XMLGregorianCalendar asXMLGregorianCalendar(java.util.Date date) { if(date == null) { return null; } else { GregorianCalendar gc = new GregorianCalendar(); gc.setTimeInMillis(date.getTime()); return df.newXMLGregorianCalendar(gc); } } // Converts an XMLGregorianCalendar to an instance of java.util.Date public static java.util.Date asDate(XMLGregorianCalendar xmlGC) { if(xmlGC == null) { return null; } else { return xmlGC.toGregorianCalendar().getTime(); } } public static void main(String[] args) { Date currentDate = new Date(); // Current date // java.util.Date to XMLGregorianCalendar XMLGregorianCalendar xmlGC = XMLGregorianCalendarConversionUtil.asXMLGregorianCalendar( currentDate); System.out.println( "Current date in XMLGregorianCalendar format: " + xmlGC.toString()); // XMLGregorianCalendar to java.util.Date System.out.println( "Current date in java.util.Date format: " + XMLGregorianCalendarConversionUtil.asDate(xmlGC).toString()); } } Why do we need XMLGregorianCalendar? Java Architecture for XML Binding (JAXB) allows Java developers to map Java classes to XML representations. JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects. In the default data type bindings i.e. mappings of XML Schema (XSD) data types to Java data types in JAXB, the following types in XML schema (mostly used in web services definition) – xsd:dateTime, xsd:time, xsd:date and so on map to javax.xml.datatype.XMLGregorianCalendar Java type. From http://singztechmusings.in/datatype-conversion-in-java-xmlgregoriancalendar-to-java-util-date-java-util-date-to-xmlgregoriancalendar/
January 21, 2012
by Singaram Subramanian
· 101,217 Views
article thumbnail
The Persistence Layer with Spring Data JPA
This is the forth of a series of articles about Persistence with Spring. This article will focus on the configuration and implementation of the persistence layer with Spring 3.1, JPA and Spring Data. For a step by step introduction about setting up the Spring context using Java based configuration and the basic Maven pom for the project, see this article. The Persistence with Spring series: Part 1 – The Persistence Layer with Spring 3.1 and Hibernate Part 3 – The Persistence Layer with Spring 3.1 and JPA Part 5 – Transaction configuration with JPA and Spring 3.1 No More DAO implementations As I discussed in a previous post, the DAO layer usually consists of a lot of boilerplate code that can and should be simplified. The advantages of such a simplification are many fold: a decrease in the number of artifacts that need to be defined and maintained, simplification and consistency of data access patterns and consistency of configuration. Spring Data takes this simplification one step forward and makes it possible to remove the DAO implementations entirely – the interface of the DAO is now the only artifact that need to be explicitly defined. The Spring Data managed DAO In order to start leveraging the Spring Data programming model with JPA, a DAO interface needs to extend the JPA specific Repository interface - JpaRepository – in Spring’s interface hierarchy. This will enable Spring Data to find this interface and automatically create an implementation for it. Also, by extending the interface we get most if not all relevant CRUD generic methods for standard data access available in the DAO. Defining custom access method and queries As discussed, by implementing one of the Repository interfaces, the DAO will already have some basic CRUD methods (and queries) defined and implemented. To define more specific access methods, Spring JPA supports quite a few options – you can either simply define a new method in the interface, or you can provide the actual JPQ query by using the @Query annotation. A third option to define custom queries is to make use of JPA Named Queries, but this has the disadvantage that it either involves XML or burdening the domain class with the queries. In addition to these, Spring Data introduces a more flexible and convenient API, similar to the JPA Criteria API, only more readable and reusable. The advantages of this API will become more pronounced when dealing with a large number of fixed queries that could potentially be more concisely expressed through a smaller number of reusable blocks that keep occurring in different combinations. Automatic Custom Queries When Spring Data creates a new Repository implementation, it analyzes all the methods defined by the interfaces and tries to automatically generate queries from the method name. While this has limitations, it is a very powerful and elegant way of defining new custom access methods with very little effort. For example, if the managed entity has a name field (and the Java Bean standard getter and setter for that field), defining the findByName method in the DAO interface will automatically generate the correct query: public interface IFooDAO extends JpaRepository< Foo, Long >{ Foo findByName( final String name ); } This is a relatively simple example; a much larger set of keywords is supported by query creation mechanism. In the case that the parser cannot match the property with the domain object field, the following exception is thrown: java.lang.IllegalArgumentException: No property nam found for type class org.rest.model.Foo Manual Custom Queries In addition to deriving the query from the method name, a custom query can be manually specified with the method level @Query annotation. For even more fine grained control over the creation of queries, such as using named parameters or modifying existing queries, the reference is a good place to start. Spring Data transaction configuration The actual implementation of the Spring Data managed DAO – SimpleJpaRepository – uses annotations to define and configure transactions. A read only @Transactional annotation is used at the class level, which is then overridden for the non read-only methods. The rest of the transaction semantics are default, but these can be easily overridden manually per method. Exception Translation without the template One of the responsibilities of Spring ORM templates (JpaTemplate, HibernateTemplate) is exception translation – translating JPA exceptions – which tie the API to JPA – to Spring’s DataAccessException hierarchy. Without the template to do that, exception translation can still be enabled by annotating the DAOs with the @Repository annotation. That, coupled with a Spring bean postprocessor will advice all @Repository beans with all the implementations of PersistenceExceptionTranslator found in the Container – to provide exception translation without using the template. The fact that exception translation is indeed active can easily be verified with an integration test: @Test( expected = DataAccessException.class ) public void whenAUniqueConstraintIsBroken_thenSpringSpecificExceptionIsThrown(){ String name = "randomName"; this.service.save( new Foo( name ) ); this.service.save( new Foo( name ) ); } Exception translation is done through proxies; in order for Spring to be able to create proxies around the DAO classes, these must not be declared final. Spring Data Configuration To activate the Spring JPA repository support, the jpa namespace is defined and used to specify the package where to DAO interfaces are located: At this point, there is no equivalent Java based configuration – support for it is however in the works. The Spring Java or XML configuration The JPA configuration with Spring 3.1 has already been carefully discussed in the previous article of this series. Spring Data also takes advantage of the Spring support for the JPA @PersistenceContext annotation which it uses to wire the EntityManager into the Spring factory bean responsible with creating the actual DAO implementations – JpaRepositoryFactoryBean. In addition to the already discussed configuration, there is one last missing piece – including the Spring Data XML configuration in the overall persistence configuration: @Configuration @EnableTransactionManagement @ImportResource( "classpath*:*springDataConfig.xml" ) public class PersistenceJPAConfig{ ... } The Maven configuration In addition to the Maven configuration for JPA defined in a previous article, the spring-data-jpa dependency is addeed: org.springframework.data spring-data-jpa 1.0.2.RELEASE Conclusion This article covered the configuration and implementation of the persistence layer with Spring 3.1, JPA 2 and Spring JPA (part of the Spring Data umbrella project), using both XML and Java based configuration. The various method of defining more advanced custom queries are discussed, as well as configuration with the new jpa namespace and transactional semantics. The final result is a new and elegant take on data access with Spring, with almost no actual implementation work. You can check out the full implementation in the github project. From the originalThe Persistence Layer with Spring Data JPA of the Persistence with Spring series
January 20, 2012
by Eugen Paraschiv
· 154,989 Views · 2 Likes
article thumbnail
Which Integration Framework Should You Use – Spring Integration, Mule ESB or Apache Camel?
Data exchanges between companies are increasing a lot. The number of applications that must be integrated is increasing, too. The interfaces use different technologies, protocols and data formats. Nevertheless, the integration of these applications must be modeled in a standardized way, realized efficiently and supported by automatic tests. Three integration frameworks are available in the JVM environment, which fulfil these requirements: Spring Integration, Mule ESB and Apache Camel. They implement the well-known Enteprise Integration Patterns (EIP, http://www.eaipatterns.com) and therefore offer a standardized, domain-specific language to integrate applications. These integration frameworks can be used in almost every integration project within the JVM environment – no matter which technologies, transport protocols or data formats are used. All integration projects can be realized in a consistent way without redundant boilerplate code. This article compares all three alternatives and discusses their pros and cons. If you want to know, when to use a more powerful Enterprise Service Bus (ESB) instead of one of these lightweight integration frameworks, then you should read this blog post: http://www.kai-waehner.de/blog/2011/06/02/when-to-use-apache-camel/ (it explains when to use Apache Camel, but the title could also be „When to use a lightweight integration framework“). Comparison Criteria Several criteria can be used to compare these three integration frameworks: Open source Basic concepts / architecture Testability Deployment Popularity Commercial support IDE-Support Errorhandling Monitoring Enterprise readiness Domain specific language (DSL) Number of components for interfaces, technologies and protocols Expandability Similarities All three frameworks have many similarities. Therefore, many of the above comparison criteria are even! All implement the EIPs and offer a consistent model and messaging architecture to integrate several technologies. No matter which technologies you have to use, you always do it the same way, i.e. same syntax, same API, same automatic tests. The only difference is the the configuration of each endpoint (e.g. JMS needs a queue name while JDBC needs a database connection url). IMO, this is the most significant feature. Each framework uses different names, but the idea is the same. For instance, „Camel routes“ are equivalent to „Mule flows“, „Camel components“ are called „adapters“ in Spring Integration. Besides, several other similarities exists, which differ from heavyweight ESBs. You just have to add some libraries to your classpath. Therefore, you can use each framework everywhere in the JVM environment. No matter if your project is a Java SE standalone application, or if you want to deploy it to a web container (e.g. Tomcat), JEE application server (e.g. Glassfish), OSGi container or even to the cloud. Just add the libraries, do some simple configuration, and you are done. Then you can start implementing your integration stuff (routing, transformation, and so on). All three frameworks are open source and offer familiar, public features such as source code, forums, mailing lists, issue tracking and voting for new features. Good communities write documentation, blogs and tutorials (IMO Apache Camel has the most noticeable community). Only the number of released books could be better for all three. Commercial support is available via different vendors: Spring Integration: SpringSource (http://www.springsource.com) Mule ESB: MuleSoft (http://www.mulesoft.org) Apache Camel: FuseSource (http://fusesource.com) and Talend (http://www.talend.com) IDE support is very good, even visual designers are available for all three alternatives to model integration problems (and let them generate the code). Each of the frameworks is enterprise ready, because all offer required features such as error handling, automatic testing, transactions, multithreading, scalability and monitoring. Differences If you know one of these frameworks, you can learn the others very easily due to their same concepts and many other similarities. Next, let’s discuss their differences to be able to decide when to use which one. The two most important differences are the number of supported technologies and the used DSL(s). Thus, I will concentrate especially on these two criteria in the following. I will use code snippets implementing the well-known EIP „Content-based Router“ in all examples. Judge for yourself, which one you prefer. Spring Integration Spring Integration is based on the well-known Spring project and extends the programming model with integration support. You can use Spring features such as dependency injection, transactions or security as you do in other Spring projects. Spring Integration is awesome, if you already have got a Spring project and need to add some integration stuff. It is almost no effort to learn Spring Integration if you know Spring itself. Nevertheless, Spring Integration only offers very rudimenary support for technologies – just „basic stuff“ such as File, FTP, JMS, TCP, HTTP or Web Services. Mule and Apache Camel offer many, many further components! Integrations are implemented by writing a lot of XML code (without a real DSL), as you can see in the following code snippet: You can also use Java code and annotations for some stuff, but in the end, you need a lot of XML. Honestly, I do not like too much XML declaration. It is fine for configuration (such as JMS connection factories), but not for complex integration logic. At least, it should be a DSL with better readability, but more complex Spring Integration examples are really tough to read. Besides, the visual designer for Eclipse (called integration graph) is ok, but not as good and intuitive as its competitors. Therefore, I would only use Spring Integration if I already have got an existing Spring project and must just add some integration logic requiring only „basic technologies“ such as File, FTP, JMS or JDBC. Mule ESB Mule ESB is – as the name suggests – a full ESB including several additional features instead of just an integration framework (you can compare it to Apache ServiceMix which is an ESB based on Apache Camel). Nevertheless, Mule can be use as lightweight integration framework, too – by just not adding and using any additional features besides the EIP integration stuff. As Spring Integration, Mule only offers a XML DSL. At least, it is much easier to read than Spring Integration, in my opinion. Mule Studio offers a very good and intuitive visual designer. Compare the following code snippet to the Spring integration code from above. It is more like a DSL than Spring Integration. This matters if the integration logic is more complex. The major advantage of Mule is some very interesting connectors to important proprietary interfaces such as SAP, Tibco Rendevous, Oracle Siebel CRM, Paypal or IBM’s CICS Transaction Gateway. If your integration project requires some of these connectors, then I would probably choose Mule! A disadvantage for some projects might be that Mule says no to OSGi: http://blogs.mulesoft.org/osgi-no-thanks/ Apache Camel Apache Camel is almost identical to Mule. It offers many, many components (even more than Mule) for almost every technology you could think of. If there is no component available, you can create your own component very easily starting with a Maven archetype! If you are a Spring guy: Camel has awesome Spring integration, too. As the other two, it offers a XML DSL: ${in.header.type} is ‘com.kw.DvdOrder’ ${in.header.type} is ‘com.kw.VideogameOrder’ Readability is better than Spring Integration and almost identical to Mule. Besides, a very good (but commercial) visual designer called Fuse IDE is available by FuseSource – generating XML DSL code. Nevertheless, it is a lot of XML, no matter if you use a visual designer or just your xml editor. Personally, I do not like this. Therefore, let’s show you another awesome feature: Apache Camel also offers DSLs for Java, Groovy and Scala. You do not have to write so much ugly XML. Personally, I prefer using one of these fluent DSLs instead XML for integration logic. I only do configuration stuff such as JMS connection factories or JDBC properties using XML. Here you can see the same example using a Java DSL code snippet: from(“file:incomingOrders “) .choice() .when(body().isInstanceOf(com.kw.DvdOrder.class)) .to(“file:incoming/dvdOrders”) .when(body().isInstanceOf(com.kw.VideogameOrder.class)) .to(“jms:videogameOrdersQueue “) .otherwise() .to(“mock:OtherOrders “); The fluent programming DSLs are very easy to read (even in more complex examples). Besides, these programming DSLs have better IDE support than XML (code completion, refactoring, etc.). Due to these awesome fluent DSLs, I would always use Apache Camel, if I do not need some of Mule’s excellent connectors to proprietary products. Due to its very good integration to Spring, I would even prefer Apache Camel to Spring Integration in most use cases. By the way: Talend offers a visual designer generating Java DSL code, but it generates a lot of boilerplate code and does not allow vice-versa editing (i.e. you cannot edit the generated code). This is a no-go criteria and has to be fixed soon (hopefully)! And the winner is… … all three integration frameworks, because they are all lightweight and easy to use – even for complex integration projects. It is awesome to integrate several different technologies by always using the same syntax and concepts – including very good testing support. My personal favorite is Apache Camel due to its awesome Java, Groovy and Scala DSLs, combined with many supported technologies. I would only use Mule if I need some of its unique connectors to proprietary products. I would only use Spring Integration in an existing Spring project and if I only need to integrate „basic technologies“ such as FTP or JMS. Nevertheless: No matter which of these lightweight integration frameworks you choose, you will have much fun realizing complex integration projects easily with low efforts. Remember: Often, a fat ESB has too much functionality, and therefore too much, unnecessary complexity and efforts. Use the right tool for the right job! Best regards, Kai Wähner (Twitter: @KaiWaehner) http://www.kai-waehner.de/blog/2012/01/10/spoilt-for-choice-which-integration-framework-to-use-spring-integration-mule-esb-or-apache-camel/
January 19, 2012
by Kai Wähner DZone Core CORE
· 110,953 Views · 9 Likes
article thumbnail
Java Garbage Collection Algorithm Design Choices And Metrics To Evaluate Garbage Collector Performance
Memory Management in the Java HotSpot Virtual Machine View more documents from white paper Serial vs Parallel With serial collection, only one thing happens at a time. For example, even when multiple CPUs are available, only one is utilized to perform the collection. When parallel collection is used, the task of garbage collection is split into parts and those subparts are executed simultaneously, on different CPUs. The simultaneous operation enables the collection to be done more quickly, at the expense of some additional complexity and potential fragmentation. Concurrent versus Stop-the-world When stop-the-world garbage collection is performed, execution of the application is completely suspended during the collection. Alternatively, one or more garbage collection tasks can be executed concurrently, that is, simultaneously, with the application. Typically, a concurrent garbage collector does most of its work concurrently, but may also occasionally have to do a few short stop-the-world pauses. Stop-the-world garbage collection is simpler than concurrent collection, since the heap is frozen and objects are not changing during the collection. Its disadvantage is that it may be undesirable for some applications to be paused. Correspondingly, the pause times are shorter when garbage collection is done concurrently, but the collector must take extra care, as it is operating over objects that might be updated at the same time by the application. This adds some overhead to concurrent collectors that affects performance and requires a larger heap size. Compacting versus Non-compacting versus Copying After a garbage collector has determined which objects in memory are live and which are garbage, it can compact the memory, moving all the live objects together and completely reclaiming the remaining memory. After compaction, it is easy and fast to allocate a new object at the first free location. A simple pointer can be utilized to keep track of the next location available for object allocation. In contrast with a compacting collector, a non-compacting collector releases the space utilized by garbage objects in-place, i.e., it does not move all live objects to create a large reclaimed region in the same way a compacting collector does. The benefit is faster completion of garbage collection, but the drawback is potential fragmentation. In general, it is more expensive to allocate from a heap with in-place deallocation than from a compacted heap. It may be necessary to search the heap for a contiguous area of memory sufficiently large to accommodate the new object. A third alternative is a copying collector, which copies (or evacuates) live objects to a different memory area. The benefit is that the source area can then be considered empty and available for fast and easy subsequent allocations, but the drawback is the additional time required for copying and the extra space that may be required. Performance Metrics Several metrics are utilized to evaluate garbage collector performance, including: Throughput—the percentage of total time not spent in garbage collection, considered over long periods of time. Garbage collection overhead—the inverse of throughput, that is, the percentage of total time spent in garbage collection. Pause time—the length of time during which application execution is stopped while garbage collection is occurring. Frequency of collection—how often collection occurs, relative to application execution. Footprint—a measure of size, such as heap size. Promptness—the time between when an object becomes garbage and when the memory becomes available. If you’d like to explore more on this and in general about Java’s garbage collection / memory management, have a look at these slides: Java Garbage Collection, Monitoring, and Tuning View more presentations from Carol McDonald Related articles Practical Garbage Collection – Part 1: Introduction (worldmodscode.wordpress.com) Reducing memory churn when processing large data set (stackoverflow.com) The Top Java Memory Problems – Part 2 (dynatrace.com) imabonehead: Performance Tuning the JVM for Running Apache Tomcat | TomcatExpert (tomcatexpert.com) When Does the Garbage Collector Run in JVM ? (javacircles.wordpress.com) Why Garbage Collection Paranoia is Still (sometimes) Justified (prog21.dadgum.com) Adventures in Java Garbage Collection Tuning (rapleaf.com) From http://singztechmusings.in/java-garbage-collection-algorithm-design-choices-and-metrics-to-evaluate-garbage-collector-performance/
January 19, 2012
by Singaram Subramanian
· 14,518 Views
article thumbnail
Method Validation With Spring 3.1 and Hibernate Validator 4.2
JSR 303 and Hibernate Validator have been awesome additions to the Java ecosystem, giving you a standard way to validate your domain model across application layers.
January 13, 2012
by Gunnar Hillert
· 32,930 Views
article thumbnail
From Java to Node.js
I’ve been developing for quite a while and in quite a few languages. Somehow though, I’ve always seemed to fall back to Java when doing my own stuff – maybe partly from habit, partly because it has in my opinion the best open source selection out there, and party because I liked its mix of features and performance. Originally authored by Matan Amir Specifically though, in the web arena things have been moving fast and furious with new languages, approaches, and methods like RoR, Play!, and Lift (and many others!). While I “get it” regarding the benefits of these frameworks, I never felt the need to give them more than an initial deep dive to see how they work. I nod a few times at their similarities and move on back to plain REST-ful services in Java with Spring, maybe an ORM (i try to avoid them these days), and a JS-rich front-end. Recently, two factors made me deep dive into Node.js. First is my growing appreciation with the progress of the JavaScript front-end. What used to be little JavaScript snippets to validate a form “onSubmit” have evolved to a complete ecosystem of technologies, frameworks, and stacks. My personal favorite these days is Backbone.js and try to use it whenever I can. Second was the first hand feedback I got from a friend at Voxer about their success in using and deploying Node.js at real scale (they have a pretty big Node.js deployment). So I jumped in. In the short time I’ve been using it for some (real) projects, I can say that it’s my new favorite language of choice. First of all, the event-driven (and non-blocking) model is a perfect fit for server side development. While this has existed in the other languages and forms (Java Servlet 3.0, Event Machine, Twisted to name a few), I connected with the easy of use and natural maturity of it in JavaScript. We’re all used to using callbacks anyway from your typical run-of-the-mill AJAX work right? Second is the community and how large its gotten in the short time Node has been around. There are lots of useful open source libraries to use to solve your problems and the quality level is high. Third is that it was just so easy to pick up. I have to admit that my core JavaScript was decent before I started using Node, but in terms of the Node core library and feature set itself, it’s pretty lean and mean and provides a good starting point to build what you need in case you can’t find someone who already did (which you most likely can). So having said all that, I wanted to share what resources helped me get up to speed in Node.js coming from a Java background. Getting to know JavaScript There are lots of good resources out there on Node.js and i’ve listed them below. For me, the most critical piece was getting my JavaScript knowledge to the next level. Because you’ll be spending all your time writing your server code in JavaScript, it pays huge dividends to understand how to take full advantage of it. As a Java developer you’re probably trained to think in OO designs. With me, this was the part that I focused the most on. Fortunately (or unforunately), JavaScript is not a classic OO language. It can be if you shoehorn it, but i think that defeats the purpose. Here is my short list of JavaScript resources: JavaScript: The Good Parts - Definitely a requirement. Chapters 4 and 5 (functions, objects, and inheritance) are probably the most important part to understand well for those with an OO background. Learning Javascript with Object Graphs (part 2, and part 3) – howtonode.org has lots of good Node material, but this 3 part post is a good resource to top off your knowledge from the book. Simple “Class” Instantiation – Another good post I read recently. Worth digesting. Learning Node.js With a good JavaScript background, starting to use Node.js is pretty straightforward. The main part to understand is the asynchronous nature of the I/O and the need to produce and consume events to get stuff done. Here is a list of resources I used to get up to speed: DailyJS’s Node Tutorial - A multipart tutorial for Node on DailyJS’s blog. It’s a great resource and worth going through all the posts. Mixu’s Node Book - Not complete, but still worth it. I look forward to reading the future chapters. Node Beginner Book – A good starter read. How To Node – A blog dedicated to Node.js. Bookmark it. I felt that going through these was more than enough to give me the push I needed get started. Hopefully it does for you too (thanks to the authors for taking the time to share their knowledge!). Frameworks? Java is all about open source frameworks. That’s part of why it’s so popular. While Node.js is much newer, lots of people have already done quite a bit of heavy-lifting and have shared their code with the world. Below is what I think is a good mapping of popular Java frameworks to their Node.js equivalents (from what I know so far). Web MVC In Java land, most people are familiar with Web MVC frameworks like Spring MVC, Struts, Wicket, and JSF. More recently though, the trend towards client-side JS MVC frameworks like Ember.js (SproutCore) and Backbone.js reduces the required feature-set of some of these frameworks. Nonetheless, a good comparable Node.js web framework is Express. In a sense, it’s even more than a web framework because it also provides most of the “web server” functionality most Java developers are used to through Tomcat, Jetty, etc (more specifically, Express builds on top of Connect) It’s well thought out and provides the feature set needed to get things done. Application Lifecycle Framework (DI Framework) Spring is a popular framework in Java to provide a great deal of glue and abstraction functionality. It allows easy dependency injection, testing, object lifecycle management, transaction management, etc. It’s usually one of the first things I slap into a new project in Java. In Node.js… I haven’t really missed it. JavaScript allows much more flexible ways of decoupling dependencies and I personally haven’t felt the need to find a replacement for Spring. Maybe that’s a good thing? Object-Relational Mapping (ORMs) I have mixed feelings regarding ORMs in general, but it does make your life easier sometimes. There is no shortage of ORM librares for Node.js. Take your pick. Package Management Tools Maven is probably most popular build management tool for Java. While it is very flexible and powerful with a wide variety of plug-ins, it can get very cumbersome. Npm is the mainstream package manager for Node.js. It’s light, fast, and useful. Testing Framework Java has lots of these for sure, jUnit and company as standard. There are also mock libraries, stub libraries, db test libraries, etc. Node.js has quite a few as well. Pick your poison. I see that nodeunit is popular and is similar to jUnit. I’m personally testing Mocha. Testing tools are a more personal and subjective choice, but the good thing is that there definitely are good choices out there. Logging Java developers have quite a list of choices when choosing a logger library. Commons logging, log4j, logback, and slf4j (wrapper) are some of the more popular ones. Node.js also has a few. I’m currently using winston and have no complaints so far. It has the logging levels, multiple transports (appenders to log4j people), and does it all asynchronously as well. Hopefully this will help someone save some time when peeking into the world of Node. Good luck! Source: http://n0tw0rthy.wordpress.com/2012/01/08/from-java-to-node-js/
January 10, 2012
by Chris Smith
· 28,971 Views · 2 Likes
article thumbnail
Object-oriented Clojure
Clojure is a LISP dialect, and as such a functional language based on a large set of functions and a small set of data structures that they operate with. However, it is possible to implement classes and object in Clojure, with constructs well-supported in the language itself. I do not claim you should program in Clojure only with the techniques described in this article: they are just an attempt to bridge Java libraries with Clojure, and to introduce objects and interfaces where needed. Java interoperability Even from the Clojure REPL, you can easily instantiate Java classes as long as they are in the classpath (so use lein if they are in a library) (def ford (Car. arg1 arg2)) Since classes usually reside into packages, in real code you would use their fully qualified name: (def ford (com.dzone.example.Car. arg1 arg2)) You can also call methods: (.brake ford arg1 arg2) The first argument of the evaluation of a .methodName is always the object, while additional arguments are placed after it, in the same s-expression (a fancy name for a list that can be evaluated.) One of the first exercises in the book The Joy of Clojure is an instantiation of a java.awt.Frame object and a rendering done on it, all from the Clojure interactive interpreter. Doing exploratory testing classes and objects for Java development with the REPL is as faster as writing code into JUnit test. Define your own: interfaces defprotocol takes as the first argument an identifier, and a variable number of parameters. Each of this parameters is a method definition like you would do with fn, but without the fn keyword itself and a body to evaluate. The first argument of the methods should always be this, representing the current object (remember Python?). (defprotocol Position (description [this]) (translateX [this dx]) (translateY [this dy]) (doubleCoords [this]) (average [this another])) Define your own: classes Defining classes in Clojure is simple, at least when they implement immutable Value Objects. defrecord takes a class name, a list of parameters for the constructor, an optional protocol name and a variable number of arguments representing the methods. Again, the methods definition are similar to the ones made with fn, but this time with a body, an s-expression to evaluate. There is a catch: you can only implement methods defined in a protocol. (defrecord CartesianPoint [x y] Position (description [this] (str "(x=" x ", y=" y ")")) (translateX [this dx] (CartesianPoint. (+ x dx) y)) (translateY [this dy] (CartesianPoint. x (+ y dy))) (doubleCoords [this] (CartesianPoint. (* 2 x) (* 2 y))) (average [this another] (let [mean (fn [a b] (/ (+ a b) 2))] (CartesianPoint. (mean x (:x another)) (mean y (:y another)))))) The method access the (immutable) fields of the current object with their names, so this is not probably necessary if not for calling other methods on the object. Note that records are not strictly objects in the OO sense, since they do not encapsulate their fields: fields can be accessed anywhere with (:fieldname object). Here's how to work with CartesianPoint objects: (deftest test-point-x-field (is (= 1 (:x (CartesianPoint. 1 2))))) (deftest test-point-y-field (is (= 2 (:y (CartesianPoint. 1 2))))) (deftest test-point-to-string (is (= "(x=1, y=2)" (description (CartesianPoint. 1 2))))) (deftest test-point-translation-x (is (= (CartesianPoint. 11 2) (translateX (CartesianPoint. 1 2) 10)))) (deftest test-point-translation-y (is (= (CartesianPoint. 1 12) (translateY (CartesianPoint. 1 2) 10)))) (deftest test-point-doubling (is (= (CartesianPoint. 2 4) (doubleCoords (CartesianPoint. 1 2))))) (deftest test-points-average (is (= (CartesianPoint. 3 4) (average (CartesianPoint. 1 2) (CartesianPoint. 5 6)))))
January 10, 2012
by Giorgio Sironi
· 13,852 Views · 2 Likes
article thumbnail
Searching relational content with Lucene's BlockJoinQuery
Lucene's 3.4.0 release adds a new feature called index-time join (also sometimes called sub-documents, nested documents or parent/child documents), enabling efficient indexing and searching of certain types of relational content. Most search engines can't directly index relational content, as documents in the index logically behave like a single flat database table. Yet, relational content is everywhere! A job listing site has each company joined to the specific listings for that company. Each resume might have separate list of skills, education and past work experience. A music search engine has an artist/band joined to albums and then joined to songs. A source code search engine would have projects joined to modules and then files. Perhaps the PDF documents you need to search are immense, so you break them up and index each section as a separate Lucene document; in this case you'll have common fields (title, abstract, author, date published, etc.) for the overall document, joined to the sub-document (section) with its own fields (text, page number, etc.). XML documents typically contain nested tags, representing joined sub-documents; emails have attachments; office documents can embed other documents. Nearly all search domains have some form of relational content, often requiring more than one join. If such content is so common then how do search applications handle it today? One obvious "solution" is to simply use a relational database instead of a search engine! If relevance scores are less important and you need to do substantial joining, grouping, sorting, etc., then using a database could be best overall. Most databases include some form a text search, some even using Lucene. If you still want to use a search engine, then one common approach is to denormalize the content up front, at index-time, by joining all tables and indexing the resulting rows, duplicating content in the process. For example, you'd index each song as a Lucene document, copying over all fields from the song's joined album and artist/band. This works correctly, but can be horribly wasteful as you are indexing identical fields, possibly including large text fields, over and over. Another approach is to do the join yourself, outside of Lucene, by indexing songs, albums and artist/band as separate Lucene documents, perhaps even in separate indices. At search-time, you first run a query against one collection, for example the songs. Then you iterate through all hits, gathering up (joining) the full set of corresponding albums and then run a second query against the albums, with a large OR'd list of the albums from the first query, repeating this process if you need to join to artist/band as well. This approach will also work, but doesn't scale well as you may have to create possibly immense follow-on queries. Yet another approach is to use a software package that has already implemented one of these approaches for you! elasticsearch, Apache Solr, Apache Jackrabbit, Hibernate Search and many others all handle relational content in some way. With BlockJoinQuery you can now directly search relational content yourself! Let's work through a simple example: imagine you sell shirts online. Each shirt has certain common fields such as name, description, fabric, price, etc. For each shirt you have a number of separate stock keeping units or SKUs, which have their own fields like size, color, inventory count, etc. The SKUs are what you actually sell, and what you must stock, because when someone buys a shirt they buy a specific SKU (size and color). Maybe you are lucky enough to sell the incredible Mountain Three-wolf Moon Short Sleeve Tee, with these SKUs (size, color): small, blue small, black medium, black large, gray Perhaps a user first searches for "wolf shirt", gets a bunch of hits, and then drills down on a particular size and color, resulting in this query: name:wolf AND size=small AND color=blue which should match this shirt. name is a shirt field while the size and color are SKU fields. But if the user drills down instead on a small gray shirt: name:wolf AND size=small AND color=gray then this shirt should not match because the small size only comes in blue and black. How can you run these queries using BlockJoinQuery? Start by indexing each shirt (parent) and all of its SKUs (children) as separate documents, using the new IndexWriter.addDocuments API to add one shirt and all of its SKUs as a single document block. This method atomically adds a block of documents into a single segment as adjacent document IDs, which BlockJoinQuery relies on. You should also add a marker field to each shirt document (e.g. type = shirt), as BlockJoinQuery requires a Filter identifying the parent documents. To run a BlockJoinQuery at search-time, you'll first need to create the parent filter, matching only shirts. Note that the filter must use FixedBitSet under the hood, like CachingWrapperFilter: Filter shirts = new CachingWrapperFilter( new QueryWrapperFilter( new TermQuery( new Term("type", "shirt")))); Create this filter once, up front and re-use it any time you need to perform this join. Then, for each query that requires a join, because it involves both SKU and shirt fields, start with the child query matching only SKU fields: BooleanQuery skuQuery = new BooleanQuery(); skuQuery.add(new TermQuery(new Term("size", "small")), Occur.MUST); skuQuery.add(new TermQuery(new Term("color", "blue")), Occur.MUST); Next, use BlockJoinQuery to translate hits from the SKU document space up to the shirt document space: BlockJoinQuery skuJoinQuery = new BlockJoinQuery( skuQuery, shirts, ScoreMode.None); The ScoreMode enum decides how scores for multiple SKU hits should be aggregated to the score for the corresponding shirt hit. In this query you don't need scores from the SKU matches, but if you did you can aggregate with Avg, Max or Total instead. Finally you are now free to build up an arbitrary shirt query using skuJoinQuery as a clause: BooleanQuery query = new BooleanQuery(); query.add(new TermQuery(new Term("name", "wolf")), Occur.MUST); query.add(skuJoinQuery, Occur.MUST); You could also just run skuJoinQuery as-is if the query doesn't have any shirt fields. Finally, just run this query like normal! The returned hits will be only shirt documents; if you'd also like to see which SKUs matched for each shirt, use BlockJoinCollector: BlockJoinCollector c = new BlockJoinCollector( Sort.RELEVANCE, // sort 10, // numHits true, // trackScores false // trackMaxScore ); searcher.search(query, c); The provided Sort must use only shirt fields (you cannot sort by any SKU fields). When each hit (a shirt) is competitive, this collector will also record all SKUs that matched for that shirt, which you can retrieve like this: TopGroups hits = c.getTopGroups( skuJoinQuery, skuSort, 0, // offset 10, // maxDocsPerGroup 0, // withinGroupOffset true // fillSortFields ); Set skuSort to the sort order for the SKUs within each shirt. The first offset hits are skipped (use this for paging through shirt hits). Under each shirt, at most maxDocsPerGroup SKUs will be returned. Use withinGroupOffset if you want to page within the SKUs. If fillSortFields is true then each SKU hit will have values for the fields from skuSort. The hits returned by BlockJoinCollector.getTopGroups are SKU hits, grouped by shirt. You'd get the exact same results if you had denormalized up-front and then used grouping to group results by shirt. You can also do more than one join in a single query; the joins can be nested (parent to child to grandchild) or parallel (parent to child1 and parent to child2). However, there are some important limitations of index-time joins: The join must be computed at index-time and "compiled" into the index, in that all joined child documents must be indexed along with the parent document, as a single document block. Different document types (for example, shirts and SKUs) must share a single index, which is wasteful as it means non-sparse data structures like FieldCache entries consume more memory than they would if you had separate indices. If you need to re-index a parent document or any of its child documents, or delete or add a child, then the entire block must be re-indexed. This is a big problem in some cases, for example if you index "user reviews" as child documents then whenever a user adds a review you'll have to re-index that shirt as well as all its SKUs and user reviews. There is no QueryParser support, so you need to programmatically create the parent and child queries, separating according to parent and child fields. The join can currently only go in one direction (mapping child docIDs to parent docIDs), but in some cases you need to map parent docIDs to child docIDs. For example, when searching songs, perhaps you want all matching songs sorted by their title. You can't easily do this today because the only way to get song hits is to group by album or band/artist. The join is a one (parent) to many (children), inner join. As usual, patches are welcome! There is work underway to create a more flexible, but likely less performant, query-time join capability, which should address a number of the above limitations. Source: http://blog.mikemccandless.com/2012/01/searching-relational-content-with.html
January 9, 2012
by Michael Mccandless
· 14,816 Views
  • Previous
  • ...
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • ...
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×