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
Clojure: State Management
Those unfamiliar with Clojure are often interested in how you manage changing state within your applications. If you've heard a few things about Clojure but haven't really looked at it, I wouldn't be surprised if you thought it was impossible to write a "real" application with Clojure since "everything is immutable". I've even heard a developer that I respect make the mistake of saying: we're not going to use Clojure because it doesn't handle state well. Clearly, state management in Clojure is greatly misunderstood. I actually had a hard time not calling this blog entry "Clojure, it's about state". I think state shapes Clojure more than any other influence; it's the core of the language (as far as I can tell). Rich Hickey has clearly spent a lot of time thinking about state - there's an essay at http://clojure.org/state which describes common problems with a traditional approach to state management and Clojure's solutions. Rich's essay does a good job of succinctly discussing his views on state; you should read it before you continue with this entry. The remainder of this entry will give examples of how you can manage state using Clojure's functions. At the end of Rich's essay he says: In the local case, since Clojure does not have mutable local variables, instead of building up values in a mutating loop, you can instead do it functionally with recur or reduce. Before we get to reduce, let's start with the simplest example. You have an array of ints and you want to double each integer. In a language with mutable state you can loop through the array and build a new array with each integer doubled. for (int i=0; i < nums.length; i++) { result.add(nums[i] * 2); } In Clojure you would build the new array by calling the map function with a function that doubles each value. (I'm using Clojure 1.2) user=> (map (fn [i] (* i 2)) [1 2 3]) (2 4 6) If you're new to Clojure there's a few things worth mentioning. "user=>" is a REPL prompt. You enter some text and hit enter and the text is evaluated. If you've completed the list (closed the parenthesis), the results of evaluating that list will be printed to the following line. I remember what I thought the first time I looked at a lisp, and I know the code might not look like readable code, so here's a version that breaks up a few of the concepts and might make it easier to digest the example. user=> (defn double-int [i] (* i 2)) #'user/double-int user=> (def the-array [1 2 3]) #'user/the-array user=> (map double-int the-array) (2 4 6) In the first Clojure example you call the fn function to create an anonymous function, that was then passed to the map function (to be applied to each element of the array). The map function is a high order function that can take an anonymous function (example 1) or a named function (double-int, example 2). In Clojure (def ...) is a special form that allows you to define a var and defn is a function that allows you to easily define a function and assign it to a var. The syntax for defn is pretty straightforward, the first argument is the name, the second argument is the argument list of the new function, and any additional forms are the body of the function you are defining. Once you get used to Clojure's syntax you can even have a bit of fun with your function naming that might result in concise and maintainable code. user=> (defn *2 [i] (* 2 i)) #'user/*2 user=> (map *2 [1 2 3]) (2 4 6) but, I digress. Similarly, you may want to sum the numbers from an array. for (int i = 0; i < nums.length; i++) { result += nums[i]; } You can achieve goal of reducing an array to a single value in Clojure using the reduce function. user=> (reduce + [1 2 3]) 6 Clojure has several functions that allow you to create new values from existing values, which should be enough to solve any problem where you would traditionally use local mutable variables. For non-local mutable state you generally have 3 options: atoms, refs, and agents. When I started programming in Clojure, atoms were my primary choice for mutable state. Atoms are very easy to use and only require that you know a few functions to interact with them. Let's assume we're building a trading application that needs to keep around the current price of Apple. Our application will call our apple-price-update function when a new price is received and we'll need to keep that price around for (possible) later usage. The example below shows how you can use an atom to track the current price of Apple. user=> (def apple-price (atom nil)) #'user/apple-price user=> (defn update-apple-price [new-price] (reset! apple-price new-price)) #'user/update-apple-price user=> @apple-price nil user=> (update-apple-price 300.00) 300.0 user=> @apple-price 300.0 user=> (update-apple-price 301.00) 301.0 user=> (update-apple-price 302.00) 302.0 user=> @apple-price 302.0 The above example demonstrates how you can create a new atom and reset its value with each price update. The reset! function sets the value of the atom synchronously and returns its new value. You can also query the price of apple at any time using @ (or deref). If you're coming from a Java background the example above should be the easiest to relate to. Each time we call the update-apple-price function our state is set to a new value. However, atoms provide much more value than simply being a variable that you can reset. You may remember the following example from Java Concurrency in Practice. @NotThreadSafe public class UnsafeSequence { private int value; /** * Returns a unique value. */ public int getNext() { return value++; } } The book explains why this could cause potential problems. The problem with UnsafeSequence is that with some unlucky timing, two threads could call getNext and receive the same value. The increment notation, nextValue++, may appear to be a single operation, but is in fact three separate operations: read the value, add one to it, and write out the new value. Since operations in multiple threads may be arbitrarily interleaved by the runtime, it is possible for two threads to read the value at the same time, both see the same value, and then both add one to it. The result is that the same sequence number is returned from multiple calls in different threads. We could write a get-next function using a Clojure atom and the same race condition would not be a concern. user=> (def uniq-id (atom 0)) #'user/uniq-id user=> (defn get-next [] (swap! uniq-id inc)) #'user/get-next user=> (get-next) 1 user=> (get-next) 2 The above code demonstrates the result of calling get-next multiple times (the inc function just adds one to the value passed in). Since we aren't in a multithreaded environment the example isn't exactly breathtaking; however, what's actually happening under the covers is described very well on clojure.org/atoms - [Y]ou change the value by applying a function to the old value. This is done in an atomic manner by swap! Internally, swap! reads the current value, applies the function to it, and attempts to compare-and-set it in. Since another thread may have changed the value in the intervening time, it may have to retry, and does so in a spin loop. The net effect is that the value will always be the result of the application of the supplied function to a current value, atomically. Also, remember that changes to atoms are synchronous, so our get-next function will never return the same value twice. (note: while Java already provides an AtomicInteger class for handling this issue - that's not the point. The point of the example is to show that an Atom is safe to use across threads.) If you're truly interested in verifying that an atom is safe across threads, The Joy of Clojure provides the following snippet of code (as well as a wonderful explanation of all things Clojure, including mutability). (import '(java.util.concurrent Executors)) (def *pool* (Executors/newFixedThreadPool (+ 2 (.availableProcessors (Runtime/getRuntime))))) (defn dothreads [f & {thread-count :threads exec-count :times :or {thread-count 1 exec-count 1}] (dotimes [t thread-count] (.submit *pool* #(dotimes [_ exec-count] (f))))) (def ticks (atom 0)) (defn tick [] (swap! ticks inc)) (dothreads tick :threads 1000 :times 100) @ticks ;=> 100000 There you have it, 1000 threads updated ticks 100 times without issue. Atoms work wonderfully when you want to insure atomic updates to an individual piece of state; however, it probably wont be long before you find yourself wanting to coordinate some type of state update. For example, if you're running an online store, when a customer cancels an order the order is either active or cancelled; however, the order should never be active and cancelled. If you were to keep a set of active orders and a set of cancelled orders, you would never want to have an order be in both sets at the same time. Clojure addresses this issue by using refs. Refs are similar to atoms, but they also participate in coordinated updates. The following example shows the cancel-order function moving an order-id from the active orders set into the cancelled orders set. user=> (def active-orders (ref #{2 3 4})) #'user/active-orders user=> (def cancelled-orders (ref #{1})) #'user/cancelled-orders user=> (defn cancel-order [id] (dosync (commute active-orders disj id) (commute cancelled-orders conj id))) #'user/cancel-order user=> (cancel-order 2) #{1 2} user=> @active-orders #{3 4} user=> @cancelled-orders #{1 2} As you can see from the example, we're moving an order id from active to cancelled. Again, our REPL session doesn't show the power of what's going on with a ref, but clojure.org/refs contains a good explanation - All changes made to Refs during a transaction (via ref-set, alter or commute) will appear to occur at a single point in the 'Ref world' timeline (its 'write point'). The above quote is actually only 1 item in a 10 point list that discusses what's actually going on. It's worth reviewing the list a few times until you feel comfortable with everything that's going on. But, you don't need to completely understand everything to get started. You can begin to experiment with refs anytime you know you need coordinated changes to more than one piece of state. When you first begin to look at refs you may wonder if you should use commute or alter. For most cases commute will provide more concurrency and is preferred; however, you may need to guarantee that the ref has not been updated during the life of the current transaction. This is generally the case where alter comes into play. The following example shows using commute to update two values. The example demonstrates that the pairs are always updated only once; however, it also shows that the function is simply applied to the current value, so the incrementing is not sequential and @uid can be dereferenced to the same value multiple times. user=> (def uid (ref 0)) #'user/uid user=> (def used-id (ref [])) #'user/used-id user=> (defn use-id [] (dosync (commute uid inc) (commute used-id conj @uid))) #'user/use-id user=> (dothreads use-id :threads 10 :times 10) nil user=> @used-id [1 2 3 4 5 6 7 8 9 10 ... 89 92 92 94 93 94 97 97 99 100] The above example shows that commute simply applies regardless of the underlying value. As a result, you may see duplicate values and gaps in your sequence (shown in the 90s in our output). If you wanted to ensure that the value didn't change during your transaction you could switch to alter. The following example shows the behavior of changing from commute to alter. user=> (def uid (ref 0)) #'user/uid user=> (def used-id (ref [])) #'user/used-id user=> (defn use-id [] (dosync (alter uid inc) (alter used-id conj @uid))) #'user/use-id user=> (dothreads use-id :threads 10 :times 10) nil user=> @used-id [1 2 3 4 5 6 7 8 9 10 ... 91 92 93 94 95 96 97 98 99 100] There are more advanced examples using refs in The Joy of Clojure for those of you looking to discuss corner case conditions. Last, but not least, agents are also available. From clojure.org/agents - Like Refs, Agents provide shared access to mutable state. Where Refs support coordinated, synchronous change of multiple locations, Agents provide independent, asynchronous change of individual locations. While I understand agents conceptually, I haven't used them much in practice. Some people love them, and the last team I was on switched to using agents heavily in one of our applications shortly after I left. But, I personally don't have enough experience to say exactly where I think they fit in. I'm sure that will be a topic for a future blog post. Between Rich's essay and the examples above I hope a few things have become clear: Clojure has plenty of support for managing state Rich's distinction between identity and value allows Clojure to benefit from immutable structures while also allowing identity reassignment. Clojure, it's about state. From http://blog.jayfields.com/2011/04/clojure-state-management.html
April 13, 2011
by Jay Fields
· 9,966 Views
article thumbnail
Introduction to Efficient Java Matrix Library (EJML)
Linear algebra is a commonly used area of mathematics with a wide range of applications in various engineering and scientific fields. Examples of applications include line fitting, Kalman filters, face recognition, financial software, and numerical optimization to name a few. Many computer libraries have been developed for linear algebra. One of the better known would be LAPACK, which was originally programmed in Fortran. Introducing Efficient Java Matrix Library The following article provides a brief introduction to one of the newer linear algebra libraries for Java, Efficient Java Matrix Library (EJML), a free open source library. EJML is a linear algebra library for dense real matrices. EJML's design goals are; 1) to be as computationally and memory efficient as possible for both small and large matrices, and 2) to be accessible to both novices and experts. These goals are accomplished by dynamically selecting the best algorithms to use at runtime and through a thoughtfully designed clean API. Providing good documentation, code examples, and constant benchmarking for speed, memory, and stability are also priorities. The following functionality is provided: Basic Operators (addition, multiplication, ... ) Matrix Manipulation (extract, insert, combine, ... ) Linear Solvers (linear, least squares, incremental, ... ) Decompositions (LU, QR, Cholesky, SVD, Eigenvalue, ...) Matrix Features (rank, symmetric, definitiveness, ... ) Random Matrices (covariance, orthogonal, symmetric, ... ) Different Internal Formats (row-major, block) Unit Testing EJML can be downloaded from its website at: http://ejml.org/ Application Programming Interface There are three primary ways to interact with EJML, 1) a simple to use object oriented interface, 2) procedural interface that provides greater control over memory and algorithms, 3) an expert interface that directly access specialized algorithms that is abstracted away using the first two. To see a practical comparison of these three interfaces take a look at the Kalman filter example provided at EJML's website. There each interface is used to code up a functionally identical Kalman filter: Here are three code sniplets showing the Kalman gain being computed: Simple: SimpleMatrix K = P.mult(H.transpose().mult(S.invert())); Procedural: if( !invert(S,S_inv) ) throw new RuntimeException("Invert failed"); multTransA(H,S_inv,d); mult(P,d,K); Specialized: if( !solver.setA(S) ) throw new RuntimeException("Invert failed"); solver.invert(S_inv); MatrixMatrixMult.multTransA_small(H,S_inv,d); MatrixMatrixMult.mult_small(P,d,K); The full examples are available at: http://ejml.org/wiki/index.php?title=Example_Kalman_Filter Going beyond the basics, there are easy to use yet powerful Java interfaces for solving linear systems and matrix decompositions. These provide much more control over the type of algorithm used, what it computes, how much memory is used, and remove as much of the drudgery as possible. DecompositionFactory and LinearSolverFactory are provided for creating these solvers and decompositions. By using the factory the best most update algorithm will be automatically selected. EJML offer many different decomposition algorithms, even within the same family. For instance, there are four QR decompositions provided, each of which is catered towards a different sized matrix. Different factories hide much of these detail from the end user. Who is using EJML? Even though EJML is a fairly new library it has already been picked up by several opensource projects: goGPS: http://code.google.com/p/gogps/ Set Visualiser: http://www-edc.eng.cam.ac.uk/tools/set_visualiser/ Universal Java Matrix Library (UJML): http://www.ujmp.org/ Scalalab: http://code.google.com/p/scalalab/ Java Content Based Image Retrieval (JCBIR): http://code.google.com/p/jcbir/ JquantLib (Will be added): http://www.jquantlib.org/ Performance and Benchmarks What about speed, stability, and correctness? Constant benchmarking for speed and stability is a core part of EJML's development. It has many internal benchmarks and also uses Java Matrix Benchmark (JMatBench)[1] (http://code.google.com/p/java-matrix-benchmark/) to compare its performance against other libraries. At the time of this writing there are a total of 551 unit tests that test basic correctness of almost all the functions in EJML. For runtime performance EJML is one of the fastest single threaded libraries. When compared against multi-threaded libraries on systems with several cores/CPU's it still competitive for many operations, despite its disadvantage of being single threaded. It has one of the lowest memory footprints [2]. A brief summary of EJML's performance relative to other libraries is shown below. Runtime performance is measured on a Core i7M620 system. (2 cores with 4 threads) Performance varies significantly by system. This processor was choosen because it is the most modern system benchmarked. Click here to get a explaination of the plots shown below. [1] Both EJML and JMatBench are developed by the same author. [2] Memory usage is highly dependent on the operation being used and the parameters passed to it. JMatBench only tests a few operations, but at least it shows attention is being paid to memory usage.
April 12, 2011
by Peter Abeles
· 7,167 Views
article thumbnail
Java Access to SQL Azure via the JDBC Driver for SQL Server
I’ve written a couple of posts (here and here) about Java and the JDBC Driver for SQL Server with the promise of eventually writing about how to get a Java application running on the Windows Azure platform. In this post, I’ll deliver on that promise. Specifically, I’ll show you two things: 1) how to connect to a SQL Azure Database from a Java application running locally, and 2) how to connect to a SQL Azure database from an application running in Windows Azure. You should consider these as two ordered steps in moving an application from running locally against SQL Server to running in Windows Azure against SQL Azure. In both steps, connection to SQL Azure relies on the JDBC Driver for SQL Server and SQL Azure. The instructions below assume that you already have a Windows Azure subscription. If you don’t already have one, you can create one here: http://www.microsoft.com/windowsazure/offers/. (You’ll need a Windows Live ID to sign up.) I chose the Free Trial Introductory Special, which allows me to get started for free as long as keep my usage limited. (This is a limited offer. For complete pricing details, see http://www.microsoft.com/windowsazure/pricing/.) After you purchase your subscription, you will have to activate it before you can begin using it (activation instructions will be provided in an email after signing up). Connecting to SQL Azure from an application running locally I’m going to assume you already have an application running locally and that it uses the JDBC Driver for SQL Server. If that isn’t the case, then you can start from scratch by following the steps in this post: Getting Started with the SQL Server JDBC Driver. Once you have an application running locally, then the process for running that application with a SQL Azure back-end requires two steps: 1. Migrate your database to SQL Azure. This only takes a couple of minutes (depending on the size of your database) with the SQL Azure Migration Wizard - follow the steps in the Creating a SQL Azure Server and Creating a SQL Azure Database sections of this post. 2. Change the database connection string in your application. Once you have moved your local database to SQL Azure, you only have to change the connection string in your application to use SQL Azure as your data store. In my case (using the Northwind database), this meant changing this… String connectionUrl = "jdbc:sqlserver://serverName\\sqlexpress;" + "database=Northwind;" + "user=UserName;" + "password=Password"; …to this… String connectionUrl = "jdbc:sqlserver://xxxxxxxxxx.database.windows.net;" + "database=Northwind;" + "user=UserName@xxxxxxxxxx;" + "password=Password"; (where xxxxxxxxxx is your SQL Azure server ID). Connecting to SQL Azure from an application running in Windows Azure The heading for this section might be a bit misleading. Once you have a locally running application that is using SQL Azure, then all you have to do is move your application to Windows Azure. The connecting part is easy (see above), but moving your Java application to Windows Azure takes a bit more work. Fortunately, Ben Lobaugh has written a great post that that shows how to use the Windows Azure Starter Kit for Java to get a Java application (a JSP application, actually) running in Windows Azure: Deploying a Java application to Windows Azure with Command-Line Ant. (If you are using Eclipse, see Ben’s related post: Deploying a Java application to Windows Azure with Eclipse.) I won’t repeat his work here, but I will call out the steps I took in modifying his instructions to deploy a simple JSP page that connects to SQL Azure. 1. Add the JDBC Driver for SQL Server to the Java archive. One step in Ben’s tutorial (see the Select the Java Runtime Environment section) requires that you create a .zip file from your local Java installation and add it to your Java/Azure application. Most likely, your local Java installation references the JDBC driver by setting the classpath environment variable. When you create a .zip file from your java installation, the JDBC driver will not be included and the classpath variable will not be set in the Azure environment. I found the easiest way around this was to simply add the sqljdbc4.jar file (probably located in C:\Program Files\Microsoft SQL Server JDBC Driver\sqljdbc_3.0\enu) to the \lib\ext directory of my local Java installation before creating the .zip file. Note: You can put the JDBC driver in a separate directory, include it when you create the .zip folder, and set the classpath environment variable in the startup.bat script. But, I found the above approach to be easier. 2. Modify the JSP page. Instead of the code Ben suggests for the HelloWorld.jsp file (see the Prepare your Java Application section), use code from your locally running application. In my case, I just used the code from this post after changing the connection string and making a couple minor JSP-specific changes: Northwind Customers That’s it!. To summarize the steps… Migrate your database to SQL Azure with the SQL Azure Migration Wizard. Change the database connection in your locally running application. Use the Windows Azure Starter Kit for Java to move your application to Windows Azure. (You’ll need to follow instructions in this post and instructions above.) Thanks. -Brian
March 30, 2011
by Brian Swan
· 19,041 Views
article thumbnail
CDI Dependency Injection - An Introductory Java EE Tutorial Part 1
This article discusses dependency injection in a tutorial format. It covers some of the features of CDI such as type safe annotations configuration, alternatives and more.
March 28, 2011
by Rick Hightower
· 367,523 Views · 17 Likes
article thumbnail
Java 7: New Feature – Automatically Close Files and Resources in try-catch-finally
Try with resources is a new feature in Java 7 which lets us write more elegant code by automatically closing resources like FileInputStream at the end of the try-block. Old Try Catch Finally Dealing with resources like InputStreams is painful when it comes to the try-catch-finally blocks. You need to declare the resources outside the try so that they are is accessible from finally, then you must initialize the variable to null and check for non-null when closing the resource in finally. File file = new File("input.txt"); InputStream is = null; try { is = new FileInputStream(file); // do something with this input stream // ... } catch (FileNotFoundException ex) { System.err.println("Missing file " + file.getAbsolutePath()); } finally { if (is != null) { is.close(); } } Java 7: Try with resources With Java 7, you can create one or more “resources” in the try statement. A “resources” is something that implements the java.lang.AutoCloseable interface. This resource would be automatically closed and the end of the try block. File file = new File("input.txt"); try (InputStream is = new FileInputStream(file)) { // do something with this input stream // ... } catch (FileNotFoundException ex) { System.err.println("Missing file " + file.getAbsolutePath()); } Exception handling If both the (explicit) try block and the (implicit) resource handling code throw an exception, then the try block exception is the one which will be thrown. The resource handling exception will be made available via the Throwable.getSupressed() method of the thrown exception. Throwable.getSupressed() is a new method added to the Throwable class since 1.7 specifically for this purpose. If there were no suppressed exceptions then this will return an empty array. Reference http://download.java.net/jdk7/docs/technotes/guides/language/try-with-resources.html From http://www.vineetmanohar.com/2011/03/java-7-try-with-auto-closable-resources/
March 24, 2011
by Vineet Manohar
· 49,652 Views
article thumbnail
New Java 7 Feature: String in Switch support
One of the new features added in Java 7 is the capability to switch on a String. With Java 6, or less String color = "red"; if (color.equals("red")) { System.out.println("Color is Red"); } else if (color.equals("green")) { System.out.println("Color is Green"); } else { System.out.println("Color not found"); } String color = "red"; if (color.equals("red")) { System.out.println("Color is Red"); } else if (color.equals("green")) { System.out.println("Color is Green"); } else { System.out.println("Color not found"); } With Java 7: String color = "red"; switch (color) { case "red": System.out.println("Color is Red"); break; case "green": System.out.println("Color is Green"); break; default: System.out.println("Color not found"); } Conclusion The switch statement when used with a String uses the equals() method to compare the given expression to each value in the case statement and is therefore case-sensitive and will throw a NullPointerException if the expression is null. It is a small but useful feature which not only helps us write more readable code but the compiler will likely generate more efficient bytecode as compared to the if-then-else statement. From http://www.vineetmanohar.com/2011/03/new-java-7-feature-string-in-switch-support/
March 22, 2011
by Vineet Manohar
· 106,630 Views · 2 Likes
article thumbnail
Configuring Sonar with Maven
Sonar is an open source web-based application to manage code quality which covers seven axes of code quality as: Architecture and design, comments, duplications, unit tests, complexity, potential bugs and coding rules. Developed in Java and can cover projects in Java, Flex, PHP, PL/SQL, Cobol and Visual Basic 6. It's very efficient to navigate, offering visual reporting and you can follow metrics evolution of your project and combine them. There is an online project called Nemo dedicated to open source projects, as you can see projects like Jetty, Apache Lucene and Apache Tomcat. So, let's config Sonar to work together with Maven. First of all set up Sonar server and other configurations in Maven's settings.xml file: sonar true jdbc:postgresql://localhost/sonar org.postgresql.Driver user password http://localhost:9000 You must to have a Sonar server running and define it in sonar.host.url parameter. In this example I'm using the default Sonar URL, http://localhost:9000 , and you must set user name and password for your database. To install local Sonar Server you can see this link. After that, to execute the code analysers and save results in Sonar database just execute mvn sonar:sonar. You can config Sonar to execute in your CI (Continuous Integration) application. Hudson is a perfect match, because there is a Sonar plugin for it. See the final result below: I prefer Teamcity CI, but there isn't a stable plugin as you can see in compatibility matrix. To resolve this plugin's problem, just add sonar:sonar in the maven command executed by Teamcity. Sonar is an essential tool for your software project to help you evaluating how cohesive your classes are, warning for future problems as code complexity or duplication problems arise, and will help you to have a cleaner code. If you have any question or some difficulties, contact me.
March 21, 2011
by Valdemar Júnior
· 143,704 Views · 2 Likes
article thumbnail
How to watch the file system for changes in Java 7 (JDK 7)
Java 7 uses the underlying file system functionalities to watch the file system for changes. Now, we can watch for events like creation, deletion, modification, and get involved with our own actions. For accomplish this task, we need: • An object implementing the Watchable interface - the Path class is perfect for this job. • A set of events that we are interested in - we will use StandardWatchEventKind which implements the WatchEvent.Kind. • An event modifier that qualifies how a Watchable is registered with a WatchService. • A watcher who watch some watchable – per example, a watcher that watches the File System for changes. The abstract class is java.nio.file.WatchService but we will be using the FileSystem object to create a watcher for the File System. The below example follows the above scenario: import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardWatchEventKind; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.util.List; public class Main { public static void main(String[] args) { //define a folder root Path myDir = Paths.get("D:/data"); try { WatchService watcher = myDir.getFileSystem().newWatchService(); myDir.register(watcher, StandardWatchEventKind.ENTRY_CREATE, StandardWatchEventKind.ENTRY_DELETE, StandardWatchEventKind.ENTRY_MODIFY); WatchKey watckKey = watcher.take(); List> events = watckKey.pollEvents(); for (WatchEvent event : events) { if (event.kind() == StandardWatchEventKind.ENTRY_CREATE) { System.out.println("Created: " + event.context().toString()); } if (event.kind() == StandardWatchEventKind.ENTRY_DELETE) { System.out.println("Delete: " + event.context().toString()); } if (event.kind() == StandardWatchEventKind.ENTRY_MODIFY) { System.out.println("Modify: " + event.context().toString()); } } } catch (Exception e) { System.out.println("Error: " + e.toString()); } } } The FileSystem object and the WatchService can also be created like this: FileSystem fileSystem = FileSystems.getDefault(); WatchService watcher = fileSystem.newWatchService(); And the Path (watchable), what we watch, and register it with the WatchService object like this: Path myDir = fileSystem.getPath("D:/data"); myDir.register(watcher, StandardWatchEventKind.ENTRY_CREATE, StandardWatchEventKind.ENTRY_DELETE, StandardWatchEventKind.ENTRY_MODIFY);
March 17, 2011
by A. Programmer
· 122,052 Views
article thumbnail
2-Way SSL with Java: The Keystore Strikes Back - Part 1
If you start off trying to get to grips with the in-built Java Secure Sockets Extension you're gonna be stunned by the complexity of it all.
March 11, 2011
by Frank Kelly
· 64,390 Views · 7 Likes
article thumbnail
Upgrading to JSF 2
Last week, I spent a few hours upgrading AppFuse from JSF 1.2 to JSF 2.0. In reality, I upgraded from MyFaces 1.2.7 to 2.0.4, but all JSF implementations should be the same, right? All in all, it was a pretty easy upgrade with a few minor AppFuse-specific things. My goal in upgrading was to do the bare minimum to get things working and to leave integration of JSF 2 features for a later date. In addition to upgrading MyFaces, I had to upgrade Tomahawk by changing the dependency's artifactId to tomahawk20. I was also able to remove the following listener from my web.xml: org.apache.myfaces.webapp.StartupServletContextListener After that, I discovered that MyFaces uses a new URI (/javax.faces.resource/) for serving up some of its resource files. I kindly asked Spring Security to ignore these requests by adding the following to my security.xml file. Since JSF 2 includes Facelets by default, I tried removing Facelets as a dependency. After doing this, I received the following error: ERROR [308855416@qtp-120902214-7] ViewHandlerWrapper.fillChain(158) | Error instantiation parent Faces ViewHandler java.lang.ClassNotFoundException: com.sun.facelets.FaceletViewHandler at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50) at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:244) at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230) at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:401) at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:363) at org.ajax4jsf.framework.ViewHandlerWrapper.fillChain(ViewHandlerWrapper.java:144) at org.ajax4jsf.framework.ViewHandlerWrapper.calculateRenderKitId(ViewHandlerWrapper.java:68) at org.apache.myfaces.lifecycle.DefaultRestoreViewSupport.isPostback(DefaultRestoreViewSupport.java:179) at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:113) at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:171) at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189) Figuring this was caused by the following element in my web.xml ... org.ajax4jsf.VIEW_HANDLERS com.sun.facelets.FaceletViewHandler ... I removed it and tried again. This time I received a NoClassDefFoundError: java.lang.NoClassDefFoundError: com/sun/facelets/tag/TagHandler at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) at java.lang.ClassLoader.defineClass(ClassLoader.java:616) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) at java.net.URLClassLoader.defineClass(URLClassLoader.java:283) at java.net.URLClassLoader.access$000(URLClassLoader.java:58) at java.net.URLClassLoader$1.run(URLClassLoader.java:197) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:392) at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:363) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) at org.apache.myfaces.shared_impl.util.ClassUtils.classForName(ClassUtils.java:184) at org.apache.myfaces.view.facelets.util.ReflectionUtil.forName(ReflectionUtil.java:67) Since everything seemed to work with Facelets in the classpath, I decided to save this headache for a later date. I entered two issues in AppFuse's JIRA, one for removing Facelets and one for replacing Ajax4JSF with RichFaces. The next issue I encountered was redirecting from AppFuse's password hint page. The navigation-rule for this page is as follows: navigation-rule> /passwordHint.xhtml success /login With JSF 2.0, the rule changes the URL to /login.xhtml when redirecting (where it was left as /login with 1.2) and it was caught by the security setting in my web.xml that prevents users from viewing raw templates. Protect XHTML Templates *.xhtml To solve this issue, I had to make a couple of changes: Comment out the security-constraint in web.xml and move it to Spring Security's security.xml file. Add a rule to urlrewrite.xml that redirects back to login (since login.xhtml doesn't exist and I'm using extensionless URLs). ^/login.xhtml$ %{context-path}/login After getting the Password Hint feature passing in the browser, I tried running the integration tests (powered by Canoo WebTest). The Password Hint test kept failing with the following error: [ERROR] /Users/mraible/dev/appfuse/web/jsf/src/test/resources/web-tests.xml:51: JavaScript error loading page http://localhost:9876/appfuse-jsf-2.1.0-SNAPSHOT/passwordHint?username=admin: syntax error (http:// localhost:9876/appfuse-jsf-2.1.0-SNAPSHOT/javax.faces.resource/oamSubmit.js.jsf?ln=org.apache.myfaces#122) Figuring this was caused by my hack to submit the form when the page was loaded, I turned to Pretty Faces, which allows you to call a method directly from a URL. After adding the Pretty Faces dependencies to my pom.xml, I created a src/main/webapp/WEB-INF/pretty-config.xml file with the following XML: #{userForm.edit} #{passwordHint.execute} This allowed me to remove both editProfile.xhtml and passwordHint.xhtml, both of which simply auto-submitted forms. At this point, I figured I'd be good to go and ran my integration tests again. The first thing I discovered was that ".jsf" was being tacked onto my pretty URL, most likely by the UrlRewriteFilter. Adding the following to my PasswordHint.java class solved this. if (username.endsWith(".jsf")) { username = username.substring(0, username.indexOf(".jsf")); } The next thing was a cryptic error that took me a while to figure out. DEBUG [1152467051@qtp-144702232-0] PasswordHint.execute(38) | Processing Password Hint... 2011-03-05 05:48:52.471:WARN::/passwordHint/admin com.ocpsoft.pretty.PrettyException: Exception occurred while processing <:#{passwordHint.execute}> null at com.ocpsoft.pretty.faces.beans.ActionExecutor.executeActions(ActionExecutor.java:71) at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.processEvent(PrettyPhaseListener.java:214) at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.afterPhase(PrettyPhaseListener.java:108) at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter(PhaseListenerManager.java:111) at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:185) at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189) Digging into the bowels of MyFaces, I discovered a class was looking for a viewId with an extension and no view-id was being set. Adding the following to the top of my execute() method solved this. getFacesContext().getViewRoot().setViewId("/passwordHint.xhtml"); After making this change, all AppFuse's integration tests are passing and the upgrade seems complete. The only other issues I encountered were logging-related. The first is an error about Tomahawk that doesn't seem to affect anything. Mar 5, 2011 6:44:01 AM com.sun.facelets.compiler.TagLibraryConfig loadImplicit SEVERE: Error Loading Library: jar:file:/Users/mraible/.m2/repository/org/apache/myfaces/tomahawk/tomahawk20/1.1.10/tomahawk20-1.1.10.jar!/META-INF/tomahawk.taglib.xml java.io.IOException: Error parsing [jar:file:/Users/mraible/.m2/repository/org/apache/myfaces/tomahawk/tomahawk20/1.1.10/tomahawk20-1.1.10.jar!/META-INF/tomahawk.taglib.xml]: at com.sun.facelets.compiler.TagLibraryConfig.create(TagLibraryConfig.java:410) at com.sun.facelets.compiler.TagLibraryConfig.loadImplicit(TagLibraryConfig.java:431) at com.sun.facelets.compiler.Compiler.initialize(Compiler.java:87) at com.sun.facelets.compiler.Compiler.compile(Compiler.java:104) The second is excessive logging from MyFaces. As far as I can tell, this is because MyFaces switched to java.util.logging instead of commons logging. With all the frameworks that AppFuse leverages, I think it has all the logging frameworks in its classpath now. I was hoping to fix this by posting a message to the mailing list, but haven't received a reply yet. [WARNING] [talledLocalContainer] Mar 5, 2011 6:50:25 AM org.apache.myfaces.config.annotation.TomcatAnnotationLifecycleProvider newInstance [WARNING] [talledLocalContainer] INFO: Creating instance of org.appfuse.webapp.action.BasePage [WARNING] [talledLocalContainer] Mar 5, 2011 6:50:25 AM org.apache.myfaces.config.annotation.TomcatAnnotationLifecycleProvider destroyInstance [WARNING] [talledLocalContainer] INFO: Destroy instance of org.appfuse.webapp.action.BasePage After successfully upgrading AppFuse, I turned to AppFuse Light, where things were much easier. Now that AppFuse uses JSF 2, I hope to start leveraging some of its new features. If you're yearning to get started with them today, I invite you to grab the source and start integrating them yourself. From http://raibledesigns.com/rd/entry/upgrading_to_jsf_2
March 8, 2011
by Matt Raible
· 20,277 Views · 1 Like
article thumbnail
Java 7: Do we really need <> in the diamond operator?
As you may know, one of new features of upcoming Java 7 will be the diamond operator. Purpose of the diamond operator is to simplify instantiation of generic classes. For example, instead of List p = new ArrayList(); with the diamond operator we can write only List p = new ArrayList<>(); and let compiler infer the value of type argument. Nice simplification. But do we really need to write <>? Isn't new ArrayList() enough? In this article, I will describe the arguments of the <> proponents and explain why I think that these arguments are not very strong. However, I also describe arguments why we need <>. In Java 1.4, we had raw types only: List p = new ArrayList(); Java 5 introduced generics: List p = new ArrayList(); Many types in Java API were generified and even though we can still use generic types as raw types, there is no reason for this in Java 5 or newer. When generics were introduced, raw types were allowed for backward compatibility so that we could gradually and smoothly adopt generics. For example, code in Java 1.4 can be combined with new generic code because raw and generic types are allowed together. This is also expressed in the JLS (4.8 Raw Types): "The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of genericity into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types." Now let's go back to the diamond operator and ask again: "Do we really need <>?". The proponents of the <> syntax say that we need <> to preserve backward compatibility. Let's look at an example from the coin-dev conference: class Foo { Foo(X x) { } Foo get(X x) { return this; } } class Test { void test() { Foo f1 = new Foo(1).get(""); //ok - can pass String where Object is expected Foo f2 = new Foo<>(1).get(""); //fail - cannot pass String where Integer is expected } } This shows the difference between new Foo(1) and new Foo<>(1). Clearly, these two are different and if we changed the semantics of new Foo(1), it would break backward compatibility. But wait. Backward compatibility with what? Isn't line Foo f1 = new Foo(1).get(""); a little suspicious? It uses generic type in the left part and raw type in the right part. Although it is legal, it is probably either omission or malpractice. And its legality is probably only a side effect of "a concession to compatibility of legacy code". Let's go further and look at another example from the coin-dev conference. It shows the difference between raw type and parameterized type with the diamond: public class X { public X(T t) { } public T get() { return null; } public static int f(String s) { return 1; } public static int f(Object o) { return 2; } public static void main(String[] args) { System.out.println(f(new X<>("").get())); System.out.println(f(new X("").get())); } } Let's play with the code a bit. Let's assume that there was a library with the X class: public class X { public X(Object o) { } public Object get() { return null; } } and some code that compiled against this library: public class Client { static int f(String s) { return 1; } static int f(Object o) { return 2; } public static void main(String[] args) { System.out.println(f(new X("").get())); } } Then, the library was generified: public class X { public X(T t) { } public T get() { return null; } } and we compiled the client project against the generified version. Now, if we changed the semantics of new X("") to new X("") (or new X<>("") with the diamond syntax), the code would behave differently. So, the answer to the title question is 'yes'. If we want to stay backward compatible, we need <> and we cannot put new X("") semantically equal to new X<>(""). Another questions are how long can Java evolve and remain compatible with concessions to compatibility and whether newcomers to Java will appreciate this. From http://tronicek.blogspot.com/2011/03/do-we-really-need-in-diamond-operator.html
March 7, 2011
by Zdenek Tronicek
· 59,371 Views · 3 Likes
article thumbnail
Implementing Ajax Authentication using jQuery, Spring Security and HTTPS
I've always had a keen interest in implementing security in webapps. I implemented container-managed authentication (CMA) in AppFuse in 2002, watched Tomcat improve it's implementation in 2003 and implemented Remember Me with CMA in 2004. In 2005, I switched from CMA to Acegi Security (now Spring Security) and never looked back. I've been very happy with Spring Security over the years, but also hope to learn more about Apache Shiro and implementing OAuth to protect JavaScript APIs in the near future. I was recently re-inspired to learn more about security when working on a new feature at Overstock.com. The feature hasn't been released yet, but basically boils down to allowing users to login without leaving a page. For example, if they want to leave a review on a product, they would click a link, be prompted to login, enter their credentials, then continue to leave their review. The login prompt and subsequent review would likely be implemented using a lightbox. While lightboxes are often seen in webapps these days because they look good, it's also possible Lightbox UIs provide a poor user experience. User experience aside, I think it's interesting to see what's required to implement such a feature. To demonstrate how we did it, I whipped up an example using AppFuse Light, jQuery and Spring Security. The source is available in my ajax-login project on GitHub. To begin, I wanted to accomplish a number of things to replicate the Overstock environment: Force HTTPS for authentication. Allow testing HTTPS without installing a certificate locally. Implement a RESTful LoginService that allows users to login. Implement login with Ajax, with the request coming from an insecure page. Forcing HTTPS with Spring Security The first feature was fairly easy to implement thanks to Spring Security. Its configuration supports a requires-channel attribute that can be used for this. I used this to force HTTPS on the "users" page and it subsequently causes the login to be secure. Testing HTTPS without adding a certificate locally After making the above change in security.xml, I had to modify my jWebUnit test to work with SSL. In reality, I didn't have to modify the test, I just had to modify the configuration that ran the test. In my last post, I wrote about adding my 'untrusted' cert to my JVM keystore. For some reason, this works for HttpClient, but not for jWebUnit/HtmlUnit. The good news is I figured out an easier solution - adding the trustStore and trustStore password as system properties to the maven-failsafe-plugin configuration. maven-failsafe-plugin 2.7.2 **/*WebTest.java ${project.build.directory}/ssl.keystore appfuse The disadvantage to doing things this way is you'll have to pass these in as arguments when running unit tests in your IDE. Implementing a LoginService Next, I set about implementing a LoginService as a Spring MVC Controller that returns JSON thanks to the @ResponseBody annotation and Jackson. package org.appfuse.examples.web; import org.appfuse.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/api/login.json") public class LoginService { @Autowired @Qualifier("authenticationManager") AuthenticationManager authenticationManager; @RequestMapping(method = RequestMethod.GET) @ResponseBody public LoginStatus getStatus() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && !auth.getName().equals("anonymousUser") && auth.isAuthenticated()) { return new LoginStatus(true, auth.getName()); } else { return new LoginStatus(false, null); } } @RequestMapping(method = RequestMethod.POST) @ResponseBody public LoginStatus login(@RequestParam("j_username") String username, @RequestParam("j_password") String password) { UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); User details = new User(username); token.setDetails(details); try { Authentication auth = authenticationManager.authenticate(token); SecurityContextHolder.getContext().setAuthentication(auth); return new LoginStatus(auth.isAuthenticated(), auth.getName()); } catch (BadCredentialsException e) { return new LoginStatus(false, null); } } public class LoginStatus { private final boolean loggedIn; private final String username; public LoginStatus(boolean loggedIn, String username) { this.loggedIn = loggedIn; this.username = username; } public boolean isLoggedIn() { return loggedIn; } public String getUsername() { return username; } } } To verify this class worked as expected, I wrote a unit test using JUnit and Mockito. I used Mockito because Overstock is transitioning to it from EasyMock and I've found it very simple to use. package org.appfuse.examples.web; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Matchers; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextImpl; import static org.junit.Assert.*; import static org.mockito.Mockito.*; public class LoginServiceTest { LoginService loginService; AuthenticationManager authenticationManager; @Before public void before() { loginService = new LoginService(); authenticationManager = mock(AuthenticationManager.class); loginService.authenticationManager = authenticationManager; } @After public void after() { SecurityContextHolder.clearContext(); } @Test public void testLoginStatusSuccess() { Authentication auth = new TestingAuthenticationToken("foo", "bar"); auth.setAuthenticated(true); SecurityContext context = new SecurityContextImpl(); context.setAuthentication(auth); SecurityContextHolder.setContext(context); LoginService.LoginStatus status = loginService.getStatus(); assertTrue(status.isLoggedIn()); } @Test public void testLoginStatusFailure() { LoginService.LoginStatus status = loginService.getStatus(); assertFalse(status.isLoggedIn()); } @Test public void testGoodLogin() { Authentication auth = new TestingAuthenticationToken("foo", "bar"); auth.setAuthenticated(true); when(authenticationManager.authenticate(Matchers.anyObject())).thenReturn(auth); LoginService.LoginStatus status = loginService.login("foo", "bar"); assertTrue(status.isLoggedIn()); assertEquals("foo", status.getUsername()); } @Test public void testBadLogin() { Authentication auth = new TestingAuthenticationToken("foo", "bar"); auth.setAuthenticated(false); when(authenticationManager.authenticate(Matchers.anyObject())) .thenThrow(new BadCredentialsException("Bad Credentials")); LoginService.LoginStatus status = loginService.login("foo", "bar"); assertFalse(status.isLoggedIn()); assertEquals(null, status.getUsername()); } } Implement login with Ajax The last feature was the hardest to implement and still isn't fully working as I'd hoped. I used jQuery and jQuery UI to implement a dialog that opens the login page on the same page rather than redirecting to the login page. The "#demo" locator refers to a button in the page. Passing in the "ajax=true" parameter disables SiteMesh decoration on the login page, something that's described in my Ajaxified Body article. var dialog = $(''); $(document).ready(function() { $.get('/login?ajax=true', function(data) { dialog.html(data); dialog.dialog({ autoOpen: false, title: 'Authentication Required' }); }); $('#demo').click(function() { dialog.dialog('open'); // prevent the default action, e.g., following a link return false; }); }); Instead of adding a click handler to a specific id, it's probably better to use a CSS class that indicates authentication is required for a link, or -- even better -- use Ajax to see if the link is secured. The login page then has the following JavaScript to add a click handler to the "login" button that submits the request securely to the LoginService. var getHost = function() { var port = (window.location.port == "8080") ? ":8443" : ""; return ((secure) ? 'https://' : 'http://') + window.location.hostname + port; }; var loginFailed = function(data, status) { $(".error").remove(); $('#username-label').before('Login failed, please try again.'); }; $("#login").live('click', function(e) { e.preventDefault(); $.ajax({url: getHost() + "/api/login.json", type: "POST", data: $("#loginForm").serialize(), success: function(data, status) { if (data.loggedIn) { // success dialog.dialog('close'); location.href= getHost() + '/users'; } else { loginFailed(data); } }, error: loginFailed }); }); The biggest secret to making this all work (the HTTP -> HTTPS communication, which is considered cross-domain), is the window.name Transport and the jQuery plugin that implements it. To make this plugin work with Firefox 3.6, I had to implement a Filter that adds Access-Control headers. A question on Stackoverflow helped me figure this out. public class OptionsHeadersFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET,POST"); response.setHeader("Access-Control-Max-Age", "360"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); chain.doFilter(req, res); } public void init(FilterConfig filterConfig) { } public void destroy() { } } Issues I encountered a number of issues when implementing this in the ajax-login project. If you try to run this with ports (e.g. 8080 and 8443) in your URLs, you'll get a 501 (Not Implemented) response. Removing the ports by fronting with Apache and mod_proxy solves this problem. If you haven't accepted the certificate in your browser, the Ajax request will fail. In the example, I solved this by clicking on the "Users" tab to make a secure request, then going back to the homepage to try and login. The jQuery window.name version 0.9.1 doesn't work with jQuery 1.5.0. The error is "$.httpSuccess function not found." Finally, even though I was able to authenticate successfully, I was unable to make the authentication persist. I tried adding the following to persist the updated SecurityContext to the session, but it doesn't work. I expect the solution is to create a secure JSESSIONID cookie somehow. @Autowired SecurityContextRepository repository; @RequestMapping(method = RequestMethod.POST) @ResponseBody public LoginStatus login(@RequestParam("j_username") String username, @RequestParam("j_password") String password, HttpServletRequest request, HttpServletResponse response) { UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); ... try { Authentication auth = authenticationManager.authenticate(token); SecurityContextHolder.getContext().setAuthentication(auth); // save the updated context to the session repository.saveContext(SecurityContextHolder.getContext(), request, response); return new LoginStatus(auth.isAuthenticated(), auth.getName()); } catch (BadCredentialsException e) { return new LoginStatus(false, null); } } Conclusion This article has shown you how to force HTTPS for login, how to do integration testing with a self-generated certificate, how to implement a LoginService with Spring MVC and Spring Security, as well as how to use jQuery to talk to a service cross-domain with the window.name Transport. While I don't have everything working as much as I'd like, I hope this helps you implement a similar feature in your applications. One thing to be aware of is with lightbox/dialog logins and HTTP -> HTTPS is that users won't see a secure icon in their address bar. If your app has sensitive data, you might want to force https for your entire app. OWASP's Secure Login Pages has a lot of good tips in this area. Update: I've posted a demo of the ajax-login webapp. Thanks to Contegix for hosting the demo and helping obtain/install an SSL certificate so quickly. Update March 24, 2011: Rob Winch figured out how to make this work and sent me a patch. From his comment: The first issue is that Access-Control-Allow-Credentials header must be set to true. This is so that the browser knows it can send and accept cookies. The second issue is that XMLHttpRequest.withCredentials should be set to true. The last change was that in order to allow credentials to work across domains, the Access-Control-Allow-Origin must be a specific value (i.e. it won't work if you use a wildcard). For more information, you can read about it on mozilla's site. I've updated the demo with these changes. Works great now - thanks Rob! From http://raibledesigns.com/rd/entry/implementing_ajax_authentication_using_jquery
February 24, 2011
by Matt Raible
· 89,587 Views
article thumbnail
Spring and Hibernate Application with Zero XML
The Spring framework came up with annotation support since 2.5 version which eases development. Whether the annotation based approach, or XML approach is better, is depends on the project and your personal preference. Let us see how we can write a Simple Application using Spring and Hibernate using annotations, no xml at all. The configuration for JDBC datasource and Hibernate properties: application.properties ################### JDBC Configuration ########################## jdbc.driverClassName=org.hsqldb.jdbcDriver jdbc.url=jdbc:hsqldb:file:db/SivaLabsDB;shutdown=true jdbc.username=sa jdbc.password= ################### Hibernate Configuration ########################## hibernate.dialect=org.hibernate.dialect.HSQLDialect hibernate.show_sql=true hibernate.hbm2ddl.auto=update hibernate.generate_statistics=true We can instantiate ApplicationContext from a Java file using the @Configuration annotation. AppConfig.java package com.sivalabs.springmvc.config; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.core.io.ClassPathResource; /** * @author SivaLabs * */ @Import({RepositoryConfig.class}) @Configuration public class AppConfig { // @Bean public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() { PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); ppc.setLocation(new ClassPathResource("application.properties")); ppc.setIgnoreUnresolvablePlaceholders(true); return ppc; } } Here @Import({RepositoryConfig.class}) is the same as the xml version: package com.sivalabs.springmvc.config; import java.util.HashMap; import java.util.Map; import java.util.Properties; import javax.sql.DataSource; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.orm.hibernate3.HibernateTransactionManager; import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean; import org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener; import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource; import org.springframework.transaction.interceptor.TransactionAttributeSource; import org.springframework.transaction.interceptor.TransactionInterceptor; /** * @author SivaLabs * */ @Configuration public class RepositoryConfig { //${jdbc.driverClassName} @Value("${jdbc.driverClassName}") private String driverClassName; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Value("${hibernate.dialect}") private String hibernateDialect; @Value("${hibernate.show_sql}") private String hibernateShowSql; @Value("${hibernate.hbm2ddl.auto}") private String hibernateHbm2ddlAuto; @Bean() public DataSource getDataSource() { DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setDriverClassName(driverClassName); ds.setUrl(url); ds.setUsername(username); ds.setPassword(password); return ds; } @Bean @Autowired public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) { HibernateTransactionManager htm = new HibernateTransactionManager(); htm.setSessionFactory(sessionFactory); return htm; } @Bean @Autowired public HibernateTemplate getHibernateTemplate(SessionFactory sessionFactory) { HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory); return hibernateTemplate; } @Bean public AnnotationSessionFactoryBean getSessionFactory() { AnnotationSessionFactoryBean asfb = new AnnotationSessionFactoryBean(); asfb.setDataSource(getDataSource()); asfb.setHibernateProperties(getHibernateProperties()); asfb.setPackagesToScan(new String[]{"com.sivalabs"}); return asfb; } @Bean public Properties getHibernateProperties() { Properties properties = new Properties(); properties.put("hibernate.dialect", hibernateDialect); properties.put("hibernate.show_sql", hibernateShowSql); properties.put("hibernate.hbm2ddl.auto", hibernateHbm2ddlAuto); return properties; } } Create an Entity User as follows: package com.sivalabs.springmvc.entities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; /** * @author SivaLabs * */ @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String name; private String address; public User() { } public User(Integer id, String name, String address) { this.id = id; this.name = name; this.address = address; } @Override public String toString() { return "User [address=" + address + ", id=" + id + ", name=" + name+ "]"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } Create UserRepository to perform DB operations using Hibernate. package com.sivalabs.springmvc.repositories; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.sivalabs.springmvc.entities.User; /** * @author SivaLabs * */ @Transactional @Repository public class UserRepository { @Autowired private HibernateTemplate hibernateTemplate; public List getAllUsers() { return this.hibernateTemplate.loadAll(User.class); } public Integer createUser(User user) { User mergeUser = this.hibernateTemplate.merge(user); return mergeUser.getId(); } } Create a UserService class which is responsible for performing User operations. package com.sivalabs.springmvc.services; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.sivalabs.springmvc.entities.User; import com.sivalabs.springmvc.repositories.UserRepository; /** * @author SivaLabs * */ @Service public class UserService { @Autowired private UserRepository userRepository; public List getAllUsers() { return this.userRepository.getAllUsers(); } public Integer createUser(User user) { return this.userRepository.createUser(user); } } Now let us create ApplicationContext from AppConfig.java and test the functionality. package com.sivalabs.test; import java.util.List; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.sivalabs.springmvc.entities.User; import com.sivalabs.springmvc.services.UserService; public class ContainerTest { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.scan("com.sivalabs");//This will load the configured components UserService, UserRepository, ctx.refresh(); System.out.println(ctx); UserService userService = ctx.getBean("userService", UserService.class); List allUser = userService.getAllUsers(); for (User u : allUser) { System.out.println(u); } User user = new User(null, "K.siva reddy", "hyderabad"); Integer id = userService.createUser(user); System.out.println("Newly created User Id="+id); allUser = userService.getAllUsers(); for (User u : allUser) { System.out.println(u); } } } See how application development is much more easier now with Annotations. From : http://sivalabs.blogspot.com/2011/02/springhibernate-application-with-zero.html
February 23, 2011
by Siva Prasad Reddy Katamreddy
· 75,420 Views · 7 Likes
article thumbnail
Java Coding Best Practices: Better Search Implementation
In web applications searching for information based on the selected criteria and displaying the results is a very common requirement. Suppose we need to search users based on their name. The end user will enter the username in the textbox and hit the search button and the user results will be fetched from database and display in a grid. At first this looks simple and we can start to implement it as follows: public class UserSearchAction extends Action { public ActionForward execute(...) { SearchForm sf = (SearchForm)form; String searchName = sf.getSearchName(); UserService userService = new UserService(); List searchResults = userService.search(searchName); //put search results in request and dsplay in JSP } } public class UserService { public List search(String username) { // query the DB and get the results by applying filter on USERNAME column List users = UserDAO.search(username); } } The above implementation works fine for the current requirement. Later client wants to display only 10 rows per page and display a message like "Displaying 1-10 of 35 Users". Now the code need to be changed for the change request. public class UserSearchAction extends Action { public ActionForward execute(...) { SearchForm sf = (SearchForm)form; String searchName = sf.getSearchName(); UserService userService = new UserService(); Map searchResultsMap = userService.search(searchName, start, pageSize); List users = (List)searchResultsMap.get("DATA"); Integer count = (Integer)searchResultsMap.get("COUNT"); //put search results in request and dsplay in JSP } } public class UserService { public Map search(String username, int start, int pageSize) { //Get the total number of results for this criteria int count = UserDAO.searchResultsCount(username); List users = UserDAO.search(username, start, pageSize); // query the DB and get the start to start+pageSize results by applying filter on USERNAME column Map RESULTS_MAP = new HashMap(); RESULTS_MAP.put("DATA",users); RESULTS_MAP.put("COUNT",count); return RESULTS_MAP; } } Later the client wants to give an option to the end user to choose the search type either by UserID or by Username and show the paginated results. Now again the code needs to be changed for the change request. public class UserSearchAction extends Action { public ActionForward execute(...) { SearchForm sf = (SearchForm)form; String searchName = sf.getSearchName(); String searchId = sf.getSearchId(); UserService userService = new UserService(); Map searchCriteriaMap = new HashMap(); //searchCriteriaMap.put("SEARCH_BY","NAME"); searchCriteriaMap.put("SEARCH_BY","ID"); searchCriteriaMap.put("ID",searchId); searchCriteriaMap.put("START",start); searchCriteriaMap.put("PAGESIZE",pageSize); Map searchResultsMap = userService.search(searchCriteriaMap); List users = (List)searchResultsMap.get("DATA"); Integer count = (Integer)searchResultsMap.get("COUNT"); //put search results in request and dsplay in JSP } } public class UserService { public Map search(Map searchCriteriaMap) { return UserDAO.search(searchCriteriaMap); } } public class UserDAO { public Map search(Map searchCriteriaMap) { String SEARCH_BY = (String)searchCriteriaMap.get("SEARCH_BY"); int start = (Integer)searchCriteriaMap.get("START"); int pageSize = (Integer)searchCriteriaMap.get("PAGESIZE"); if("ID".equals(SEARCH_BY)) { int id = (Integer)searchCriteriaMap.get("ID"); //Get the total number of results for this criteria int count = UserDAO.searchResultsCount(id); // query the DB and get the start to start+pageSize results by applying filter on USER_ID column List users = search(id, start, pageSize); } else { String username = (String)searchCriteriaMap.get("USERNAME"); //Get the total number of results for this criteria int count = UserDAO.searchResultsCount(username); // query the DB and get the start to start+pageSize results by applying filter on USERNAME column List users = search(username, start, pageSize); } Map RESULTS_MAP = new HashMap(); RESULTS_MAP.put("DATA",users); RESULTS_MAP.put("COUNT",count); return RESULTS_MAP; } } Finally the code becomes a big mess and completely violates object oriented principles. There are lot of problems with the above code. 1. For each change request the method signatures are changing 2. Code needs to be changed for each enhancement such as adding more search criteria We can design a better object model for this kind of search functionality which is Object Oriented and scalable as follows. A generic SearchCriteria which holds common search criteria like pagination, sorting details. package com.sivalabs.javabp; public abstract class SearchCriteria { private boolean pagination = false; private int pageSize = 25; private String sortOrder = "ASC"; public boolean isPagination() { return pagination; } public void setPagination(boolean pagination) { this.pagination = pagination; } public String getSortOrder() { return sortOrder; } public void setSortOrder(String sortOrder) { this.sortOrder = sortOrder; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } } A generic SearchResults object which holds the actual results and other detials like total available results count, page wise results provider etc. package com.sivalabs.javabp; import java.util.ArrayList; import java.util.List; public abstract class SearchResults { private int totalResults = 0; private int pageSize = 25; private List results = null; public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getTotalResults() { return totalResults; } private void setTotalResults(int totalResults) { this.totalResults = totalResults; } public List getResults() { return results; } public List getResults(int page) { if(page <= 0 || page > this.getNumberOfPages()) { throw new RuntimeException("Page number is zero or there are no that many page results."); } List subList = new ArrayList(); int start = (page -1)*this.getPageSize(); int end = start + this.getPageSize(); if(end > this.results.size()) { end = this.results.size(); } for (int i = start; i < end; i++) { subList.add(this.results.get(i)); } return subList; } public int getNumberOfPages() { if(this.results == null || this.results.size() == 0) { return 0; } return (this.totalResults/this.pageSize)+(this.totalResults%this.pageSize > 0 ? 1: 0); } public void setResults(List aRresults) { if(aRresults == null) { aRresults = new ArrayList(); } this.results = aRresults; this.setTotalResults(this.results.size()); } } A SearchCriteria class specific to User Search. package com.sivalabs.javabp; public class UserSearchCriteria extends SearchCriteria { public enum UserSearchType { BY_ID, BY_NAME }; private UserSearchType searchType = UserSearchType.BY_NAME; private int id; private String username; public UserSearchType getSearchType() { return searchType; } public void setSearchType(UserSearchType searchType) { this.searchType = searchType; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } } A SearchResults class specific to User Search. package com.sivalabs.javabp; import java.text.MessageFormat; public class UserSearchResults extends SearchResults { public static String getDataGridMessage(int start, int end, int total) { return MessageFormat.format("Displaying {0} to {1} Users of {2}", start, end, total); } } UserService takes the SearchCriteria, invokes the DAO and get the results, prepares the UserSearchResults and return it back. package com.sivalabs.javabp; import java.util.ArrayList; import java.util.List; import com.sivalabs.javabp.UserSearchCriteria.UserSearchType; public class UserService { public SearchResults search(UserSearchCriteria searchCriteria) { UserSearchType searchType = searchCriteria.getSearchType(); String sortOrder = searchCriteria.getSortOrder(); System.out.println(searchType+":"+sortOrder); List results = null; if(searchType == UserSearchType.BY_NAME) { //Use hibernate Criteria API to get and sort results based on USERNAME field in sortOrder results = userDAO.searchUsers(...); } else if(searchType == UserSearchType.BY_ID) { //Use hibernate Criteria API to get and sort results based on USER_ID field in sortOrder results = userDAO.searchUsers(...); } UserSearchResults searchResults = new UserSearchResults(); searchResults.setPageSize(searchCriteria.getPageSize()); searchResults.setResults(results); return searchResults; } } package com.sivalabs.javabp; import com.sivalabs.javabp.UserSearchCriteria.UserSearchType; public class TestClient { public static void main(String[] args) { UserSearchCriteria criteria = new UserSearchCriteria(); criteria.setPageSize(3); //criteria.setSearchType(UserSearchType.BY_ID); //criteria.setId(2); criteria.setSearchType(UserSearchType.BY_NAME); criteria.setUsername("s"); UserService userService = new UserService(); SearchResults searchResults = userService.search(criteria); System.out.println(searchResults.getTotalResults()); System.out.println(searchResults.getResults().size()+":"+searchResults.getResults()); System.out.println(searchResults.getResults(1).size()+":"+searchResults.getResults(1)); } } With this approach if we want to add a new criteria like search by EMAIL we can do it as follows: 1. Add BY_EMAIL criteria type to UserSearchType enum 2. Add new property "email" to UserSearchCriteria 3. criteria.setSearchType(UserSearchType.BY_EMAIL); criteria.setEmail("gmail"); 4. In UserService prepare the HibernateCriteria with email filter. Thats it :-) From : http://sivalabs.blogspot.com/2011/02/java-coding-best-practices-better.html
February 9, 2011
by Siva Prasad Reddy Katamreddy
· 61,719 Views · 1 Like
article thumbnail
Introduction to iBatis (MyBatis), An alternative to Hibernate and JDBC
i started to write a new article series about ibatis / mybatis . this is the first article and it will walk you through what is ibatis / mybatis and why you should use it. for those who does not know ibatis / mybatis yet, it is a persistence framework – an alternative to jdbc and hibernate , available for java and .net platforms. i’ve been working with it for almost two years, and i am enjoying it! the first thing you may notice in this and following articles about ibatis/mybatis is that i am using both ibatis and mybatis terms. why? until june 2010, ibatis was under apache license and since then, the framework founders decided to move it to google code and they renamed it to mybatis. the framework is still the same though, it just has a different name now. i gathered some resources, so i am just going to quote them: what is mybatis/ibatis? the mybatis data mapper framework makes it easier to use a relational database with object-oriented applications. mybatis couples objects with stored procedures or sql statements using a xml descriptor. simplicity is the biggest advantage of the mybatis data mapper over object relational mapping tools.to use the mybatis data mapper, you rely on your own objects, xml, and sql. there is little to learn that you don’t already know. with the mybatis data mapper, you have the full power of both sql and stored procedures at your fingertips. ( www.mybatis.org ) ibatis is based on the idea that there is value in relational databases and sql, and that it is a good idea to embrace the industrywide investment in sql. we have experiences whereby the database and even the sql itself have outlived the application source code, and even multiple versions of the source code. in some cases we have seen that an application was rewritten in a different language, but the sql and database remained largely unchanged. it is for such reasons that ibatis does not attempt to hide sql or avoid sql. it is a persistence layer framework that instead embraces sql by making it easier to work with and easier to integrate into modern object-oriented software. these days, there are rumors that databases and sql threaten our object models, but that does not have to be the case. ibatis can help to ensure that it is not. ( ibatis in action book) so… what is ibatis ? a jdbc framework developers write sql, ibatis executes it using jdbc. no more try/catch/finally/try/catch. an sql mapper automatically maps object properties to prepared statement parameters. automatically maps result sets to objects. support for getting rid of n+1 queries. a transaction manager ibatis will provide transaction management for database operations if no other transaction manager is available. ibatis will use external transaction management (spring, ejb cmt, etc.) if available. great integration with spring, but can also be used without spring (the spring folks were early supporters of ibatis). what isn’t ibatis ? an orm does not generate sql does not have a proprietary query language does not know about object identity does not transparently persist objects does not build an object cache essentially, ibatis is a very lightweight persistence solution that gives you most of the semantics of an o/r mapping toolkit, without all the drama. in other words ,ibatis strives to ease the development of data-driven applications by abstracting the low-level details involved in database communication (loading a database driver, obtaining and managing connections, managing transaction semantics, etc.), as well as providing higher-level orm capabilities (automated and configurable mapping of objects to sql calls, data type conversion management, support for static queries as well as dynamic queries based upon an object’s state, mapping of complex joins to complex object graphs, etc.). ibatis simply maps javabeans to sql statements using a very simple xml descriptor. simplicity is the key advantage of ibatis over other frameworks and object relational mapping tools.( http://www.developersbook.com ) who is using ibatis/mybatis? see the list in this link: http://www.apachebookstore.com/confluence/oss/pages/viewpage.action?pageid=25 i think the biggest case is myspace , with millions of users. very nice! this was just an introduction, so in next articles i will show how to create an application using ibatis/mybatis – step-by-step. enjoy! from http://loianegroner.com/2011/02/introduction-to-ibatis-mybatis-an-alternative-to-hibernate-and-jdbc/
February 9, 2011
by Loiane Groner
· 42,658 Views · 5 Likes
article thumbnail
Spring Data with Redis
The Spring Data project provides a solution for accessing data stored in new emerging technologies like NoSQL databases and cloud based services. When we look into the SpringSource git repository we see a lot of spring-data sub-projects: spring-data-commons: common interfaces and utility class for other spring-data projects. spring-data-column: support for column based databases. It has not started yet, but there will be support for Cassandra and HBase spring-data-document: support for document databases. Currently MongoDB and CouchDB are supported. spring-data-graph: support for graph based databases. Currently Neo4j is supported. spring-data-keyvalue: support for key-value databases. Currently Redis and Riak are supported and probably Membase will be supported in future. spring-data-jdbc-ext: JDBC extensions, as example Oracle RAC connection failover is implemented. spring-data-jpa: simplifies JPA based data access layer. I would like to share with you how you can use Redis. The first step is to download it from the redis.io web page. try.redis-db.com is a useful site where we can run Redis commands. It also provides a step by step tutorial. This tutorial shows us all structures that Redis supports (list, set, sorted set and hashes) and some useful commands. A lot of reputable sites use Redis today. After download and unpacking we should compile Redis (version 2.2, the release candidate is the preferable one to use since some commands do not work in version 2.0.4). make sudo make install Once we run these commands we are all set to run the following five commands: redis-benchmark - for benchmarking Redis server redis-check-aof - check the AOF (Aggregate Objective Function), and it can repair that. redis-check-dump - check rdb files for unprocessable opcodes. redis-cli - Redis client. redis-server - Redis server. We can test Redis server. redis-server [1055] 06 Jan 18:19:15 # Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf' [1055] 06 Jan 18:19:15 * Server started, Redis version 2.0.4 [1055] 06 Jan 18:19:15 * The server is now ready to accept connections on port 6379 [1055] 06 Jan 18:19:15 - 0 clients connected (0 slaves), 1074272 bytes in use and Redis client. redis-cli redis> set my-super-key "my-super-value" OK Now we create a simple Java project in order to show how simple a spring-data-redis module really is. mvn archetype:create -DgroupId=info.pietrowski -DpackageName=info.pietrowski.redis -DartifactId=spring-data-redis -Dpackage=jar Next we have to add in pom.xml milestone spring repository, and add spring-data-redis as a dependency. After that all required dependencies will be fetched. Next we create a resources folder under the main folder, and create application.xml which will have all the configuration. We can configure the JedisConnectionFactory, in two different ways, One - we can provide a JedisShardInfo object in shardInfo property. Two - we can provide host (default localhost), port (default 6379), password (default empty) and timeout (default 2000) properties. One thing to keep in mind is that the JedisShardInfo object has precedence and allows to setup weight, but only allows constructor injection. We can setup the factory to use connection pooling by setting the value of the pooling property to 'true' (default). See application.xml comments to see three different way of configuration. Note: There are two different libraries supported: Jedis and JRedis. They have very similar names and both have the same factory name. See the difference: org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionFactory org.springframework.data.keyvalue.redis.connection.jredis.JredisConnectionFactory Similar to what we do in Spring, we configure the template object by providing it with a connection factory. We will perform all the operations through this template object. By default we need to provide only Connection Factory, but there are more properties we can provide: exposeConnection (default false) - if we return real connection or proxy object. keySerializer, hashKeySerializer, valueSerializer, hashValueSerializer (default JdkSerializationRedisSerializer) which delegates serialization to Java serialization mechanism. stringSerializer (default StringRedisSerializer) which is simple String to byte[] (and back) serializer with UTF8 encoding. We are ready to execute some code which will be cooperating with the Redis instance. Spring-Data provides us with two ways of interaction, First is by using the execute method and providing a RedisCallback object. Second is by using *Operations helpers (these will be explained later) When we are using RedisCallback we have access to low level Redis commands, see this list of interfaces (I won't put all the methods here because it is huge list): RedisConnection - gathers all Redis commands plus connection management. RedisCommands - gathers all Redis commands (listed beloved). RedisHashCommands - Hash-specific Redis commands. RedisListCommands - List-specific Redis commands. RedisSetCommands - Set-specific Redis commands. RedisStringCommands - key/value specific Redis commands. RedisTxCommands - Transaction/Batch specific Redis commands. RedisZSetCommands - Sorted Set-specific Redis commands. Check RedisCallbackExample class, this was the hard way and the problem is we have to convert our objects into byte arrays in both directions, the second way is easier. Spring Data provides for us with Operations objects, so we have much more simpler API and all byte<->object conversion is made by serializer we setup (or the default one). Higher level API (you will easily recognize *Operation *Commands equivalents): HashOperations - Redis hash operations. ListOperations - Redis list operations. SetOperations - Redis set operations. ValueOperations - Redis 'string' operations. ZSetOperations - Redis sorted set operations. Most of methods get key as first parameters so we have an even better API for multiple operations on the same key: BoundHashOperations - Redis hash operations for specific key. BoundListOperations - Redis list operations for specific key. BoundSetOperations - Redis set operations for specific key. BoundValueOperations - Redis 'string' operations for specific key. BoundZSetOperations - Redis sorted set operations for specific key. Check RedisCallbackExample class to see some easy examples of *Operations usage. One important thing to mention is that you should use stringSerializers for keys, otherwise you will have problems from other clients, because standard serialization adds class information. Otherwise you end up keys such as: "\xac\xed\x00\x05t\x00\x05atInt" "\xac\xed\x00\x05t\x00\nmySuperKey" "\xac\xed\x00\x05t\x00\bsuperKey" Up until now we have just checked the API for Redis, but Spring Data offers more for us. All the cool stuff is in org.springframework.data.keyvalue.redis.support package and all sub-packages. We have: RedisAtomicInteger - Atomic integer (CAS operation) backed by Redis. RedisAtomicLong - Same as previous for Long. RedisList - Redis extension for List, Queue, Deque, BlockingDeque and BlockingQueue with two additional methods List range(start, end) and RedisList trim(start, end). RedisSet - Redis extension for Set with additional methods: diff, diffAndStore, intersect, intersectAndStore, union, unionAndStore. RedisZSet - Redis extension for SortedSet. Note that Comparator is not applicable here so this interface extends normal Set and provide proper methods similar to SortedSet. RedisMap - Redis extension for Map with additional Long increment(key, delta) method Every interface currently has one Default implementation. Check application-support.xml for examples of configuration and RedisSupportClassesExample for examples of use. There is lot of useful information in the comments as well. Summary The library is a first milestone release so there are minor bugs, the documentation isn't as perfect as we used to and the current version needs no stable Redis server. But this is definitely a great library which allows us to use all this cool NoSQL stuff in a "standard" Spring Data Access manner. Awesome job! This post is only useful if you checkout the code: from bitbucket , for the lazy ones here is spring-data-redis zip file as well. This post is originally from http://pietrowski.info/2011/01/spring-data-redis-tutorial/
February 3, 2011
by Sebastian Pietrowski
· 31,170 Views
article thumbnail
JUnit 4.9 - Class and Suite Level Rules
If you have worked with JUnit Rule API which was introduced in version 4.8 then you might probably also think that they are very useful. For example, there is a Rule called TemporaryFolder which creates files and folder before test is executed and deletes them after the test method finishes(whether test passes or fails). For those who are not familiar with Rule API , a Rule is an alteration in how a test method, or set of methods, is run and reported. Before version 4.9 Rule can only be applied to a test method not to a Test class or JUnit test suite. But with JUnit 4.9 which is not yet released you can use @ClassRule annotation to apply a rule to test class or a test suite. If you want to use JUnit 4.9 download it from JUnit git repository. The @ClassRule annotation can be applied to any public static field of Type org.junit.rules.TestRule. The class level rule can be applied in scenarios where you use normally use @BeforeClass and @AfterClass annotation. Some of the scenarios can be like when you want to start a server or any other external resource before a test class or test suite, or when you want to make sure that your test suite or test class runs within a specified time, etc. The advantage of using class level rule is that they can be reused among different modules and classes. Let's take an example when we want to make sure that our test suite should run within x seconds otherwise test should timeout. As you can see below we TestSuite AllTests runs TestCase1 and TestCase2. I have defined a suite level rule which would make sure that test run in three seconds otherwise suite will fail. Test Suite @RunWith(Suite.class) @SuiteClasses({ TestCase1.class, TestCase2.class }) public class AllTests { @ClassRule public static Timeout timeout = new Timeout(3000); } TestCase 1 public class TestCase1 { @Test public void test1() throws Exception{ Thread.sleep(1000); Assert.assertTrue(true); } } TestCase2 public class TestCase2 { @Test public void test2() throws Exception{ Thread.sleep(1000); Assert.assertTrue(true); } } This is the most important feature which will be released in version 4.9 of JUnit.
January 31, 2011
by Shekhar Gulati
· 37,533 Views
article thumbnail
HOWTO: Partially Clone an SVN Repo to Git, and Work With Branches
I've blogged a few times now about Git (which I pronounce with a hard 'g' a la "get", as it's supposed to be named for Linus Torvalds, a self-described git, but which I've also heard called pronounced with a soft 'g' like "jet"). Either way, I'm finding it way more efficient and less painful than either CVS or SVN combined. So, to continue this series ([1], [2], [3]), here is how (and why) to pull an SVN repo down as a Git repo, but with the omission of old (irrelevant) revisions and branches. Using SVN for SVN repos In days of yore when working with the JBoss Tools and JBoss Developer Studio SVN repos, I would keep a copy of everything in trunk on disk, plus the current active branch (most recent milestone or stable branch maintenance). With all the SVN metadata, this would eat up substantial amounts of disk space but still require network access to pull any old history of files. The two repos were about 2G of space on disk, for each branch. Sure, there's tooling to be able to diff and merge between branches w/o having both branches physically checked out, but nothing beats the ability to place two folders side by side OFFLINE for deep comparisons. So, at times, I would burn as much as 6-8G of disk simply to have a few branches of source for comparison and merging. With my painfullly slow IDE drive, this would grind my machine to a halt, especially when doing any SVN operation or counting files / disk usage. Using Git for SVN repos naively Recently, I started using git-svn to pull the whole JBDS repo into a local Git repo, but it was slow to create and still unwieldy. And the JBoss Tools repo was too large to even create as a Git repo - the operation would run out of memory while processing old revisions of code to play forward. At this point, I was stuck having individual Git repos for each JBoss Tools component (major source folder) in SVN: archives, as, birt, bpel, build, etc. It worked, but replicating it when I needed to create a matching repo-collection for a branch was painful and time-consuming. As well, all the old revision information was eating even more disk than before: jbosstools' trunk as multiple git-svn clones: 6.1G devstudio's trunk as single git-svn clone: 1.3G So, now, instead of a couple Gb per branch, I was at nearly 4x as much disk usage. But at least I could work offline and not deal w/ network-intense activity just to check history or commit a change. Still, far from ideal. Cloning SVN with standard layout & partial history This past week, I discovered two ways to make the git-svn experience at least an order of magnitude better: Standard layout (-s) - this allows your generated Git repo to contain the usual trunk, branches/* and tags/* layout that's present in the source SVN repo. This is a win because it means your repo will contain the branch information so you can easily switch between branches within the same repo on disk. No more remote network access needed! Revision filter (-r) - this allows your generated Git repo to start from a known revision number instead of starting at its birth. Now instead of taking hours to generate, you can get a repo in minutes by excluding irrelevant (ancient) revisions. So, why is this cool? Because now, instead of having 2G of source+metadata to copy when I want to do a local comparison between branches, the size on disk is merely: jbosstools' trunk as single git-svn clone w/ trunk and single branch: 1.3G devstudio's trunk as single git-svn clone w/ trunk and single branch: 0.13G So, not only is the footprint smaller, but the performance is better and I need never do a full clone (or svn checkout) again - instead, I can just copy the existing Git repo, and rebase it to a different branch. Instead of hours, this operation takes seconds (or minutes) and happens without the need for a network connection. Okay, enough blather. Show me the code! Check out the repo, including only the trunk & most recent branch # Figure out the revision number based on when a branch was created, then # from r28571, returns -r28571:HEAD rev=$(svn log --stop-on-copy \ http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x \ | egrep "r[0-9]+" | tail -1 | sed -e "s#\(r[0-9]\+\).\+#-\1:HEAD#") # now, fetch repo starting from the branch's initial commit git svn clone -s $rev http://svn.jboss.org/repos/jbosstools jbosstools_GIT Now you have a repo which contains trunk & a single branch git branch -a # list local (Git) and remote (SVN) branches * master remotes/jbosstools-3.2.x remotes/trunk Switch to the branch git checkout -b local/jbosstools-3.2.x jbosstools-3.2.x # connect a new local branch to remote one Checking out files: 100% (609/609), done. Switched to a new branch 'local/jbosstools-3.2.x' git svn info # verify now working in branch URL: http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x Repository Root: http://svn.jboss.org/repos/jbosstools Switch back to trunk git checkout -b local/trunk trunk # connect a new local branch to remote trunk Switched to a new branch 'local/trunk' git svn info # verify now working in branch URL: http://svn.jboss.org/repos/jbosstools/trunk Repository Root: http://svn.jboss.org/repos/jbosstools Rewind your changes, pull updates from SVN repo, apply your changes; won't work if you have local uncommitted changes git svn rebase Fetch updates from SVN repo (ignoring local changes?) git svn fetch Create a new branch (remotely with SVN) svn copy \ http://svn.jboss.org/repos/jbosstools/branches/jbosstools-3.2.x \ http://svn.jboss.org/repos/jbosstools/branches/some-new-branch From http://divby0.blogspot.com/2011/01/howto-partially-clone-svn-repo-to-git.html
January 28, 2011
by Nick Boldt
· 35,823 Views
article thumbnail
Apache Solr: Get Started, Get Excited!
we've all seen them on various websites. crappy search utilities. they are a constant reminder that search is not something you should take lightly when building a website or application. search is not just google's game anymore. when a java library called lucene was introduced into the apache ecosystem, and then solr was built on top of that, open source developers began to wield some serious power when it came to customizing search features. in this article you'll be introduced to apache solr and a wealth of applications that have been built with it. the content is divided as follows: introduction setup solr applications summary 1. introduction apache solr is an open source search server. it is based on the full text search engine called apache lucene . so basically solr is an http wrapper around an inverted index provided by lucene. an inverted index could be seen as a list of words where each word-entry links to the documents it is contained in. that way getting all documents for the search query "dzone" is a simple 'get' operation. one advantage of solr in enterprise projects is that you don't need any java code, although java itself has to be installed. if you are unsure when to use solr and when lucene, these answers could help. if you need to build your solr index from websites, you should take a look into the open source crawler called apache nutch before creating your own solution. to be convinced that solr is actually used in a lot of enterprise projects, take a look at this amazing list of public projects powered by solr . if you encounter problems then the mailing list or stackoverflow will help you. to make the introduction complete i would like to mention my personal link list and the resources page which lists books, articles and more interesting material. 2. setup solr 2.1. installation as the very first step, you should follow the official tutorial which covers the basic aspects of any search use case: indexing - get the data of any form into solr. examples: json, xml, csv and sql-database. this step creates the inverted index - i.e. it links every term to its documents. querying - ask solr to return the most relevant documents for the users' query to follow the official tutorial you'll have to download java and the latest version of solr here . more information about installation is available at the official description . next you'll have to decide which web server you choose for solr. in the official tutorial, jetty is used, but you can also use tomcat. when you choose tomcat be sure you are setting the utf-8 encoding in the server.xml . i would also research the different versions of solr, which can be quite confusing for beginners: the current stable version is 1.4.1. use this if you need a stable search and don't need one of the latest features. the next stable version of solr will be 3.x the versions 1.5 and 2.x will be skipped in order to reach the same versioning as lucene. version 4.x is the latest development branch. solr 4.x handles advanced features like language detection via tika, spatial search , results grouping (group by field / collapsing), a new "user-facing" query parser ( edismax handler ), near real time indexing, huge fuzzy search performance improvements, sql join-a like feature and more. 2.2. indexing if you've followed the official tutorial you have pushed some xml files into the solr index. this process is called indexing or feeding. there are a lot more possibilities to get data into solr: using the data import handler (dih) is a really powerful language neutral option. it allows you to read from a sql database, from csv, xml files, rss feeds, emails, etc. without any java knowledge. dih handles full-imports and delta-imports. this is necessary when only a small amount of documents were added, updated or deleted. the http interface is used from the post tool, which you have already used in the official tutorial to index xml files. client libraries in different languages also exist. (e.g. for java (solrj) or python ). before indexing you'll have to decide which data fields should be searchable and how the fields should get indexed. for example, when you have a field with html in it, then you can strip irrelevant characters , tokenize the text into 'searchable terms', lower case the terms and finally stem the terms . in contrast, if you would have a field with text in it that should not be interpreted (e.g. urls) you shouldn't tokenize it and use the default field type string. please refer to the official documentation about field and field type definitions in the schema.xml file. when designing an index keep in mind the advice from mauricio : "the document is what you will search for. " for example, if you have tweets and you want to search for similar users, you'll need to setup a user index - created from the tweets. then every document is a user. if you want to search for tweets, then setup a tweet index; then every document is a tweet. of course, you can setup both indices with the multi index options of solr. please also note that there is a project called solr cell which lets you extract the relevant information out of several different document types with the help of tika. 2.3. querying for debugging it is very convenient to use the http interface with a browser to query solr and get back xml. use firefox and the xml will be displayed nicely: you can also use the velocity contribution , a cross-browser tool, which will be covered in more detail in the section about 'search application prototyping' . to query the index you can use the dismax handler or standard query handler . you can filter and sort the results: q=superman&fq=type:book&sort=price asc you can also do a lot more ; one other concept is boosting. in solr you can boost while indexing and while querying. to prefer the terms in the title write: q=title:superman^2 subject:superman when using the dismax request handler write: q=superman&qf=title^2 subject check out all the various query options like fuzzy search , spellcheck query input , facets , collapsing and suffix query support . 3. applications now i will list some interesting use cases for solr - in no particular order. to see how powerful and flexible this open source search server is. 3.1. drupal integration the drupal integration can be seen as generic use case to integrate solr into php projects. for the php integration you have the choice to either use the http interface for querying and retrieving xml or json. or to use the php solr client library . here is a screenshot of a typical faceted search in drupal : for more information about faceted search look into the wiki of solr . more php projects which integrates solr: open source typo3- solr module magento enterprise - solr module . the open source integration is out dated. oxid - solr module . no open source integration available. 3.2. hathi trust the hathi trust project is a nice example that proves solr's ability to search big digital libraries. to quote directly from the article : "... the index for our one million book index is over 200 gigabytes ... so we expect to end up with a two terabyte index for 10 million books" other examples for libraries: vufind - aims to replace opac internet archive national library of australia 3.3. auto suggestions mainly, there are two approaches to implement auto-suggestions (also called auto-completion) with solr: via facets or via ngramfilterfactory . to push it to the extreme you can use a lucene index entirely in ram. this approach is used in a large music shop in germany. live examples for auto suggestions: kaufda.de 3.4. spatial search applications when mentioning spatial search, people have geographical based applications in mind. with solr, this ordinary use case is attainable . some examples for this are : city search - city guides yellow pages kaufda.de spatial search can be useful in many different ways : for bioinformatics, fingerprints search, facial search, etc. (getting the fingerprint of a document is important for duplicate detection). the simplest approach is implemented in jetwick to reduce duplicate tweets, but this yields a performance of o(n) where n is the number of queried terms. this is okay for 10 or less terms, but it can get even better at o(1)! the idea is to use a special hash set to get all similar documents. this technique is called local sensitive hashing . read this nice paper about 'near similarity search and plagiarism analysis' for more information. 3.5. duckduckgo duckduckgo is made with open source and its "zero click" information is done with the help of solr using the dismax query handler: the index for that feature contains 18m documents and has a size of ~12gb. for this case had to tune solr: " i have two requirements that differ a bit from most sites with respect to solr: i generally only show one result, with sometimes a couple below if you click on them. therefore, it was really important that the first result is what people expected. false positives are really bad in 0-click, so i needed a way to not show anything if a match wasn't too relevant. i got around these by a) tweaking dismax and schema and b) adding my own relevancy filter on top that would re-order and not show anything in various situations. " all the rest is done with tuned open source products. to quote gabriel again: "the main results are a hybrid of a lot of things, including external apis, e.g. bing, wolframalpha, yahoo, my own indexes and negative indexes (spam removal), etc. there are a bunch of different types of data i'm working with. " check out the other cool features such as privacy or bang searches . 3.6. clustering support with carrot2 carrot2 is one of the "contributed plugins" of solr. with carrot2 you can support clustering : " clustering is the assignment of a set of observations into subsets (called clusters) so that observations in the same cluster are similar in some sense. " see some research papers regarding clustering here . here is one visual example when applying clustering on the search "pannous" - our company : 3.7. near real time search solr isn't real time yet, but you can tune solr to the point where it becomes near real time, which means that the time ('real time latency') that a document takes to be searchable after it gets indexed is less than 60 seconds even if you need to update frequently. to make this work, you can setup two indices. one write-only index "w" for the indexer and one read-only index "r" for your application. index r refers to the same data directory of w, which has to be defined in the solrconfig.xml of r via: /pathto/indexw/data/ to make sure your users and the r index see the indexed documents of w, you have to trigger an empty commit every 60 seconds: wget -q http://localhost:port/solr/update?stream.body=%3ccommit/%3e -o /dev/null everytime such a commit is triggered a new searcher without any cache entries is created. this can harm performance for visitors hitting the empty cache directly after this commit, but you can fill the cache with static searches with the help of the newsearcher entry in your solrconfig.xml. additionally, the autowarmcount property needs to be tuned, which fills the cache with a newsearcher from old entries. also, take a look at the article 'scaling lucene and solr' , where experts explain in detail what to do with large indices (=> 'sharding') and what to do for high query volume (=> 'replicating'). 3.8. loggly = full text search in logs feeding log files into solr and searching them at near real-time shows that solr can handle massive amounts of data and queries the data quickly. i've setup a simple project where i'm doing similar things , but loggly has done a lot more to make the same task real-time and distributed. you'll need to keep the write index as small as possible otherwise commit time will increase too great. loggly creates a new solr index every 5 minutes and includes this when searching using the distributed capabilities of solr ! they are merging the cores to keep the number of indices small, but this is not as simple as it sounds. watch this video to get some details about their work. 3.9. solandra = solr + cassandra solandra combines solr and the distributed database cassandra , which was created by facebook for its inbox search and then open sourced. at the moment solandra is not intended for production use. there are still some bugs and the distributed limitations of solr apply to solandra too. tthe developers are working very hard to make solandra better. jetwick can now run via solandra just by changing the solrconfig.xml. solandra also has the advantages of being real-time (no optimize, no commit!) and distributed without any major setup involved. the same is true for solr cloud. 3.10. category browsing via facets solr provides facets , which make it easy to show the user some useful filter options like those shown in the "drupal integration" example. like i described earlier , it is even possible to browse through a deep category tree. the main advantage here is that the categories depend on the query. this way the user can further filter the search results with this category tree provided by you. here is an example where this feature is implemented for one of the biggest second hand stores in germany. a click on 'schauspieler' shows its sub-items: other shops: game-change 3.11. jetwick - open twitter search you may have noticed that twitter is using lucene under the hood . twitter has a very extreme use case: over 1,000 tweets per second, over 12,000 queries per second, but the real-time latency is under 10 seconds! however, the relevancy at that volume is often not that good in my opinion. twitter search often contains a lot of duplicates and noise. reducing this was one reason i created jetwick in my spare time. i'm mentioning jetwick here because it makes extreme use of facets which provides all the filters to the user. facets are used for the rss-alike feature (saved searches), the various filters like language and retweet-count on the left, and to get trending terms and links on the right: to make jetwick more scalable i'll need to decide which of the following distribution options to choose: use solr cloud with zookeeper use solandra move from solr to elasticsearch which is also based on apache lucene other examples with a lot of facets: cnet reviews - product reviews. electronics reviews, computer reviews & more. shopper.com - compare prices and shop for computers, cell phones, digital cameras & more. zappos - shoes and clothing. manta.com - find companies. connect with customers. 3.12. plaxo - online address management plaxo.com , which is now owned by comcast, hosts web addresses for more than 40 million people and offers smart search through the addresses - with the help of solr. plaxo is trying to get the latest 'social' information of your contacts through blog posts, tweets, etc. plaxo also tries to reduce duplicates . 3.13. replace fast or google search several users report that they have migrated from a commercial search solution like fast or google search appliance (gsa) to solr (or lucene). the reasons for that migration are different: fast drops linux support and google can make integration problems. the main reason for me is that solr isn't a black box —you can tweak the source code, maintain old versions and fix your bugs more quickly! 3.14. search application prototyping with the help of the already integrated velocity plugin and the data import handler it is possible to create an application prototype for your search within a few hours. the next version of solr makes the use of velocity easier. the gui is available via http://localhost:port/solr/browse if you are a ruby on rails user, you can take a look into flare. to learn more about search application prototyping, check out this video introduction and take a look at these slides. 3.15. solr as a whitelist imagine you are the new google and you have a lot of different types of data to display e.g. 'news', 'video', 'music', 'maps', 'shopping' and much more. some of those types can only be retrieved from some legacy systems and you only want to show the most appropriated types based on your business logic . e.g. a query which contains 'new york' should result in the selection of results from 'maps', but 'new yorker' should prefer results from the 'shopping' type. with solr you can set up such a whitelist-index that will help to decide which type is more important for the search query. for example if you get more or more relevant results for the 'shopping' type then you should prefer results from this type. without the whitelist-index - i.e. having all data in separate indices or systems, would make it nearly impossible to compare the relevancy. the whitelist-index can be used as illustrated in the next steps. 1. query the whitelist-index, 2. decide which data types to display, 3. query the sub-systems and 4. display results from the selected types only. 3.16. future solr is also useful for scientific applications, such as a dna search systems. i believe solr can also be used for completely different alphabets so that you can query nucleotide sequences - instead of words - to get the matching genes and determine which organism the sequence occurs in, something similar to blast . another idea you could harness would be to build a very personalized search. every user can drag and drop their websites of choice and query them afterwards. for example, often i only need stackoverflow, some wikis and some mailing lists with the expected results, but normal web search engines (google, bing, etc.) give me results that are too cluttered. my final idea for a future solr-based app could be a lucene/solr implementation of desktop search. solr's facets would be especially handy to quickly filter different sources (files, folders, bookmarks, man pages, ...). it would be a great way to wade through those extra messy desktops. 4. summary the next time you think about a problem, think about solr! even if you don't know java and even if you know nothing about search: solr should be in your toolbox. solr doesn't only offer professional full text search, it could also add valuable features to your application. some of them i covered in this article, but i'm sure there are still some exciting possibilities waiting for you!
January 25, 2011
by Peter Karussell
· 147,567 Views
article thumbnail
Mock Static Methods using Spring Aspects
I am a Spring framework user for last three years and I have really enjoyed working with Spring. One thing that I am seeing these days is the heavy use of AspectJ in most of SpringSource products. Spring Roo is a RAD tool for Java developers which makes use of AspectJ ITD's for separate compilation units. Spring transaction management and exception translation is also done using Aspectj. There are also numerous other usages of Aspectj in Spring products. In this article, I am going to talk about another cool usage of AspectJ by Spring - Mocking Static Methods. These days most of the developers write unit test cases and it is very common to use any of the mocking libraries like EasyMock, Mockito etc. to mock the external dependencies of a class. Using any of these mocking libraries it is very easy to mock calls to other class instance method. But most of these mocking framework does not provide the facility to mock the calls to static methods. Spring provides you the capability to mock static methods by using Spring Aspects library. In order to use this feature you need to add spring-aspects.jar dependency in your pom.xml. org.springframework spring-aspects 3.0.4.RELEASE Next thing you need to do is to convert your project in to a AspectJ project. If you are using Eclipse or STS(SpringSource Tool Suite) you can do that by right-click your project -> configure -> convert to AspectJ project. STS by default has AspectJ plugin, for eclipse users you need to install AspectJ plugin for above to work. I would recommend using STS for developing Spring based applications. The two aspects and one annotation that is of interest in spring-aspects.jar are : AbstractMethodMockingControl : This is an abstract aspect to enable mocking of methods picked out by a pointcut. All the child aspects need to define mockStaticsTestMethod() and methodToMock() pointcuts. The mockStaticTestMethod() pointcut is used to indicate when mocking should be triggered and methodToMock() pointcut is used to define which method invocations to mock. AnnotationDrivenStaticEntityMockingControl : This is the single implementation of AbstractMethodMockingControl aspect which exists in spring-aspects.jar. This is an annotation-based aspect to use in a test build to enable mocking static methods on Entity classes. In this aspect mockStaticTestMethod() pointcut defines that for classes marked with @MockStaticEntityMethods annotation mocking should be triggered and methodToMock() pointcut defines that all the public static methods in the classes marked with @Entity annotation should be mocked. MockStaticEntityMethods : Annotation to indicate a test class for whose @Test methods static methods on Entity classes should be mocked. The AnnotationDrivenStaticEntityMockingControl provide the facility to mock static methods of any class which is marked with @Entity annotation. But usually we would need to mock static method of classes other than marked with @Entity annotation. The only thing we need to do to make it work is to extend AbstractMethodMockingControl aspect and provide definitions for mockStaticsTestMethod() and methodToMock() pointcuts. For example, lets write an aspect which should mock all the public static methods of classes marked with @Component annotation. package com.shekhar.javalobby; import org.springframework.mock.staticmock.AbstractMethodMockingControl; import org.springframework.stereotype.Component; import org.springframework.mock.staticmock.MockStaticEntityMethods;; public aspect AnnotationDrivenStaticComponentMockingControl extends AbstractMethodMockingControl { public static void playback() { AnnotationDrivenStaticComponentMockingControl.aspectOf().playbackInternal(); } public static void expectReturn(Object retVal) { AnnotationDrivenStaticComponentMockingControl.aspectOf().expectReturnInternal(retVal); } public static void expectThrow(Throwable throwable) { AnnotationDrivenStaticComponentMockingControl.aspectOf().expectThrowInternal(throwable); } protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..)); protected pointcut methodToMock() : execution(public static * (@Component *).*(..)); } The only difference between AnnotationDrivenStaticEntityMockingControl(comes with spring-aspects.jar) and AnnotationDrivenStaticComponentMockingControl(custom that we have written above) is in methodToMock() pointcut. In methodToMock() pointcut we have specified that it should mock all the static methods in any class marked with @Component annotation. Now that we have written the custom aspect lets test it. I have created a simple ExampleService with one static method. This is the method which we want to mock. @Component public class ExampleService implements Service { /** * Reads next record from input */ public String getMessage() { return myName(); } public static String myName() { return "shekhar"; } } This class will return "shekhar" when getMessage() method will be called. Lets test this without mocking package com.shekhar.javalobby; import org.junit.Assert; import org.junit.Test; public class ExampleConfigurationTests { private ExampleService service = new ExampleService(); @Test public void testSimpleProperties() throws Exception { String myName = service.getMessage(); Assert.assertEquals("shekhar", myName); } } This test will work fine. Now let's add mocking to this test class. There are two things that we need to do in our test We need to annotate our test with @MockStaticEntityMethods to indicate that static methods of @Component classes will be mocked. Please note that it is not required to use @MockStaticEntityMethods annotation you can create your own annotation and use that in mockStaticsTestMethod() pointcut. So, I could have created an annotation called @MockStaticComponentMethods and used that in mockStaticsTestMethod() pointcut. But I just reused the @MockStaticEntityMethods annotation. In our test methods we need to first invoke the static method which we want to mock so that it gets recorded. Next we need to set our expectation i.e. what should be returned from the mock and finally we need to call the playback method to stop recording mock calls and enter playback state. To make it more concrete lets apply mocking to the above test import org.junit.Assert; import org.junit.Test; import org.springframework.mock.staticmock.MockStaticEntityMethods; @MockStaticEntityMethods public class ExampleConfigurationTests { private ExampleService service = new ExampleService(); @Test public void testSimpleProperties() throws Exception { ExampleService.myName(); AnnotationDrivenStaticComponentMockingControl.expectReturn("shekhargulati"); AnnotationDrivenStaticComponentMockingControl.playback(); String myName = service.getMessage(); Assert.assertEquals("shekhargulati", myName); } } As you can see we annotated the test class with @MockStaticEntityMethods annotation and in the test method we first recorded the call (ExampleService.myName()), then we set the expectations, then we did the playback and finally called the actual code. In this way you can mock the static method of class.
January 25, 2011
by Shekhar Gulati
· 22,739 Views · 1 Like
  • Previous
  • ...
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • ...
  • 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
×