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
Using a Hibernate Interceptor To Set Audit Trail Properties
In almost every application I've done, the database tables have some kind of audit trail fields. Sometimes this is a separate "audit log" table where all inserts, updates, deletes, and possibly even queries are logged. Other times there are the four typical audit trail fields in each table, for example you might have created_by, created_on, updated_by, and updated_on fields in each table. The goal in the latter case is to update those four fields with the appropriate information as to who created or updated a record and when they did it. Using a simple Hibernate Interceptor this can be accomplished with no changes to your application code (with several assumptions which I'll detail next). In other words, you won't need to and definitely should not be manually setting those audit properties littered around your application code. The basic assumptions I'll make for this simple audit interceptor are that: (1) model objects contain the four audit properties mentioned above, and (2) there is an easy way to obtain the current user's information from anywhere in the code. The first assumption is needed since you need some way to identify which properties constitute the audit trail properties. The second assumption is required because you need some way to obtain the credentials of the person making the change in order to set the createdBy or updatedBy property in your Hibernate Interceptor class. So, for reference purposes, assume you have a (Groovy) base entity like this with the four audit properties: @MappedSuperclassclass BaseEntity implements Serializable { String createdBy Date createdOn String updatedBy Date updatedOn} I'm using the Hibernate ImprovedNamingStrategy so that camel case names are translated to underscored names, e.g. "createdBy" becomes "created_by". Next assume there is a BlogEntry entity class that extends BaseEntity and inherits the audit trail properties: @Entityclass BlogEntry extends BaseEntity { @Id @GeneratedValue (strategy = GenerationType.IDENTITY) Long id @Version Long version String title @Column (name = "entry_text") String text @Temporal (TemporalType.TIMESTAMP) Date publishedOn} To implement the interceptor, we need to implement the aforementioned Interceptor interface. We could do this directly, but it is better to extend EmptyInterceptor so we need only implement the methods we actually care about. Without further ado, here's the implementation (excluding package declaration and imports): class AuditTrailInterceptor extends EmptyInterceptor { boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { setValue(currentState, propertyNames, "updatedBy", UserUtils.getCurrentUsername()) setValue(currentState, propertyNames, "updatedOn", new Date()) true } boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { setValue(state, propertyNames, "createdBy", UserUtils.getCurrentUsername()) setValue(state, propertyNames, "createdOn", new Date()) true } private void setValue(Object[] currentState, String[] propertyNames, String propertyToSet, Object value) { def index = propertyNames.toList().indexOf(propertyToSet) if (index >= 0) { currentState[index] = value } } So what did we do? First, we implemented the onFlushDirty and onSave methods because they are called for SQL updates and inserts, respectively. For example, when a new entity is first saved, the onSave method is called, at which point we want to set the createdBy and properties. And if an existing entity is updated, onFlushDirty is called and we set the updatedBy and updatedOn. Second, we are using the setValue helper method to do the real work. Specfically, the only way to modify the state in a Hibernate Interceptor (that I am aware of anyway) is to dig into the currentState array and change the appropriate value. In order to do that, you first need to trawl through the propertyNames array to find the index of the property you are trying to set. For example, if you are updating a blog entry you need to set the updatedBy and updatedOn properties within the currentState array. For a BlogEntry object, the currentState array might look like this before the update (the updated by and on propertes are both null in this case because the entity was created by Bob but has not been updated yet): { "Bob", 2008-08-27 10:57:19.0, null, null, 2008-08-27 10:57:19.0, "Lorem ipsum...", "My First Blog Entry", 0} You then need to look at the propertyNames array to provide context for what the above data represents: { "createdBy", "createdOn", "updatedBy", "updatedOn", "publishedOn", "text", "title", "version"} So in the above updatedBy is at index 2 and updatedOn is located at index 3. setValue() works by finding the index of the property it needs to set, e.g. "updatedBy," and if the property was found, it changes the value at that index in the currentState array. So for updatedBy at index 2, the following is the equivalent code if we had actually hardcoded the implementation to always expect the audit fields as the first four properties (which is obviously not a great idea): // Equivalent hard-coded code to change "updatedBy" in above example// Don't use in production!currentState[2] = UserUtils.getCurrentUsername() To actually make your interceptor do something, you need to enable it on the Hibernate Session. You can do this in one of several ways. If you are using plain Hibernate (i.e. not with Spring or another framework) you can set the interceptor globally on the SessionFactory, or you can enable it for each Session as in the following example code: // Configure interceptor globally (applies to all Sessions)sessionFactory = new AnnotationConfiguration() .configure() .setNamingStrategy(ImprovedNamingStrategy.INSTANCE) .setInterceptor(new AuditTrailInterceptor()) .buildSessionFactory()// Enable per SessionSession session = getSessionFactory().openSession(new AuditTrailInterceptor()) If you enable the interceptor globally, it must be thread-safe. If you are using Spring you can easily configure a global interceptor on your session factory bean: On the other hand, if you would rather enable the interceptor per session, you either need to use the openSession(Interceptor) method to open your sessions or alternatively implement your own version of CurrentSessionContext to use the getCurrentSession() method in order to set the interceptor. Using getCurrentSession() is preferable anyway since it allows several different classes (e.g. DAOs) to use the same session without needing to explicitly pass the Session object around to each object that needs it. At this point we're done. But, if you know about the Hibernate eventing system (e.g. you can listen for events such as inserts and updates and define event listener classes to respond to those events), you might be wondering why I didn't use that mechanism rather than the Interceptor. The reason is that, to the best of my current knowledge, you cannot alter state of objects in event listeners. So for example you would not be able to change an entity's state in a PreInsertEventListener implementation class. If anyone knows this is incorrect or has implemented it, I'd love to hear about it. Until next time, happy auditing! Originally posted on Scott Leberknight's blog
August 27, 2008
by Scott Leberknight
· 103,595 Views · 2 Likes
article thumbnail
Execute Shell Command From Java
String cmd = "ls -al"; Runtime run = Runtime.getRuntime(); Process pr = run.exec(cmd); pr.waitFor(); BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream())); String line = ""; while ((line=buf.readLine())!=null) { System.out.println(line); }
August 14, 2008
by Snippets Manager
· 106,061 Views · 2 Likes
article thumbnail
Creating SOAP Message Handlers in 3 Simple Steps - Part 1
This tutorial takes a look at SOAP Message handlers and how easy it is to write handlers using JAX-WS 2.0. JAX-WS 2.0 allows both regular Java classes and stateless EJBs(Session beans) to be exposed as web services. The JAX-WS 2.0 is the core specification that defines the web services standard for Java EE 5 specification. JAX-WS 2.0 is an extension of the Java API for XML-RPC (JAX-RPC) 1.0. SOAP message handlers are used to intercept the SOAP message as they make their way from the client to the end-point service and vice-versa. These handlers intercept the SOAP message for both the request and response of the Web Service. If you are familiar with EJB interceptors, handlers are similar to EJB interceptors and are defined in an XML file. A few typical scenarios where you would be using SOAP Message handlers are: to encrypt and decrypt messages, to support logging, caching and in some cases auditing, and in rare cases to provide transaction management as well. So much for the theory. Lets see the three basic steps to use a simple log handler to intercept and print our SOAP messages (request and response). In this tutorial, we are going to expose an EJB 3 stateless session bean as a web service which is simple and can be done by adding the @WebService annotation. So, here comes the source code for the interface as well as the implementation class which is self explanatory: Listing 1: Remote Interface package com.ws;import javax.ejb.Remote;/** * * @author meerasubbarao */@Remotepublic interface HelloWebServiceRemote { String sayHello(String name); } Listing 2: Bean Implementation package com.ws;import javax.ejb.Stateless;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebService;/** * * @author meerasubbarao */@WebService@Statelesspublic class HelloWebServiceBean implements HelloWebServiceRemote { @WebMethod(operationName = "sayHello") public String sayHello(@WebParam(name = "name") String name) { return "Hello " + name; } } You can package the two source files in a jar, deploy to your application server, and test it. Quite simple, right? For this tutorial, I am using GlassFish V2 application server and SoapUI to test my web services. Shown below are the request and response from SoapUI: Now that we know our web services work, lets start writing the message handler, which as I said earlier is just 3 steps. So, what are these SOAP message handlers? They are simple Java classes that can used to modify SOAP messages; both request as well as response. These handlers have access to both the SOAP header as well as the body of the message. Lets move on to create SOAP message handlers: Step 1. Implement the SOAPHandler interface. package com.ws;import java.io.IOException;import java.util.Collections;import java.util.Set;import java.util.logging.Level;import java.util.logging.Logger;import javax.xml.namespace.QName;import javax.xml.soap.SOAPException;import javax.xml.soap.SOAPMessage;import javax.xml.ws.handler.MessageContext;import javax.xml.ws.handler.soap.SOAPHandler;import javax.xml.ws.handler.soap.SOAPMessageContext;/** * * @author meerasubbarao */public class LogMessageHandler implements SOAPHandler { public boolean handleMessage(SOAPMessageContext messageContext) { return true; } public Set getHeaders() { return Collections.EMPTY_SET; } public boolean handleFault(SOAPMessageContext messageContext) { return true; } public void close(MessageContext context) { } The handleMessage() method is invoked for both incoming as well as outgoing messages. Lets add a new method called log() and invoke this method from the handleMessage method. Shown below are both the methods: private void log(SOAPMessageContext messageContext) { SOAPMessage msg = messageContext.getMessage(); //Line 1 try { msg.writeTo(System.out); //Line 3 } catch (SOAPException ex) { Logger.getLogger(LogMessageHandler.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(LogMessageHandler.class.getName()).log(Level.SEVERE, null, ex); } } In line 1, we are retrieving the SOAPMessage from the message context. Line 3 will print the incoming and outgoing messages in our GlassFish console. Invoke this method from within the handleMessage() as shown: public boolean handleMessage(SOAPMessageContext messageContext) { log(messageContext); return true; } Step 2: Create the XML file for the Handler Chain. Create this XML file in the same package as the web service with the name LogMessage_handler.xml. com.ws.LogMessageHandler com.ws.LogMessageHandler Lets take a close look at the various elements used above: 1. is the root element that will contain a list of all handler chains that are defined for the Web Service. 2. The child element of the element lists all the handlers in the handler chain. 3. Within the element is defined the , each handler element must in turn specify the name and also the fully qualified name of the Java class that implements the handler. If you have more than one handler, specify each one of them within the handler-chain element. Step 3: Invoking the Handler The @HandlerChain annotation is used to define a set of handlers that are invoked in response to a SOAP message. So, within our HelloWebServiceBean implementaion, you need to make a simple change to invoke the Log Handler as shown below in Line 1: package com.ws;import javax.ejb.Stateless;import javax.jws.HandlerChain;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebService;/** * * @author meerasubbarao */@WebService@Stateless@HandlerChain(file = "LogMessage_handler.xml") // Line 1public class HelloWebServiceBean implements HelloWebServiceRemote { @WebMethod(operationName = "sayHello") public String sayHello(@WebParam(name = "name") String name) { return "Hello " + name; } } We added the annotation for the handlers; lets recompile, repackage and redeploy the application. Now invoke the web service from SoapUI and see if it works. If it does, we should be able to see the request and response logged in our GlassFish console window. Here is the final output: **RemoteBusinessJndiName: com.ws.CustomerManagerRemote; remoteBusIntf: com.ws.CustomerManagerRemote LDR5010: All ejb(s) of [EJBWebServices] loaded successfully! Javalobby Hello Javalobby In this article, we saw how simple and easy it was to create and use SOAP Handlers to intercept request and response of SOAP messages. We implemented the SOAPHandler interface, wrote minimal XML to define the handler chain, and finally added one simple annotation to the web service implementation class. We were also able to test these web service using SoapUI. In Part 2 of this series, we will see how to actually parse the SOAP Headers, and also use multiple handlers. Stay tuned for more..
August 13, 2008
by Meera Subbarao
· 86,128 Views
article thumbnail
OFX4J: Java Web Service APIs for Interfacing with Financial Institutions
OFX4J has been released! OFX4J is a Java implementation of Open Financial Exchange, which defines web service APIs for interfacing with financial institutions. The OFX4J library includes support for both client-side and server-side implementations of both version 1 and version 2 of the OFX specification. As an example, let's consider the OFX4J client-side interface, which can be used, for example, to download your financial transactions from your bank or credit card institution. OFX4J comes with an initial set of financial institution data, but you can load your own if your financial institution isn't included. Consider the following code for downloading your bank statement: //the financial institution data is loaded or created //the FinancialInstitutionData interface defines //what is required to interface with a financial institution. FinancialInstitutionData data = ...; FinancialInstitutionService service = new FinancialInstitutionServiceImpl(); FinancialInstitution fi = service.getFinancialInstitution(data); //get a reference to a specific bank account at the FI BankAccountDetails bankAccountDetails = new BankAccountDetails(); //routing number to the bank. bankAccountDetails.setRoutingNumber("11111111"); //bank account number. bankAccountDetails.setAccountNumber("1234-5678"); //it's a checking account bankAccountDetails.setAccountType(AccountType.CHECKING); BankAccount bankAccount = fi.loadBankAccount(bankAccountDetails, "username", "password"); //read the statement (transaction details, etc.) // for a given time period. Date startDate = ...; Date endDate = ...; AccountStatement statement = bankAccount.readStatement(startDate, endDate); // get a reference to a specific credit card // account at your FI CreditCardAccountDetails ccDetails = new CreditCardAccountDetails(); ccDetails.setAccountNumber("1234-567890-1111"); CreditCardAccount ccAccount = fi.loadCreditCardAccount(ccDetails, "username", "password"); // read the statement (transaction details, etc.) // for a given time period. Date startDate = ...; Date endDate = ...; AccountStatement statement = ccAccount.readStatement(startDate, endDate); Server-side development is just straightforward, consisting of implementing a simple interface and publishing it with a simple Servlet implementation: /** * Basic interface for an OFX server. * * @author Ryan Heaton */ public interface OFXServer { /** * Get a response for the given request. * * @param request The request. * @return The response. */ ResponseEnvelope getResponse(RequestEnvelope request); }
July 22, 2008
by Ryan Heaton
· 3,924 Views
article thumbnail
Introducing Caching for Java Applications (Part 1)
Caching may address new challenges when developing performing applications.
July 17, 2008
by Slava Imeshev
· 141,280 Views · 7 Likes
article thumbnail
Understanding the GWT Compiler
[img_assist|nid=3421|title=|desc=|link=url|url=http://www.manning.com/affiliate/idevaffiliate.php?id|align=left|width=208|height=388]The GWT compiler is the fulcrum of GWT. The entire approach GWT takes, encapsulating browser differences and compiling JavaScript from Java, is made possible by the design and architecture of the compiler. The GWT compiler compiles Java into JavaScript, but it’s important to understand that the compiler doesn’t compile Java the same way javac does. The GWT compiler is really a Java source to JavaScript source translator. The GWT compiler needs hints about the work that it must perform partly because it operates from source. These hints come in the form of the module descriptor, the marker interfaces that denote serializable types, the JavaDoc style annotations used in serializable types for collections, and more. Although these hints may sometimes seem like overkill, they’re needed because the GWT compiler will optimize your application at compile time. This doesn’t just mean compressing the JavaScript naming to the shortest possible form; it also includes pruning unused classes, and even methods and attributes, from your code. The core engineering goal of the GWT compiler is summarized succinctly: you pay for what you use. This optimization offers big advantages over other Ajax/JavaScript libraries, where a large initial download of a library may be needed even if just a few elements are used. In Java, serialization marked by the java.io.Serializable interface is handled at the bytecode level. GWT examines your code and only provides serialization for the classes where you explicitly need it. Like GWTShell, GWTCompiler supports a set of useful command-line options. They’re described in table 1: GWTCompiler [-logLevel level] [-gen dir] [-out dir] [-treeLogger] [-style style] module Table 1 GWTCompiler parameters Option Description -logLevel The logging level: ERROR, WARN, INFO, TRACE, DEBUG, SPAM, or ALL -gen The directory into which generated files will be written for review -out The directory to which output files will be written (defaults to the current directory) -treeLogger Logs output in a graphical tree view -style The script output style: OBF[uscated], PRETTY, or DETAILED(defaults to OBF) module The name of the module to compile The -gen and -out command-line options specify where generated files and the final output directory are to be, respectively. And -logLevel, as in the case of GWTShell, is used to indicate the level of logging performed during the compilation. You can even use the -treeLogger option to bring up a window to view the hierarchical logging information you would see in the shell’s console display. The GWT compiler supports several styles of output, each of use in looking at how your code is executing in the browser. JavaScript output style When working with the GWT compiler, you can use several values with the -style command-line option to control what the generated JavaScript looks like. These options are as follows: OBF - Obfuscated mode. This is a non-human-readable, compressed version suitable for production use. PRETTY - Pretty-printed JavaScript with meaningful names. DETAILED - Pretty-printed JavaScript with fully qualified names. To give you an idea of what these options mean, let’s look at examples of java.lang.StringBuffer compiled in the three different modes. First, in listing 1, is the obfuscated mode. Listing 1 StringBuffer in obfuscated compilation function A0(){this.B0();return this.js[0];}function C0(){if(this.js.length > 1){this.js = [this.js.join('')];this.length = this.js[0].length;}function D0(E0){this.js = [E0];this.length = E0.length;}function Ez(F0,a1){return F0.yx(yZ(a1));}function yB(b1){c1(b1);return b1;}function c1(d1){d1.e1('');}function zB(){}_ = zB.prototype = new f();_.yx = w0;_.vB = A0;_.B0 = C0;_.e1 = D0;_.i = 'java.lang.StringBuffer';_.j = 75;function f1(){f1 = a;g1 = new iX();h1 = new iX();return window;} Obfuscated mode is just that. This is intended to be the final compiled version of your application, which has names compressed and whitespace cleaned. Next is the pretty mode, shown in listing 2. Listing 2 StringBuffer in pretty compilation function _append2(_toAppend){ var _last = this.js.length - 1; var _lastLength = this.js[_last].length; if (this.length > _lastLength * _lastLength) { this.js[_last] = this.js[_last] + _toAppend; } else { this.js.push(_toAppend); } this.length += _toAppend.length; return this;}function _toString0(){ this._normalize(); return this.js[0];}// Some stuff omitted.function _$StringBuffer(_this$static){ _$assign(_this$static); return _this$static;}function _$assign(_this$static){ _this$static._assign0('');}function _StringBuffer(){}_ = _StringBuffer.prototype = new _Object();_._append = _append2;_._toString = _toString0;_._normalize = _normalize0;_._assign0 = _assign;_._typeName = 'java.lang.StringBuffer'; _._typeId = 75; append() becomes _append2() to avoid collision> toString() becomes _toString0()> _typeName holds name of original Java class> Pretty mode is useful for debugging as method names are somewhat preserved. However, collisions are resolved with suffixes, as the _toString0() method name shows . Last, we have the detailed mode, as displayed in listing 3. Listing 3 StringBuffer in detailed compilation function java_lang_StringBuffer_append__Ljava_lang _String_2(toAppend){ var last = this.js.length - 1; var lastLength = this.js[last].length; if (this.length > lastLength * lastLength) { this.js[last] = this.js[last] + toAppend; } else { this.js.push(toAppend); } this.length += toAppend.length; return this;}function java_lang_StringBuffer_toString__(){ this.normalize__(); return this.js[0];}function java_lang_StringBuffer_normalize__(){ if (this.js.length > 1) { this.js = [this.js.join('')]; this.length = this.js[0].length; }// . . . some stuff omittedfunction java_lang_StringBuffer(){}_ = java_lang_StringBuffer.prototype = new java_lang_Object();_.append__Ljava_lang_String_2 = java_lang_StringBuffer_append__Ljava_lang_String_2;_.toString__ = java_lang_StringBuffer_toString__;_.normalize__ = java_lang_StringBuffer_normalize__;_.assign__Ljava_lang_String_2 = java_lang_StringBuffer_assign__Ljava_lang_String_2;_.java_lang_Object_typeName = 'java.lang.StringBuffer';_.java_lang_Object_typeId = 75; Detailed mode preserves the full class name, as well as the method name #2. For overloaded methods, the signature of the method is encoded into the name, as in the case of the append() method #1. There are some important concepts to grasp about this compilation structure, especially given the way GWT interacts with native JavaScript, through the JavaScript Native Interface (JSNI), which will be discussed in the section on the compiler lifecycle. The names of your classes and methods in their JavaScript form aren’t guaranteed, even for different compilations of the same application. Use of the special syntax provided with JSNI will let you invoke known JavaScript objects from your Java code and invoke your compiled Java classes from within JavaScript; but you can’t freely invoke your JavaScript when using obfuscated style, predictably. This imposes certain limitations on your development: If you intend to expose your JavaScript API for external use, you need to create the references for calls into GWT code using JSNI registrations. You can’t rely on JavaScript naming in an object hash to give you java.lang.reflect.* type functionality, since the naming of methods isn’t reliable. Although they’re rare, you should consider potential conflicts with other JavaScript libraries you’re including in your page, especially if you’re publishing using the PRETTY setting. In addition to being aware of the available compiler output options and how they affect your application, you should also be familiar with a few other compiler nuances. Additional compiler nuances Currently, the compiler is limited to J2SE 1.4 syntactical structures. This means that exposing generics or annotations in your GWT projects can cause problems. Other options are available for many of the purposes for which you might wish to use annotations. For example, you can often use JavaDoc-style annotations, to which GWT provides its own extensions. Along with the J2SE 1.4 limitations, you also need to keep in mind the limited subset of Java classes that are supported in the GWT Java Runtime Environment (JRE) emulation library. This library is growing, and there are third-party extensions, but you need to be aware of the constructs you can use in client-side GWT code—the complete JRE you’re accustomed to isn’t available. Of course, one of the great advantages of GWT’s approach to compiling JavaScript from plain Java is that you get to leverage your existing toolbox while building your Ajax application. When you execute the hosted mode browser, you’re running regularly compiled Java classes. This, again, means you can use all the standard Java tooling—static analysis tools, debuggers, IDEs, and the like. These tools are useful for writing any code, but they become even more important in the GWT world because cleaning up your code means less transfer time to high-latency clients. Also, because JavaScript is a fairly slow execution environment, such cleanup can have a large impact on ultimate performance. The GWT compiler helps by optimizing the JavaScript it emits to include only classes and methods that are on the execution stack of your module and by using native browser functions where possible, but you should always keep the nature of JavaScript in mind. To that end, we’ll now take a closer look at the lifecycle of a GWT compilation and at how this JavaScript is generated. The compiler lifecycle When the GWT compiler runs, it goes through several stages for building the final compiled project. In these stages, the need for the GWT module definition file becomes clear. First, the compiler identifies which combinations of files need to be built. Then, it generates any client-side code using the generator metaprogramming model. Last, it produces the final output. We’ll look at each of these steps in the compiler lifecycle in more detail. dentifying build combinations One of the great strengths of GWT is that it builds specific versions of the application, each exactly targeted to what the client needs (user agent, locale, so on). This keeps the final download, and the operational overhead at the client level, very lean. A particular build combination is defined in the GWT module definition using a tag. This establishes a base set of values that are used for the build. The first and very obvious property is the user agent that the JavaScript will be built for. Listing 4 shows the core GWT UserAgent module definition. Listing 4 The GWT UserAgent definition = 6000) { return "ie6"; } } } else if (ua.indexOf("gecko") != -1) { var result = /rv:([0-9]+)\.([0-9]+)/.exec(ua); if (result && result.length == 3) { if (makeVersion(result) >= 1008) return "gecko1_8"; } return "gecko"; } return "unknown";]]> Here the tag establishes a number of different builds that the final compiler will output #1: in this case, ie6, gecko, gecko1_8, safari, and opera. This means each of these will be processed as a build of the final JavaScript that GWT emits. GWT can then switch implementations of classes based on properties using the tag in the module definition. As the GWT application starts up, the JavaScript snippet contained within the tag determines which of these implementations is used #2. This snippet is built into the startup script that determines which compiled artifact is loaded by the client. At the core of the GWT UI classes is the DOM class. This gets replaced based on the user.agent property. Listing 5 shows this definition. Listing 5 Changing the DOM implementation by UserAgent Now you can see the usefulness of this system. The basic DOM class is implemented with the same interface for each of the browsers, providing a core set of operations on which cross-platform code can easily be written. Classes replaced in this method can’t be instantiated with simple constructors but must be created using the GWT.create() method. In practice, the DOM object is a singleton exposing static methods that are called by applications, so this GWT.create() invocation is still invisible. This is an important point to remember if you want to provide alternative implementations based on compile-time settings in your application. You can also define your own properties and property providers for switching implementations. We have found that doing this for different runtime settings can be useful. For example, we have defined debug, test, and production settings, and replacing some functionality in the application based on this property can help smooth development in certain cases. This technique of identifying build combinations and then spinning off into specific implementations during the compile process is known in GWT terms as deferred binding. The GWT documentation sums this approach up as “the Google Web Toolkit answer to Java reflection.” Dynamic loading of classes (dynamic binding) isn’t truly available in a JavaScript environment, so GWT provides another way. For example, obj.getClass().getName() isn’t available, but GWT.getTypeName(obj) is. The same is true for Class.forName("MyClass"), which has GWT.create(MyClass) as a counterpart. By using deferred binding, the GWT compiler can figure out every possible variation, or axis, for every type and feature needed at compile time. Then, at runtime, the correct permutation for the context in use can be downloaded and run. Remember, though, that each axis you add becomes a combinatory compile. If you use 4 languages and 4 browser versions, you must compile 16 final versions of the application; and if you use several runtime settings, you end up with many more combinations in the mix. This concept is depicted in figure 1. Figure 1 Multiple versions of a GWT application are created by the compiler for each axis or variant application property, such as user agent and locale. Compiling a new monolithic version of your application for each axis doesn’t affect your end users negatively. Rather, this technique allows each user to download only the exact application version they need, without taking any unused portion along for the ride. This is beneficial for users, but it slows compile time considerably, and it can be a painful point for developers. Reducing the compile variants to speed up compile time Even though GWT compile time can be long, keep in mind that the end result for users is well optimized. Also, the GWT module system allows you to tweak the compile time variants for the situation. During day-to-day development, you may want to use the tag in your module definition to confine the compile to a single language, or single browser version, to speed up the compile step. Another important use for module properties is in code generation, which is the next step of the compilation process. Generating code GWT’s compiler includes a code generation or metaprogramming facility that allows you to generate code based on module properties at compile time. Perhaps the best example is the internationalization support. The i18n module defines several no-method interfaces that you extend to define Constants, Messages (which include in-text replacement), or Dictionary classes (which extract values from the HTML host page). The implementations of each of these classes are built at compile time using the code generation facility, producing a lean, custom version of your application in each language. The i18n module does this through the tag, which lets you add additional iterative values to a property in a module. Listing 6 demonstrates the use of this concept to add French and Italian support to a GWT application. Listing 6 Defining French and Italian using extend-property When an application inherits the i18n module, the GWT compiler searches for interfaces that extend one of the i18n classes and generates an implementation for the class based on a resource bundle matching the language code. This is accomplished via the tag in the i18n module definition. Listing 7 shows this along with the tag, which is used for establishing which language will be needed at runtime. Listing 7 The i18n module’s locale property declarations = 0) { var language = args.substring(startLang); var begin = language.indexOf("=") + 1; var end = language.indexOf("&"); if (end == -1) { end = language.length; } locale = language.substring(begin, end); } } if (locale == null) { // Look for the locale on the web page locale = __gwt_getMetaProperty("locale") } if (locale == null) { return "default"; } while (!__gwt_isKnownPropertyValue("locale", locale)) { var lastIndex = locale.lastIndexOf("_"); if (lastIndex == -1) { locale = "default"; break; } else { locale = locale.substring(0,lastIndex); } } return locale; } catch(e) { alert("Unexpected exception in locale "+ "detection, using default: " + e); return "default"; } ]]> The module first establishes the locale property. This is the property we extended in listing 6 to include it and fr. Next, the property provider is defined . The value is checked first as a parameter on the request URL in the format locale=xx and then as a tag on the host page in the format ; finally, it defaults to default. The last step is to define a generator class. Here it tells the compiler to generate implementations of all classes that extend or implement Localizable with the LocalizableGenerator . This class writes out Java files that implement the appropriate interfaces for each of the user’s defined Constants, Messages, or Dictionary classes. Notice that, to this point, nowhere have we dealt specifically with JavaScript outside of small snippets in the modules. GWT will produce the JavaScript in the final step. Producing output You can do a great deal from Java with the GWT module system, but you may need to get down to JavaScript-level implementations at some point if you wish to integrate existing JavaScript or extend or add lower-level components. For this, GWT includes JSNI. This is a special syntax that allows you to define method implementations on a Java class using JavaScript. Listing 8 shows a simple JSNI method. Listing 8 A simple JSNI method public class Alert { public Alert() { super(); } public native void alert(String message) /*-{ alert(message); }-*/; } In this listing, we first define the alert() method using the native keyword. Much like the Java Native Interface (JNI) in regular Java, this indicates that we are going to use a native implementation of this method. Unlike JNI, the implementation lives right in the Java file, surrounded by a special /*- -*/ comment syntax. To reference Java code from JavaScript implementations, syntax similar to JNI is provided. Figure 2 shows the structure of calls back into Java from JavaScript. Figure 2 The structure of JSNI call syntax GWT reuses the JNI typing system to reference Java types. The final compiled output will have synthetic names for methods and classes, so the use of this syntax is important to ensure that GWT knows how to direct a call from JavaScript. In the final step of the compilation process, GWT takes all the Java files, whether provided or generated, and the JSNI method implementations, and examines the call tree, pruning unused methods and attributes. Then it transforms all of this into a number of unique JavaScript files, targeted very specifically at each needed axis. This minimizes both code download time and execution time in the client. Although this complex compilation process can be time consuming for the developer, it ensures that the end user’s experience is the best it can possibly be for the application that is being built. This article is excerpted from Chapter 1 of GWT in Practice, by Robert Cooper and Charlie Collins, and published in May 2008 by Manning Publications.
June 17, 2008
by Schalk Neethling
· 126,363 Views
article thumbnail
Protect Your Java Code From Reverse Engineering
If you are developing a Java application, it is important to understand that the Java class files can be easily reverse-engineered using Java decompilers. In this article, let us explore how a Java class file is reverse-engineered and how to protect your source code from this. Java source code is compiled to a class file that contains byte code. The Java Virtual Machine needs only the class file for execution. The problem is that the class file can easily be decompiled into the original source code using Java decompiler tools. The best solution to prevent reverse-engineering is to obfuscate the class file so that is will be very hard to reverse-engineer. According to the dictionary Obfuscate means “to make obscure or unclear”. That is exactly what lot of Java obfuscator tools do as explained below. Decompile Java class file. Before understanding how to obfuscate the java code, let us first try to understand how someone can reverse engineer your java application. Following 3 steps explains how a class file is reverse engineered to the original java source code. 1. Create HelloWorld.java as shown below. public class HelloWorld { public static void main (String args[]) { String userMessage = “Hello World!”; int userCount = 100; userCount = userCount + 1; System.out.println(userMessage); System.out.println(userCount); } } 2. Compile HelloWorld.java program and execute it to make sure it works properly. $ javac HelloWorld.java $ java HelloWorld Hello World! 101 Java class file contains only byte code. If you try to view a class file, it will be non-readable as shown below. $ vi HelloWorld.class Ãþº¾^@^@^@2^@ ^@^G^@^P^H^@^Q ^@^R^@^S ^@^T^@^V^G^@^W^G^@^X^A^@^F^A^@^C()V^A^@^DCode^A^@^OLineNumberTable ^A^@^Dmain^A^@^V([Ljava/lang/String;)V^A^@ SourceFile^A^@^OHelloWorld.java^L^@^H^@ ^A^@^LHello World!^G^@^Y^L^@^Z^@^[^G^@^\^L^@^]^@^^^L^@^]^@^_^A^@ HelloWorld^A^@^Pjava/lang/Object^A^@^Pjava/lang/System^A^@^Cout^A^@^ULjava/io/PrintStream;^A ^@^Sjava/io/PrintStream^A^@^Gprintln^A^@^U(Ljava/lang/String;)V^A^@^D(I)V^@!^@^F^@^G^@^@^@^@^@^B^@^A^@^H^@ ^@^A^@ 3. Decompile HelloWorld.class file and view the original source. For this demonstration let us use Jad decompiler which is free for non-commercial use. Download the appropriate jad for your platform. Use jad to reverse-engineer the HelloWorld.class file to get the original source as shown below. $ unzip jadls158.zip $ ./jad HelloWorld.class Parsing HelloWorld.class... Generating HelloWorld.jad $ vi HelloWorld.jad Obfuscate your java application Let us review how to obfuscate and protect your source code from reverse engineering using ProGuard a free GPL licensed software. 1. Download and Install ProGuard $ cd /home/jsmith $ unzip proguard4.2.zip 2. Create a proguard config file Create myconfig.pro that contains all the information about your java application. -injar : Specify the location of your jar file. i.e the compiled java application that contains the class files -outjar: This is the jar file proguard will create after obfuscation. This will contain all the mangled, obscure naming convention of the methods and variables in the class file if someone tries to reverse engineer. -printmapping: ProGurad outputs all the mapping information in this file for your reference. -keep: Indicate the class files or the methods that you don’t want ProGuard to obfuscate. For e.g. mypkg.MainAppFrame contains the entry point for the application with the main class, which will not get obfuscated in this example. $ cat myconfig.pro -injars /home/jsmith/myapp.jar -outjars /home/jsmith/myapp-obfuscated.jar This is the obfuscated jar file -libraryjars /usr/java/jdk1.5.0_14/jre/lib/rt.jar -printmapping proguard.map -verbose -keep public class mypkg.MainAppFrame 3. Execute ProGuard. $ cd /home/jsmith/proguard4.2/lib $ java -jar proguard.jar @myconfig.pro This creates the following two files: myapp-obfuscated.jar: Contains the obfuscated class files of your application. You can distribute this without having to worry about someone reverse engineering your application easily. proguard.map: This file contains the mapping information for your reference. 4. Sample proguard.map file This is a sample proguard.map file that indicates the original name of the java source objects (classfile, methods, variable etc.) and the new obfuscated name. myapp.AppToolBar -> myapp.ae: javax.swing.JButton btnNew -> d javax.swing.JButton btnOpen -> e 5. Sample java source code (myapp.AppToolBar) before obfuscation. btnNew = changeButtonLabel(btnNew, language.getText("new")); btnOpen = changeButtonLabel(btnOpen, language.getText("open")); 6. Sample java source code that was decompiled from the class file (myapp.ae) after obfuscation. d = a(d, n.a("new")); e = a(e, n.a("open")); You can see that the line “btnNew = changeButtonLabel(btnNew, language.getText(”new”));” got translated to “d = a(d, n.a(”new”));”, by the ProGuard, which will not make any sense to someone who is using java decompiler tools to reverse engineer the class file. From http://www.thegeekstuff.com
June 17, 2008
by Ramesh Natarajan
· 109,547 Views · 4 Likes
article thumbnail
Hibernate - Dynamic Table Routing
I have been searching for a method to dynamically route objects to databases at runtime using Hibernate and recently I found a solution which fit the bill.
June 13, 2008
by alvin sd
· 60,210 Views · 3 Likes
article thumbnail
Java Reporting With Jasper Reports - Part 2
Welcome back to Java Reporting series. For those who didn't read the introductory article; have a look before we get started. Today we're going to have a quick tour in JasperReport architecture, development lifecycle, report definition files, and finally we're going to set up our environment and start work in a sample application. Architecture As shown in the above figure JasperReports architecture is based on declarative XML fileswhich by convention have an extension of jrxml that contains the report layout. A lot of third-party design tools were produced to generate your jrxml file in a smooth way (like iReport or JasperAssistant)Design file is supposed to be filled by report's result which is fetched from database, XML files, Java collection, Comma-separated values or Models. Jasper can communicate with those data-sources and more, it can merge any number of data-sources together and manipulates the results of any combinations. This communication goes through JDBC, JNDI, XQuery, EJBQL, Hibernate or existing Oracle PL/SQL. You also can define your own data-source class and pass it to jasper engine directly. After defining your report design layout in jrxml format and determining your data source(s) jasper engine does the rest of work. It compiles your design file and fills it with results fetched from data-source and generates your report to the chosen exporting format (PDF, Excel, HTML, XML, RTF, TXT …, etc.) Report Definition file structure (jrxml): Jasper design file –jrxml- contains the following elements: : the root element.
June 13, 2008
by Hossam Sadik
· 293,340 Views
article thumbnail
Hibernate - Tuning Queries Using Paging, Batch Size, and Fetch Joins
This article covers queries - in particular a tuning test case and the relations between simple queries, join fetch queries, paging query results, and batch size. Paging the Query Results I will start with a short introduction about paging in EJB3: To support paging the EJB3 Query interface defines the following two methods: setMaxResults - sets the number of maximum rows to retrieve from the database setFirstResult - sets the first row to retrieve For example if our GUI displays a list of customers and we have 500,000 customers (database rows) in out database we wouldn't like to display all 500,000 records is one view (even if we put performance considerations aside - nobody can do anything with a list of 500,000 rows). The GUI design would usually include paging - we break the list of records to display into logical pages (for example 100 records per page) and the user can navigate between pages (same as Google's results navigator down the search page). When using the paging support it is important to remember that the query has to be sorted otherwise we can't be sure that when fetching the "next page" it will really be the next page (since in the absence of the 'order by' clause form a SQL query the order in which rows are fetch is unpredictable). Here is a sample use, for fetching the first tow pages of 100 rows each: Query q = entityManager.createQuery("select c from Customer c order by c.id"); q.setFirstResult(0).setMaxResults(100); .... next page ... Query q = entityManager.createQuery("select c from Customer c order by c.id"); q.setFirstResult(100).setMaxResults(100); This is a simple API and it's important (for performance) to remember using it when we need to fetch only parts of the results. Test Case Description This test cased is based on a real tuning I did for an application, I just changed the class names to Customer and Order. Let's assume that I have a Customer entity with a set of orders (lazily fetched - but it happens in eager fetch as well) and we need to: Fetch customers and their orders Do it in a "paging mode" - 100 customers per page Tuning Requirement #1 - Fetch Customers and Their Orders There are two possibilities to perform this kind of fetch: Simple select: select c from customer c order by c.id Join fetch: select distinct c from Customer c left outer join fetch c.orders order by c.id The simple select is as simple as it can be, we load a list of customers with a proxy collection in their orders field. The orders collection will be filled with data once I access it (for example c.getOrders().getSize() ). The 'join fetch' means that we want to fetch an association as an integral part of the query execution. The joined fetched entities (in the example above: c.orders) must be part of an association that is referenced by an entity returned from the query (in the example above: c). The 'join fetch' is one of the tools used for improving queries performance (see more in here). The Hibernate core documentations explains that "a 'fetch' join allows associations or collections of values to be initialized along with their parent objects, using a single select" (see here). I have in my database 18,998 customer records, each with few orders. Let's compare execution time for the two queries. My code looks the same for both queries (except of the query itself), I execute the query, then I iterate the results checking the size of of each customer orders collection and print the execution time and number of records fetch (as a sanity for the query syntax): Query q = entityManager.createQuery(queryStr); long a = System.currentTimeMillis(); List l = q.getResultList(); for (Customer c : l) { c.getOrders().size(); } long b = System.currentTimeMillis(); System.out.println("Execution time: " + (b - a)+ "; Number of records fetch: " + l.size() ); And to the numbers (avg. 3 executions): Simple select: 24,984 millis Join fetch: 1,219 millis The join fetch query execution time was 20 times faster(!) than the simple query. The reason is obvious, using the join fetch select I had only one round trip to the database. While using a simple select I had to fetch the customers (1 round trip to the database) and each time I accessed a collection I had another round trip (that's 18,998 additional round trips!). The winner is 'join fetch'. But does it? wait for the next one - the paging... Tuning Requirement #2 - Use Paging The second requirement was to do it in paging - each page will have 100 customers (so we will have 18,900/100+1 pages - the last page has 98 customers). So let's change the code above a little bit: Query q = entityManager.createQuery(queryStr); q.setFirstResult(pageNum*100).setMaxResults(100); long a = System.currentTimeMillis(); List l = q.getResultList(); for (Customer c : l) { c.getOrders().size(); } long b = System.currentTimeMillis(); System.out.println("Execution time: " + (b - a)+ "; Number of records fetch: " + l.size() ); I added the second line which limits the query result to a specific page with up to 100 records per page. And the numbers are (avg. 3 executions): Simple select: 328 millis Join fetch: 1,660 millis The wheel has turned over. Why? First a quote from the EJB3 Persistence specification: "The effect of applying setMaxResults or setFirstResult to a query involving fetch joins over collections is undefined" (section 3.6.1 - Query Interface) We could have stopped here but it is interesting to understand the issue and to see what Hibernate does. To implement the paging features Hibernate delegates the work to the database using its syntax to limit the number of records fetched by the query. Each database has its own proprietary syntax for limiting the number of fetched records, some examples: Postgres uses LIMIT and OFFSET Oracle has rownum MySQL uses its version of LIMIT and OFFSET MSSQL has the TOP keyword in the select and so on The important thing to remember here is meaning of such limit: the database returns a subset of the query result. So if we asked for the first 100 customers which their names contain 'Eyal' the outcome is logically the same as building a table in memory out of all customers that match the criteria and take from there the first 100 rows. And here is the catch: if the query with the limit includes a join clause for a collection than the first 100 row in the "logical table" will not necessarily be the first 100 customers. the outcome of the join might duplicate customers in the "logical tables" but the database doesn't aware or care about that - it performs operations on tables not on objects!. For example think of the extreme case, the customer 'Eyal' has 100 orders. The query will return 100 rows, hibernate will identify that all belong to the same customer and return only one Customer as the query result - this is not what we were asking for. This also works, of course, the other way around. If a customer had more than 100 orders and the result set size was limited to 100 rots the orders collection would not contain all of the customer's orders. To deal with that limitation Hibernate actually doesn't issue an SQL statement with a LIMIT clause. Instead it fetches all of the records and performs the paging in memory. This explains why using the 'join fetch' statement with paging took more than the one without paging - the delta is the in-memory paging done by Hibernate. If you look at Hibernate logs you will find the next warning issued by Hibernate: WARNING: firstResult/maxResults specified with collection fetch; applying in memory! Final Tuning - BatchSize Does it mean that in the case of paging we shouldn't use a join fetch? usually it does (unless your page size is very close to the actual number of records). But even if you use a simple select this is a classic case for using the @BatchSize annotation. If my session/entity manager has 100 customers attached to it than, be default, for each first access to one of the customers' order collection Hibernate will issue a SQL statement to fill that collection. At the end I will execute 100 statements to fetch 100 collections. You can see it in the log: Hibernate: /* select c from Customer c order by c.id */ select customer0_.id as id0_, customer0_.ccNumber as ccNumber0_, customer0_.name as name0_, customer0_.fixedDiscount as fixedDis5_0_, customer0_.DTYPE as DTYPE0_ from CUSTOMERS customer0_ order by customer0_.id limit ? offset ? Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id=? Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id=? Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id=? ............ Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id=? Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id=? Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id=? The @BatchSize annotation can be used to define how many identical associations to populate in a single database query. If the session has 100 customers attached to it and the mapping of the 'orders' collection is annotated with @BatchSize of size n. It means that whenever Hibernate needs to populate a lazy orders collection it checks the session and if it has more customers which their orders collections need to be populated it fetches up to n collections. Example: if we had 100 customers and the batch size was set to 16 when iterating over the customers to get their number of orders hibernate will go to the database only 7 times (6 times to fetch 16 collections and one more time to fetch the 4 remaining collections - see the sample below). If our batch size was set to 50 it would go only twice. @OneToMany(mappedBy="customer",cascade=CascadeType.ALL, fetch=FetchType.LAZY) @BatchSize(size=16) private Set orders = new HashSet(); And in the log: Hibernate: /* select c from Customer c order by c.id */ select customer0_.id as id0_, customer0_.ccNumber as ccNumber0_, customer0_.name as name0_, customer0_.fixedDiscount as fixedDis5_0_, customer0_.DTYPE as DTYPE0_ from CUSTOMERS customer0_ order by customer0_.id limit ? offset ? Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: /* load one-to-many par2.Customer.orders */ select orders0_.customer_id as customer4_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.customer_id as customer4_1_0_, orders0_.description as descript2_1_0_, orders0_.orderId as orderId1_0_ from ORDERS orders0_ where orders0_.customer_id in (?, ?, ?, ?) Back to our test case. In my example setting the batch size to 100 looks like a nice tuning opportunity. And indeed when setting it to 100 the total execution time dropped to 188 millis (that's an 132 (!!!) times faster than worse result we had). The batch size can also be set globally by setting the hibernate.default_batch_fetch_size property for the session factory. From http://www.jroller.com/eyallupu/
June 9, 2008
by Eyal Lupu
· 256,448 Views · 7 Likes
article thumbnail
Java Concurrency: Read / Write Locks
Jakob has done a great series on Java Concurrency - check out the first 14 articles at his blog. Going forward, we're delighted to announce that you'll also be able to follow the series here on JavaLobby. A read / write lock is more sophisticated lock than the Lock implementations shown in the text Locks in Java. Imagine you have an application that reads and writes some resource, but writing it is not done as much as reading it is. Two threads reading the same resource does not cause problems for each other, so multiple threads that want to read the resource are granted access at the same time, overlapping. But, if a single thread wants to write to the resource, no other reads nor writes must be in progress at the same time. To solve this problem of allowing multiple readers but only one writer, you will need a read / write lock. Java 5 comes with read / write lock implementations in the java.util.concurrent package. Even so, it may still be useful to know the theory behind their implementation. Here is a list of the topics covered in this text: Read / Write Lock Java Implementation First let's summarize the conditions for getting read and write access to the resource: Read Access If no threads are writing, and no threads have requested write access. Write Access If no threads are reading or writing. If a thread wants to read the resource, it is okay as long as no threads are writing to it, and no threads have requested write access to the resource. By up-prioritizing write-access requests we assume that write requests are more important than read-requests. Besides, if reads are what happens most often, and we did not up-prioritize writes, starvation could occur. Threads requesting write access would be blocked until all readers had unlocked the ReadWriteLock. If new threads were constantly granted read access the thread waiting for write access would remain blocked indefinately, resulting in starvation. Therefore a thread can only be granted read access if no thread has currently locked the ReadWriteLock for writing, or requested it locked for writing. A thread that wants write access to the resource can be granted so when no threads are reading nor writing to the resource. It doesn't matter how many threads have requested write access or in what sequence, unless you want to guarantee fairness between threads requesting write access. With these simple rules in mind we can implement a ReadWriteLock as shown below: public class ReadWriteLock{ private int readers = 0; private int writers = 0; private int writeRequests = 0; public synchronized void lockRead() throws InterruptedException{ while(writers > 0 || writeRequests > 0){ wait(); } readers++; } public synchronized void unlockRead(){ readers--; notifyAll(); } public synchronized void lockWrite() throws InterruptedException{ writeRequests++; while(readers > 0 || writers > 0){ wait(); } writeRequests--; writers++; } public synchronized void unlockWrite() throws InterruptedException{ writers--; notifyAll(); } } The ReadWriteLock has two lock methods and two unlock methods. One lock and unlock method for read access and one lock and unlock for write access. The rules for read access are implemented in the lockRead() method. All threads get read access unless there is a thread with write access, or one or more threads have requested write access. The rules for write access are implemented in the lockWrite() method. A thread that wants write access starts out by requesting write access (writeRequests++). Then it will check if it can actually get write access. A thread can get write access if there are no threads with read access to the resource, and no threads with write access to the resource. How many threads have requested write access doesn't matter. It is worth noting that both unlockRead() and unlockWrite() calls notifyAll() rather than notify(). To explain why that is, imagine the following situation: Inside the ReadWriteLock there are threads waiting for read access, and threads waiting for write access. If a thread awakened by notify() was a read access thread, it would be put back to waiting because there are threads waiting for write access. However, none of the threads awaiting write access are awakened, so nothing more happens. No threads gain neither read nor write access. By calling noftifyAll() all waiting threads are awakened and check if they can get the desired access. Calling notifyAll() also has another advantage. If multiple threads are waiting for read access and none for write access, and unlockWrite() is called, all threads waiting for read access are granted read access at once - not one by one. Read / Write Lock Reentrance The ReadWriteLock class shown earlier is not reentrant. If a thread that has write access requests it again, it will block because there is already one writer - itself. Furthermore, consider this case: Thread 1 gets read access. Thread 2 requests write access but is blocked because there is one reader. Thread 1 re-requests read access (re-enters the lock), but is blocked because there is a write request In this situation the previous ReadWriteLock would lock up - a situation similar to deadlock. No threads requesting neither read nor write access would be granted so. To make the ReadWriteLock reentrant it is necessary to make a few changes. Reentrance for readers and writers will be dealt with separately. Read Reentrance To make the ReadWriteLock reentrant for readers we will first establish the rules for read reentrance: A thread is granted read reentrance if it can get read access (no writers or write requests), or if it already has read access (regardless of write requests). To determine if a thread has read access already a reference to each thread granted read access is kept in a Map along with how many times it has acquired read lock. When determing if read access can be granted this Map will be checked for a reference to the calling thread. Here is how the lockRead() and unlockRead() methods looks after that change: public class ReadWriteLock{ private Map readingThreads = new HashMap(); private int writers = 0; private int writeRequests = 0; public synchronized void lockRead() throws InterruptedException{ Thread callingThread = Thread.currentThread(); while(! canGrantReadAccess(callingThread)){ wait(); } readingThreads.put(callingThread, (getAccessCount(callingThread) + 1)); } public synchronized void unlockRead(){ Thread callingThread = Thread.currentThread(); int accessCount = getAccessCount(callingThread); if(accessCount == 1){ readingThreads.remove(callingThread); } else { readingThreads.put(callingThread, (accessCount -1)); } notifyAll(); } private boolean canGrantReadAccess(Thread callingThread){ if(writers > 0) return false; if(isReader(callingThread) return true; if(writeRequests > 0) return false; return true; } private int getReadAccessCount(Thread callingThread){ Integer accessCount = readingThreads.get(callingThread); if(accessCount == null) return 0; return accessCount.intValue(); } private boolean isReader(Thread callingThread){ return readers.get(callingThread) != null; } } As you can see read reentrance is only granted if no threads are currently writing to the resource. As you can see, if the calling thread already has read access this takes precedence over any writeRequests. Write Reentrance Write reentrance is granted only if the thread has already write access. Here is how the lockWrite() and unlockWrite() methods look after that little change: public class ReadWriteLock{ private Map<Thread, Integer> readingThreads = new HashMap<Thread, Integer>(); private int writeAccesses = 0; private int writeRequests = 0; private Thread writingThread = null; public synchronized void lockWrite() throws InterruptedException{ writeRequests++; Thread callingThread = Thread.currentThread(); while(! canGrantWriteAccess(callingThread)){ wait(); } writeRequests--; writeAccesses++; writingThread = callingThread; } public synchronized void unlockWrite() throws InterruptedException{ writeAccesses--; if(writeAccesses == 0){ writingThread = null; } notifyAll(); } private boolean canGrantWriteAccess(Thread callingThread){ if(hasReaders()) return false; if(writingThread == null) return true; if(writingThread != callingThread) return false; return true; } private boolean hasReaders(){ return readingThreads.size() > 0; } } Notice how the thread currently holding the write lock is now taken into account when determining if the calling thread can get write access. Read to Write Reentrance Sometimes it is necessary for a thread that have read access to also obtain write access. For this to be allowed the thread must be the only reader. To achieve this the writeLock() method should be changed a bit. Here is what it would look like: public class ReadWriteLock{ private Map readingThreads = new HashMap(); private int writeAccesses = 0; private int writeRequests = 0; private Thread writingThread = null; public synchronized void lockWrite() throws InterruptedException{ writeRequests++; Thread callingThread = Thread.currentThread(); while(! canGrantWriteAccess(callingThread)){ wait(); } writeRequests--; writeAccesses++; writingThread = callingThread; } public synchronized void unlockWrite() throws InterruptedException{ writeAccesses--; if(writeAccesses == 0){ writingThread = null; } notifyAll(); } private boolean canGrantWriteAccess(Thread callingThread){ if(isOnlyReader(callingThread)) return true; if(hasReaders()) return false; if(writingThread == null) return true; if(writingThread != callingThread) return false; return true; } private boolean hasReaders(){ return readingThreads.size() > 0; } private boolean isOnlyReader(Thread thread){ return readers == 1 && readingThreads.get(callingThread) != null; } } Now the ReadWriteLock class is read-to-write access reentrant. Write to Read Reentrance Sometimes a thread that has write access needs read access too. A writer should always be granted read access if requested. If a thread has read access no other threads can have read nor write access, so it is not dangerous. Here is how the canGrantReadAccess() method will look with that change: public class ReadWriteLock{ private boolean canGrantReadAccess(Thread callingThread){ if(isWriter(callingThread)) return true; if(writingThread != null) return false; if(isReader(callingThread) return true; if(writeRequests > 0) return false; return true; } } Fully Reentrant ReadWriteLock Below is the fully reentran ReadWriteLock implementation. I have made a few refactorings to the access conditions to make them easier to read, and thereby easier to convince yourself that they are correct. public class ReadWriteLock{ private Map readingThreads = new HashMap(); private int writeAccesses = 0; private int writeRequests = 0; private Thread writingThread = null; public synchronized void lockRead() throws InterruptedException{ Thread callingThread = Thread.currentThread(); while(! canGrantReadAccess(callingThread)){ wait(); } readingThreads.put(callingThread, (getReadAccessCount(callingThread) + 1)); } private boolean canGrantReadAccess(Thread callingThread){ if( isWriter(callingThread) ) return true; if( hasWriter() ) return false; if( isReader(callingThread) ) return true; if( hasWriteRequests() ) return false; return true; } public synchronized void unlockRead(){ Thread callingThread = Thread.currentThread(); if(!isReader(callingThread)){ throw new IllegalMonitorStateException("Calling Thread does not" + " hold a read lock on this ReadWriteLock"); } int accessCount = getReadAccessCount(callingThread); if(accessCount == 1){ readingThreads.remove(callingThread); } else { readingThreads.put(callingThread, (accessCount -1)); } notifyAll(); } public synchronized void lockWrite() throws InterruptedException{ writeRequests++; Thread callingThread = Thread.currentThread(); while(! canGrantWriteAccess(callingThread)){ wait(); } writeRequests--; writeAccesses++; writingThread = callingThread; } public synchronized void unlockWrite() throws InterruptedException{ if(!isWriter(Thread.currentThread()){ throw new IllegalMonitorStateException("Calling Thread does not" + " hold the write lock on this ReadWriteLock"); } writeAccesses--; if(writeAccesses == 0){ writingThread = null; } notifyAll(); } private boolean canGrantWriteAccess(Thread callingThread){ if(isOnlyReader(callingThread)) return true; if(hasReaders()) return false; if(writingThread == null) return true; if(!isWriter(callingThread)) return false; return true; } private int getReadAccessCount(Thread callingThread){ Integer accessCount = readingThreads.get(callingThread); if(accessCount == null) return 0; return accessCount.intValue(); } private boolean hasReaders(){ return readingThreads.size() > 0; } private boolean isReader(Thread callingThread){ return readingThreads.get(callingThread) != null; } private boolean isOnlyReader(Thread callingThread){ return readingThreads.size() == 1 && readingThreads.get(callingThread) != null; } private boolean hasWriter(){ return writingThread != null; } private boolean isWriter(Thread callingThread){ return writingThread == callingThread; } private boolean hasWriteRequests(){ return this.writeRequests > 0; } } Calling unlock() From a finally-clause When guarding a critical section with a ReadWriteLock, and the critical section may throw exceptions, it is important to call the readUnlock() and writeUnlock() methods from inside a finally-clause. Doing so makes sure that the ReadWriteLock is unlocked so other threads can lock it. Here is an example: lock.lockWrite(); try{ //do critical section code, which may throw exception } finally { lock.unlockWrite(); } This little construct makes sure that the ReadWriteLock is unlocked in case an exception is thrown from the code in the critical section. If unlockWrite() was not called from inside a finally-clause, and an exception was thrown from the critical section, the ReadWriteLock would remain write locked forever, causing all threads calling lockRead() or lockWrite() on that ReadWriteLock instance to halt indefinately. The only thing that could unlock the ReadWriteLockagain would be if the ReadWriteLock is reentrant, and the thread that had it locked when the exception was thrown, later succeeds in locking it, executing the critical section and calling unlockWrite() again afterwards. That would unlock the ReadWriteLock again. But why wait for that to happen, if it happens? Calling unlockWrite() from a finally-clause is a much more robust solution.
June 9, 2008
by Jakob Jenkov
· 79,362 Views
article thumbnail
Spring Batch - Hello World
This is an introductory tutorial to Spring Batch. It does not aim to provide a complete guide to the framework but rather to facilitate the first contact. Spring Batch is quite rich in functionalities, and this is basically how I started learning it. Keep in mind that we will only be scratching the surface. Before we start All the examples will have the lofty task of printing "Hello World!" though in different ways. They were developed with Spring Batch 1.0. I'll provide a Maven 2 project and I'll run the examples with Maven but of course it is not a requirement to work with Spring Batch. Spring Batch in 2 Words Fortunately, Spring Batch model objects have self-explanatory names. Let's try to enumerate the most important and to link them together: A batch Job is composed of one or more Steps. A JobInstance represents a given Job, parametrized with a set of typed properties called JobParameters. Each run of of a JobInstance is a JobExecution. Imagine a job reading entries from a data base and generating an xml representation of it and then doing some clean-up. We have a Job composed of 2 steps: reading/writing and clean-up. If we parametrize this job by the date of the generated data then our Friday the 13th job is a JobInstance. Each time we run this instance (if a failure occurs for instance) is a JobExecution. This model gives a great flexibility regarding how jobs are launched and run. This naturally brings us to launching jobs with their job parameters, which is the responsibility of JobLauncher. Finally, various objects in the framework require a JobRepository to store runtime information related to the batch execution. In fact, Spring Batch domain model is much more elaborate but this will suffice for our purpose. Well, it took more than 2 words and I feel compelled to make a joke about it, but I won't. So let's move to the next section. Common Objects For each job, we will use a separate xml context definition file. However there is a number of common objects that we will need recurrently. I will group them in an applicationContext.xml which will be imported from within job definitions. Let's go through these common objects: JobLauncher JobLaunchers are responsible for starting a Job with a given job parameters. The provided implementation, SimpleJobLauncher, relies on a TaskExecutor to launch the jobs. If no specific TaskExecutor is set then a SyncTaskExecutor is used. JobRepository We will use the SimpleJobRepository implementation which requires a set of execution Daos to store its information. JobInstanceDao, JobExecutionDao, StepExecutionDao These data access objects are used by SimpleJobRepository to store execution related information. Two sets of implementations are provided by Spring Batch: Map based (in-memory) and Jdbc based. In a real application the Jdbc variants are more suitable but we will use the simpler in-memory alternative in this example. Here's our applicationContext.xml: Hello World with Tasklets A tasklet is an object containing any custom logic to be executed as a part of a job. Tasklets are built by implementing the Tasklet interface. Let's implement a simple tasklet that simply prints a message: public class PrintTasklet implements Tasklet{ private String message; public void setMessage(String message) { this.message = message; } public ExitStatus execute() throws Exception { System.out.print(message); return ExitStatus.FINISHED; } } Notice that the execute method returns an ExitStatus to indicate the status of the execution of the tasklet. We will define our first job now in a simpleJob.xml application context. We will use the SimpleJob implementation which executes all of its steps sequentailly. In order to plug a tasklet into a job, we need a TaskletStep. I also added an abstract bean definition for tasklet steps in order to simplify the configuration: ; Running the Job Now we need something to kick-start the execution of our jobs. Spring Batch provides a convenient class to achieve that from the command line: CommandLineJobRunner. In its simplest form this class takes 2 arguments: the xml application context containing the job to launch and the bean id of that job. It naturally requires a JobLauncher to be configured in the application context. Here's how to launch the job with Maven. Of course, it can be run with the java command directly (you need to specify the class path then): mvn exec:java -Dexec.mainClass=org.springframework.batch.core.launch.support.CommandLineJobRunner -Dexec.args="simpleJob.xml simpleJob" Hopefully, your efforts will be rewarded with a "Hello World!" printed on the console. The code source can be downloaded here. What's Next? This is the first part of 3. In the next part we will improve on this example while the third part will be dedicated to item oriented steps and flat files readers and writers. Hope you find it useful.
May 23, 2008
by Tareq Abedrabbo
· 299,561 Views
article thumbnail
Converting a Java Project to a Dynamic Web Project in Eclipse
To convert a Java Project to a Web Project switch to or open the Resource Perspective of the project, in the root of the project. Open the .project file and make sure the builders and natures are present that are needed for a web project. See the example below, the name should be the name of your project, the most important nodes are the nature children in the natures node: testProjectorg.eclipse.jdt.core.javabuilderorg.eclipse.wst.common.project.facet.core.builderorg.eclipse.wst.validation.validationbuilderorg.eclipse.wst.common.project.facet.core.natureorg.eclipse.jdt.core.javanatureorg.eclipse.wst.common.modulecore.ModuleCoreNatureorg.eclipse.jem.workbench.JavaEMFNature Once you’ve updated the .project file you can close the file and right click and choose properties on the project. When the properties window opens click on Project Facets. The Facets grid is probably empty, click the Modify Project button. Check the Dynamic Web Module and Java Facets, choose the Java and Servlet version that applies to your project. Click Next and specify the existing or new location of your src and web content directories. Click Finish. As a final step I would recommend modifying the build path to compile your source directly into your /WEB-INF/classes directory by selecting Java Build Path and modifying the Default output directory. Now you should be able to create a local tomcat server, or if you’ve already created one you should be able to add the project to the server by right clicking the server and choosing Add and Remove Projects. Original article at http://greatwebguy.com/programming/eclipse/converting-a-java-project-to-a-dynamic-web-project-in-eclipse/.
May 6, 2008
by Jason Crow
· 114,909 Views
article thumbnail
Obfuscating a NetBeans Java Application Project
Some time ago I found a couple of posts talking about how to obfuscate a NetBeans RCP module (here and here). Getting some parts of the ant targets presented in the previous post, this one presents a simple target that allows to obfuscate a normal Java library. For this, you need to have installed the obfuscator ProGuard. Take into account I am talking about obfuscating a Java library. This implies the obfuscation is lighter than if you obfuscate a closed application, that is, all public methods and interfaces must maintain its name (if not you can call your library methods anymore). Open your build.xml Java application file and paste this target: Special attention to these couple of lines:
April 30, 2008
by Antonio Santiago
· 46,077 Views · 1 Like
article thumbnail
5 Techniques for Creating Java Web Services From WSDL
WSDL is a version of XML used to better work with web severs. In this post, we'll learn how to better use it alongside the Java language.
April 29, 2008
by Milan Kuchtiak
· 604,754 Views
article thumbnail
Migrate4j - Database Migration Tool for Java
Migrate4j is a migration tool for java, similar to Ruby's db:migrate task. Unlike other Java based migration tools, database schema changes are defined in Java, not SQL. This means your migrations can be applied to different database engines without worrying about whether your DDL statements will still work. Schema changes are defined in Migration classes, which define "up" and "down" methods - "up" is called when a Migration is being applied, while "down" is called when it is being rolled back. A simple Migration, which simply adds a table to a database, is written as: package db.migrations; import static com.eroi.migrate.Define.*; import static com.eroi.migrate.Define.DataTypes.*; import static com.eroi.migrate.Execute.*; import com.eroi.migrate.Migration; public class Migration_1 implements Migration { public void up() { createTable( table("simple_table", column("id", INTEGER, primaryKey(), notnull()), column("desc", VARCHAR, length(50), defaultValue("NA")))); } public void down() { dropTable("simple_table"); } } This Migration can be applied at application startup, from an Ant task (included in migrate4j) or from the command line. Migrate4j will only apply the migration if it has not yet been applied. LIkewise, migrate4j will roll back the migration when instructed, only if the migration has been previously applied. The migrate4j team is happy to announce a new release which adds improved usability (simplified syntax), additional schema changes and support for more database products. While migrate4j does not yet have support for all database products, we are actively seeking developers interested in helping fix this situation. Visit http://migrate4j.sourceforge.net for more information on how migrate4j can simplify synchronizing your databases. To obtain migrate4j, go to http://sourceforge.net/projects/migrate4j and download the latest release. For questions or to help with future development of migrate4j, email us at migrate4j-users AT lists.sourceforge.net (replacing the AT with the "at symbol").
April 28, 2008
by Todd Runstein
· 3,453 Views
article thumbnail
Pathway from ACEGI to Spring Security 2.0
Formerly called ACEGI Security for Spring, the re-branded Spring Security 2.0 has delivered on its promises of making it simpler to use and improving developer productivity. Already considered as the Java platform's most widely used enterprise security framework with over 250,000 downloads from SourceForge, Spring Security 2.0 provides a host of new features. This article outlines how to convert your existing ACEGI based Spring application to use Spring Security 2.0. What is Spring Security 2.0 Spring Security 2.0 has recently been released as a replacement to ACEGI and it provides a host of new security features: Substantially simplified configuration. OpenID integration, single sign on standard. Windows NTLM support, single sign on against Windows corporate networks. Support for JSR 250 ("EJB 3") security annotations. AspectJ pointcut expression language support. Comprehensive support for RESTful web request authorization. Long-requested support for groups, hierarchical roles and a user management API. An improved, database-backed "remember me" implementation. New support for web state and flow transition authorization through the Spring Web Flow 2.0 release. Enhanced WSS (formerly WS-Security) support through the Spring Web Services 1.5 release. A whole lot more... Goal Currently I work on a Spring web application that uses ACEGI to control access to the secure resources. Users are stored in a database and as such we have configured ACEGI to use a JDBC based UserDetails Service. Likewise, all of our web resources are stored in the database and ACEGI is configure to use a custom AbstractFilterInvocationDefinitionSource to check authorization details for each request. With the release of Spring Security 2.0 I would like to see if I can replace ACEGI and keep the current ability to use the database as our source of authentication and authorization instead of the XML configuration files (as most examples demonstrate). Here are the steps that I took... Steps The first (and trickiest) step was to download the new Spring Security 2.0 Framework and make sure that the jar files are deployed to the correct location. (/WEB-INF/lib/) There are 22 jar files that come with the Spring Security 2.0 download. I did not need to use all of them (especially not the *sources packages). For this exercise I only had to include: spring-security-acl-2.0.0.jar spring-security-core-2.0.0.jar spring-security-core-tiger-2.0.0.jar spring-security-taglibs-2.0.0.jar Configure a DelegatingFilterProxy in the web.xml file. springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy springSecurityFilterChain /* Configuration of Spring Security 2.0 is far more concise than ACEGI, so instead of changing my current ACEGI based configuration file, I found it easier to start from a empty file. If you do want to change your existing configuration file, I am sure that you will be deleting more lines than adding. The first part of the configuration is to specifiy the details for the secure resource filter, this is to allow secure resources to be read from the database and not from the actual configuration file. This is an example of what you will see in most of the examples: Replace this with: The main part of this piece of configuration is the secureResourceFilter, this is a class that implements FilterInvocationDefinitionSource and is called when Spring Security needs to check the Authorities for a requested page. Here is the code for MySecureResourceFilter: package org.security.SecureFilter; import java.util.Collection; import java.util.List; import org.springframework.security.ConfigAttributeDefinition; import org.springframework.security.ConfigAttributeEditor; import org.springframework.security.intercept.web.FilterInvocation; import org.springframework.security.intercept.web.FilterInvocationDefinitionSource; public class MySecureResourceFilter implements FilterInvocationDefinitionSource { public ConfigAttributeDefinition getAttributes(Object filter) throws IllegalArgumentException { FilterInvocation filterInvocation = (FilterInvocation) filter; String url = filterInvocation.getRequestUrl(); // create a resource object that represents this Url object Resource resource = new Resource(url); if (resource == null) return null; else{ ConfigAttributeEditor configAttrEditor = new ConfigAttributeEditor(); // get the Roles that can access this Url List roles = resource.getRoles(); StringBuffer rolesList = new StringBuffer(); for (Role role : roles){ rolesList.append(role.getName()); rolesList.append(","); } // don't want to end with a "," so remove the last "," if (rolesList.length() > 0) rolesList.replace(rolesList.length()-1, rolesList.length()+1, ""); configAttrEditor.setAsText(rolesList.toString()); return (ConfigAttributeDefinition) configAttrEditor.getValue(); } } public Collection getConfigAttributeDefinitions() { return null; } public boolean supports(Class arg0) { return true; } } This getAttributes() method above essentially returns the name of Authorities (which I call Roles) that are allowed access to the current Url. OK, so now we have setup the database based resources and now the next step is to get Spring Security to read the user details from the database. The examples that come with Spring Security 2.0 shows you how to keep a list of users and authorities in the configuration file like this: You could replace these examples with this configuration so that you can read the user details straight from the database like this: While this is a very fast and easy way to configure database based security it does mean that you have to conform to a default databases schema. By default, the requires the following tables: user, authorities, groups, group_members and group_authorities. In my case this was not going to work as my security schema it not the same as what the requires, so I was forced to change the : By adding the users-by-username-query and authorities-by-username-query properties you are able to override the default SQL statements with your own. As in ACEGI security you must make sure that the columns that your SQL statement returns is the same as what Spring Security expects. There is a another property group-authorities-by-username-query which I am not using and have therefore left it out of this example, but it works in exactly the same manner as the other two SQL statements. This feature of the has only been included in the past month or so and was not available in the pre-release versions of Spring Security. Luckily it has been added as it does make life a lot easier. You can read about this here and here. The dataSource bean instructs which database to connect to, it is not included in my configuration file as it's not specific to security. Here is an example of a dataSource bean for those who are not sure: And that is all for the configuration of Spring Security. My last task was to change my current logon screen. In ACEGI you could create your own logon by making sure that you POSTED the correctly named HTML input elements to the correct URL. While you can still do this in Spring Security 2.0, some of the names have changed. You can still call your username field j_username and your password field j_password as before. However you must set the action property of your to point to j_spring_security_check and not j_acegi_security_check. Logout Conclusion This short guide on how to configure Spring Security 2.0 with access to resources stored in a database does not come close to illustrating the host of new features that are available in Spring Security 2.0, however I think that it does show some of the most commonly used abilities of the framework and I hope that you will find it useful. One of the benefits of Spring Security 2.0 over ACEGI is the ability to write more consice configuration files, this is clearly shown when I compare my old ACEGI configration (172 lines) file to my new one (42 lines). Here is my complete securityContext.xml file: As I said in step 1, downloading Spring Security was the trickiest step of all. From there on it was plain sailing...
April 22, 2008
by Chris Baker
· 117,986 Views
article thumbnail
1st Binary Release of Java Music Composer
Today marks the availability of the first binary release of the open source JFugue Music NotePad. The core basic functionality of the tool is available and ready to be tried out. After downloading and unzipping the archive, you need to specify the location of the JDK (JDK 5 or above, so Mac users are welcome too), in etc/mnotepad.conf, which is in the unzipped archive's main directory. The binary can be downloaded here: mnotepad_9April2008.zip Once you have done so, you can launch it, which should result in the following main window at start up: Here it is on the Mac: Then choose File | New, to define a new composition: Click Finish and you can begin composing music. To do so, choose notes from the toolbar and point/click to add them to the composition. Currently you can't add notes between existing notes. However, select one/more notes with your mouse, the notes turn red to show they are selected, and then use up/down to move notes up the scale and left/right to decrease/increase their length. While doing this part of the work, compositions typically look something like this: You can change instruments by right-clicking one in the Instruments window and choosing "Select". Finally, click Play to play the music or Save to save it. Compositions are saved to disk in midi format, the status bar shows where they are saved to, in the installation directory. Architecture. Instead of dealing directly with the Midi API, the JFugue API is used instead. The JFugue API provides an extremely transparent, simple, yet surprisngly powerful layer of functionality on top of the complexities of typical Midi programming. The user interface is pure Swing on top of the NetBeans Platform, therefore the application has a very mature window system (max/minimize, dock/undock) and is pluggable out of the box, among other features. User Comments. One of the user comments thus far: "It's definitely very cool! And as promised, you already got a whole bunch of subtle features for free from the NetBeans Platform (windowing, favorites, etc). :-D It already looks more stable and trustworthy than any other app with the same amount of work invested, just because of the solid and consistent windowing system." Known Issues. Amongst others, the following: several usability issues, such as that it isn't easy to know/see from the ui that notes can be changed by selecting them and moving up/down/left/right. Should be able to specify where saved midi file should be saved to. Some users report not being able to change instruments. Keyboard window currently unused. Playing of tune blocks the ui. Feedback Welcome. The JFugue Music NotePad is an open source project at https://nbjfuguesupport.dev.java.net/. You are welcome to join, especially if you are able to offer time/insight to add missing features. Especially programmers who are also musicians are welcome. For example, this application could do with a metronome, which could be provided by a separate plugin...
April 9, 2008
by Geertjan Wielenga
· 12,880 Views
article thumbnail
Spring: How to Create Decoupled Swing Components
The Spring Framework's applicability in the context of Swing seems to be underhighlighted, at least when one looks around on the web.
April 5, 2008
by Geertjan Wielenga
· 61,905 Views
article thumbnail
John Wilson: Groovy and XML
John Wilson is mainly known to the Groovy community because of his work on XmlSlurper, one of the easiest ways to work with XML in the JVM. Continue reading to learn what inspired John to get into Groovy. Enjoy! [img_assist|nid=2119|title=|desc=|link=none|align=right|width=220|height=188]Q. John, you are the creator of XmlSlurper, what motivated you to make it ? A. I had a problem with processing very large XML documents. XmlParser uses a simple and robust way of implementing GPath expressions which involves building an array to hold the result of each term on the expression. Unfortunately this means that you can consume large amounts of memory if the original document is large. I was getting out of memory errors quite a bit so I wrote the original version of XmlSlurper to use Iterarors rather than arrays which cut down the memory footprint quite a bit. It had the happy side effect of being faster too. I have rewritten XmlSlurper a couple of times since then and it now plays very well with StreamingMarkupBuilder, handles namespaces nicely and has an interesting way of doing edits on the fly as the slurped document is written out. Q. XmlSluper and XmlParser are so similar, is there a reason to have both ? A. On the one hand it's a disadvantage because users are unsure which one to use (The answer is - for most things it doesn't matter). However they have differences which are significant and, in my view, valuable. The most significant difference is their approach to editing the document. XmlParser is very straightforward, you just change the in memory tree structure which represents the document. XmlSlurper does not let you have direct access to the in memory data structure. It forces you to put you editing code in closures and specify where in the document the closures should be applied. It then does the editing on the fly as the document is written out. The first mechanism is simple but limited the second is more complicated but very powerful. Most of us only want to do relatively simple operations on small XML documents and XmlParser is excellent for that. For those people who want to do rather complex operations on XMl documents which can be quite large then XmlSlurper is a better choice. Fortunately they support an almost identical GPath syntax so switching from one to the other is no big deal. This was not always so - the community owes a big debt of gratitude to Paul King for doing a large amount of work on documenting these implementations and aligning them. My long term aim is to be able to do away altogether with the need to hold the whole document in memory but to stream the document through memory whist executing the GPath expressions. Q. You are also the creator of the xmlrpc module, what can you tell us about it ? A. It's a module I'm very fond of. It's an excellent example of how Groovy can make something that is quite complex in Java completely trivial. I can build an XML-RPC server in 4 lines of Groovy and a client in 1 line. Performance is excellent and it interoperates well. It is based on code I wrote a few years ago to implement XML-RPC on the Dallas Semiconductor TINI. The TINI is an amazing device the size of a memory SIMM which runs Java on a 8051 (the processor which controlled the keyboard in the original IBM PC) with 1Mb of battery backed up RAM and an Ethernet port. One of my favourite TINI apps was a weather forecasting toaster! [it's true! check it out for yourselves here] Q. Have you participated in other Open Source projects ? A. Yes, mostly in the embedded Java arena. I wrote tiny XML parsers (MinML and MinML2) and a tiny XML-RPC server (MinMl-RPC) i have also contributed to VNC and the Snort intrusion detections system. In the background I'm working on Ng which is an attempt to build a runtime system for dynamic languages on the JVM which is both simple and fast. Q. Ng, can you share more about it? A. Ng is a solo (at the moment) project which tries to answer the question: How can we implement a fully dynamic language on the current JVM which runs no more than ten times slower than Java? This is looking for an improvement of one to two orders of magnitude over current implementations (Groovy, JRuby, Jython, etc.). The idea is to design a programming language "backwards". I start with a highly optimised runtime system and then derive a language which can be optimally compiled for that runtime system. I'm hoping that some of the insights I get whist doing this can be fed back into the Groovy 2.0 MOP redesign. I'm making good but slow progress. I have arithmetic operations executing at less than twice as slow as Java in some benchmarks and method calls are coming below ten times as slow. I have started to document some of the techniques I have developed http://docs.google.com/View?docid=ah76zbd6xsx2_9ck33c8dp Q. How did you get involved with Groovy ? A. I was looking for an Open Source project to get involved in. I have a long term interest in programming languages (my first paid job was as a compiler writer in 1971). I looked at Ruby and JRuby but it was too Perlish for my tastes and the JRuby project looked moribund. Google found me Groovy and I liked the feel of the language and the community was very lively so I stuck around. Q. Do you use Groovy at work ? A. Yes. If I have to mung XML I will always do it in Groovy. I also spend quite a bit of time building DSLs in Groovy. I think the return on investment in DSLs is huge if they are done properly. Q. Do you have a preferred technique for building DSLs (builders, metaprogramming, ... ) ? A. I like builders a lot. I think that the Builder concept is one of James Strachan's best ideas. I built a little DSL to allow people to specify arbitrary graphs - it took about an hour to develop and it's saved days in allowing us to specify complex graphs simply, clearly and reliably. I tend to override invokeMethod, etc. or use Categories rather than ExpandoMetaClass to do MetaPrograming magic. That's probably because to got into the habit before Graeme wrote ExpandoMetaClass. However I do like the fact that Categories allow me to limit the extent of the change to a single thread - they need to have less impact on performance, though. Q. Is there a specific feature you would like to see in a future version of Groovy ? A. I think Inner Classes need to be added. Other than that I don't see much urgent need for language extensions. Quite a lot of work has been done on making the run time system cleaner and that work needs to continue. The speed of the implementation has been improved in the last few months but there is more work needed there (especially with Categories). the big thing I'd like to see is the ability to not compile to class files but to execute the AST (Abstract Syntax Tree) directly. JRuby does this and it can be very useful in cases where you are generating code dynamically and executing it once or twice before discarding it (which is quite a common use). It would also help with the Groovy console. Thanks John! John's bio John Wilson has been a programmer, project manager, teacher, CTO and CEO. He's now CTO of an English engineering company and is enjoying working with a great crowd in the Groovy/Grails community.
April 1, 2008
by Andres Almiray
· 17,376 Views · 1 Like
  • Previous
  • ...
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 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
×