Featured FREE Whitepapers

What's New Here?

jboss-drools-logo

JBoss BRMS 5.3 – adding on Business Activity Monitoring (BAM) Reporting

One of the most often asked question since the release of the JBoss BRMS 5.3 product which has added the jBPM 5 BPM component is that of Business Activity Monitoring (BAM) and Reporting features. This article will walk you through the process of adding it, but be aware, this is not a supported feature of the product at the time of this writing. Adding on BAM Reporting to JBoss BRMS 5.3Install JBoss BRMS 5.3, download from the Customer Portal. Create a birt directory at the following location JBOSS_HOME/server/default/data/birt/ Create the ReportEngine and output directories in the birt directory from step 2 as follows:JBOSS_HOME/server/default/data/birt/ReportEngine / JBOSS_HOME/server/default/data/birt/ouput/Download birt-runtime-2_3_2_2 runtime jar from the following location :http://www.eclipse.org/downloads/download.php?file=/birt/downloads/drops/R-R1-2_3_2_2-200906011507/birt-runtime-2_3_2_2.zip&url=http://download.eclipse.org/birt/downloads/drops/R-R1-2_3_2_2- 200906011507/birt-runtime-2_3_2_2.zip&mirror_id=1Unzip birt-runtime-2_3_2_2/ReportEngine into the JBOSS_HOME/server/default/data/birt/ReportEngine/ directory. Download overall_activity.rptdesign and process_summary.rptdesign report design files from the following location:https://github.com/droolsjbpm/jbpm/tree/master/jbpm-installer/report/2_3_2_2 Copy the files to JBOSS_HOME/server/default/data/birt/Copy h2.jar from /jbpm/lib to the JBOSS_HOME/server/default/data/birt/ReportEngine/plugins/org.eclipse.birt.report.data.oda.jdbc_2.3.2.r232_v20090212/drivers/ directory. Delete report-core-1.4.0-SNAPSHOT.jar and report-shared-1.4.0-SNAPSHOT.jar from the JBOSS_HOME/server/default/deploy/gwt-console-server.war/WEB-INF/lib/ directory. Download the following jars and copy them to the JBOSS_HOME/server/default/deploy/gwt-console-server.war/WEB-INF/lib/ directory.report-core-1.3.0.jarhttps://repository.jboss.org/nexus/content/repositories/releases/org/jboss/bpm/report-core/1.3.0/report-core-1.3.0.jarreport-shared-1.3.0.jarhttps://repository.jboss.org/nexus/content/repositories/releases/org/jboss/bpm/reportshared/1.3.0/report-shared-1.3.0.jarengineapi-2.3.2.jarhttp://repository.jboss.org/nexus/content/groups/public/org/eclipse/birt/engineapi/2.3.2/engineapi-2.3.2.jardteapi-2.3.2.jarhttp://repository.jboss.org/nexus/content/groups/public/org/eclipse/birt/dteapi/2.3.2/dteapi-2.3.2.jarchartengineapi-2.3.2.jarhttp://repository.jboss.org/nexus/content/groups/public/org/eclipse/birt/chartengineapi/2.3.2/chartengineapi-2.3.2.jarcoreapi-2.3.2.jarhttp://repository.jboss.org/nexus/content/groups/public/org/eclipse/birt/coreapi/2.3.2/coreapi-2.3.2.jardataadapterapi-2.3.2.jarhttp://repository.jboss.org/nexus/content/groups/public/org/eclipse/birt/dataadapterapi/2.3.2/dataadapterapi-2.3.2.jarmodelapi-2.3.2.jarhttp://repository.jboss.org/nexus/content/groups/public/org/eclipse/birt/modelapi/2.3.2/modelapi-2.3.2.jarscriptapi-2.3.2.jarhttp://repository.jboss.org/nexus/content/groups/public/org/eclipse/birt/scriptapi/2.3.2/scriptapi-2.3.2.jarecore-2.4.2.jarhttp://repository.jboss.org/nexus/content/groups/public/org/eclipse/emf/ecore/2.4.2/ecore-2.4.2.jarecore-xmi-2.4.1.jarhttp://repository.jboss.org/nexus/content/groups/public/org/eclipse/emf/ecore-xmi/2.4.1/ecorexmi-2.4.1.jarcommon-2.4.0.jarhttp://repository.jboss.org/nexus/content/groups/public/org/eclipse/emf/common/2.4.0/common-2.4.0.jarflute-1.2.jarhttp://repository.jboss.org/nexus/content/groups/public/org/w3c/flute/1.2/flute-1.2.jarsac-1.3.jarhttp://repository.jboss.org/nexus/content/groups/public/org/w3c/sac/1.3/sac-1.3.jarcommons-cli-1.0.jarhttp://repo1.maven.org/maven2/commons-cli/commons-cli/1.0/commons-cli-1.0.jarcommons-discovery-0.2.jarhttp://repo1.maven.org/maven2/commons-discovery/commons-discovery/0.2/commonsdiscovery-0.2.jaritext-1.3.jarhttp://repo1.maven.org/maven2/com/lowagie/itext/1.3/itext-1.3.jaricu4j-3.8.1.jarhttp://repository.jboss.org/nexus/content/groups/public/com/ibm/icu/icu4j/3.8.1/icu4j-3.8.1.jarjs-1.6R2.jarhttp://repo1.maven.org/maven2/rhino/js/1.6R2/js-1.6R2.jarTo view the reports in the Business Central Console go to http://localhost:8080/business-central and log on, see the JBoss BRMS Getting Started Guide for further details. To collect the Business Activity Monitoring performance parameters for a task or process, first run the task or process, and then click on the reports tab on the left pane. This will open the report configuration tab in the right pane. Select ‘overall_activity’ from the drop down and click create to view the report on the performance parameters of the executed process. Install BIRT plugin into JBoss Developer Studio (JBDS)Open JBDS and select Help > Install New Software. In the Work with text box enter BIRT Update Site – http://download.eclipse.org/birt/updtae-site/3.7 and click ADD…. The following packages should be listed for selection:BIRT 3.7 Charting SDK BIRT 3.7 Engine OSGI Runtime SDK BIRT 3.7 Reporting SDK BIRT 3.7 WTP Integration SDKSelect all and click next. Follow the instructions on the installation screen. Restart JBDSEnjoy! Reference: JBoss BRMS 5.3 – adding on Business Activity Monitoring (BAM) Reporting from our JCG partner Eric D. Schabell at the Thoughts on Middleware, Linux, software, cycling and other news… blog....
jboss-hibernate-logo

Generational caching and Envers

Konrad recently shared on our company’s technical room an interesting article on how caching is done is a big polish social network, nk.pl. One of the central concepts in the algorithm is generational caching (see here or here). The basic idea is that for cache keys you use some entity-specific string + version number. The version number increases whenever data changes, thus invalidating any old cache entries, and preventing stale data reads. This makes the assumption that the cache has some garbage collection, e.g. it may simply be a LRU cache. Of course on each request we must know the version number – that’s why it must be stored in a global cache (but depending on our consistency requirements, it also may be distributed across the cluster asynchronously). However the data itself can be stored in local caches. So if our system is read-most, the only “expensive” operation that we will have to do per request is retrieve the version numbers for the entities we are interested in. And this is usually very simple information, which can be kept entirely in-memory. Depending on the type of data and the usage patterns, you can cache individual entities (e.g. for a Person entity, the cache key could be person-9128-123, 9128 being the id, 123 the version number), or the whole lot (e.g. for a Countries entity, the cache key could be countries-8, 8 being the version number). Moreover in the global cache you can keep the latest version number per-id or per-entity; meaning that when the version changes, you invalidate a specific entity or all of them. Having written most of Envers, it quite naturally occurred to me that you may use the entity revision numbers as the cache versions. Subsequent Envers revisions are monotonically increasing numbers, for each transaction you get the next one. So whenever a cached entity changes, you would have to populate the global cache with the latest revision number. Envers provides several ways to get the revision numbers. During the transaction, you can call AuditReader.getCurrentRevision() method, which will give you the revision metadata, including the revision number. If you want more fine-grained control, you may implement your own listener (EntityTrackingRevisionListener), see the docs), and get notified whenever an entity is changed, and update the global cache in there. You can also register an after-transaction-completed callback, and update the cache outside of the transaction boundaries. Or, if you know the entity ids, you may lookup the maximum revision number using either AuditReader.getRevisions or an AuditQueryCreator. As you can obtain the current revision number during a transaction, you may even update the version/revision in the global cache atomically, if you use a transactional cache such as Infinispan. All of that of course in addition to auditing, which is still the main purpose of Envers :) Reference: Generational caching and Envers from our JCG partner Adam Warski at the Blog of Adam Warski blog....
java-interview-questions-answers

Understanding the concept behind ThreadLocal

Intro I was aware of thread local but never had the occasion of really using it until recently. So I start digging a little bit on the subject because I needed an easy way of propagating some user information via the different layers of my web application without changing the signature of each method called. Small prerequisite info A thread is an individual process that has its own call stack.In Java, there is one thread per call stack or one call stack per thread.Even if you don’t create any new threads in your program, threads are there running without your knowledge.Best example is whenyou just start a simple Java program via main method,then you do not implicitly call new Thread().start(), but the JVM creates a main thread for you in order to run the main method. The main thread is quite special because it is the thread from which all the other thread will spawn and when this thread is finished, the application ends it’s lifecycle. In a web application server normally there is a pool of of threads ,because a Thread is class quite heavyweight to create.All JEE servers (Weblogic,Glassfish,JBoss etc) have a self tuning thread pool, meaning that the thread pool increase and decrease when is needed so there is not thread created on each request, and existing ones are reused. Understanding thread local In order to understand better thread local I will show very simplistic implementation of one custom thread local. package ccs.progest.javacodesamples.threadlocal.ex1;import java.util.HashMap; import java.util.Map;public class CustomThreadLocal {private static Map threadMap = new HashMap();public static void add(Object object) { threadMap.put(Thread.currentThread(), object); }public static void remove(Object object) { threadMap.remove(Thread.currentThread()); }public static Object get() { return threadMap.get(Thread.currentThread()); }} So you can call anytime in your application the add method on CustomThreadLocal and what it will do is to put in a map the current thread as key and as value the object you want to associate with this thread. This object might be an object that you want to have access to from anywhere within the current executed thread, or it might be an expensive object you want to keep associated with the thread and reuse as many times you want. You define a class ThreadContext where you have all information you want to propagate within the thread.     package ccs.progest.javacodesamples.threadlocal.ex1;public class ThreadContext {private String userId;private Long transactionId;public String getUserId() { return userId; }public void setUserId(String userId) { this.userId = userId; }public Long getTransactionId() { return transactionId; }public void setTransactionId(Long transactionId) { this.transactionId = transactionId; }public String toString() { return 'userId:' + userId + ',transactionId:' + transactionId; }} Now is the time to use the ThreadContext. I will start two threads and in each thread I will add a new ThreadContext instance that will hold information I want to propagate for each thread. package ccs.progest.javacodesamples.threadlocal.ex1;public class ThreadLocalMainSampleEx1 {public static void main(String[] args) { new Thread(new Runnable() { public void run() { ThreadContext threadContext = new ThreadContext(); threadContext.setTransactionId(1l); threadContext.setUserId('User 1'); CustomThreadLocal.add(threadContext); //here we call a method where the thread context is not passed as parameter PrintThreadContextValues.printThreadContextValues(); } }).start(); new Thread(new Runnable() { public void run() { ThreadContext threadContext = new ThreadContext(); threadContext.setTransactionId(2l); threadContext.setUserId('User 2'); CustomThreadLocal.add(threadContext); //here we call a method where the thread context is not passed as parameter PrintThreadContextValues.printThreadContextValues(); } }).start(); } }Notice: CustomThreadLocal.add(threadContext) is the line of code where the current thread is associated with the ThreadContext instance As you will see executing this code the result will be: userId:User 1,transactionId:1 userId:User 2,transactionId:2How this is possible because we did not passed as parameter ThreadContext ,userId or trasactionId to printThreadContextValues ? package ccs.progest.javacodesamples.threadlocal.ex1;public class PrintThreadContextValues { public static void printThreadContextValues(){ System.out.println(CustomThreadLocal.get()); } } Simple enough When CustomThreadLocal.get() is called from the internal map of CustomThreadLocal it is retrived the object associated with the current thread. Now let’s see the samples when is used a real ThreadLocal class. (the above CustomThreadLocal class is just to understand the principles behind ThreadLocal class which is very fast and uses memory in an optimal way) package ccs.progest.javacodesamples.threadlocal.ex2;public class ThreadContext {private String userId; private Long transactionId;private static ThreadLocal threadLocal = new ThreadLocal(){ @Override protected ThreadContext initialValue() { return new ThreadContext(); }}; public static ThreadContext get() { return threadLocal.get(); } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public Long getTransactionId() { return transactionId; } public void setTransactionId(Long transactionId) { this.transactionId = transactionId; }public String toString() { return 'userId:' + userId + ',transactionId:' + transactionId; } } As javadoc describes : ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread package ccs.progest.javacodesamples.threadlocal.ex2;public class ThreadLocalMainSampleEx2 {public static void main(String[] args) { new Thread(new Runnable() { public void run() { ThreadContext threadContext = ThreadContext.get(); threadContext.setTransactionId(1l); threadContext.setUserId('User 1'); //here we call a method where the thread context is not passed as parameter PrintThreadContextValues.printThreadContextValues(); } }).start(); new Thread(new Runnable() { public void run() { ThreadContext threadContext = ThreadContext.get(); threadContext.setTransactionId(2l); threadContext.setUserId('User 2'); //here we call a method where the thread context is not passed as parameter PrintThreadContextValues.printThreadContextValues(); } }).start(); } }When get is called , a new ThreadContext instance is associated with the current thread,then the desired values are set the ThreadContext instance. As you see the result is the same as for the first set of samples. userId:User 1,transactionId:1 userId:User 2,transactionId:2 (it might be the reverse order ,so don’t worry if you see ‘User 2? first) package ccs.progest.javacodesamples.threadlocal.ex2;public class PrintThreadContextValues { public static void printThreadContextValues(){ System.out.println(ThreadContext.get()); } } Another very usefull usage of ThreadLocal is the situation when you have a non threadsafe instance of an quite expensive object.Most poular sample I found was with SimpleDateFormat (but soon I’ll come with another example when webservices ports will be used) package ccs.progest.javacodesamples.threadlocal.ex4;import java.text.SimpleDateFormat; import java.util.Date;public class ThreadLocalDateFormat { // SimpleDateFormat is not thread-safe, so each thread will have one private static final ThreadLocal formatter = new ThreadLocal() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat('MM/dd/yyyy'); } }; public String formatIt(Date date) { return formatter.get().format(date); } }Conclusion: There are many uses for thread locals.Here I describe only two: (I think most used ones)Genuine per-thread context, such as user id or transaction id. Per-thread instances for performance.Reference: Understanding the concept behind ThreadLocal from our JCG partner Cristian Chiovari at the Java Code Samples blog....
software-development-2-logo

The Software Developer’s Pensieve

Fictional stories (especially science fiction) are full of gadgets and other items that I wish were available to me today. One of the fictional items I would most like to have is the pensieve described in Harry Potter books and shown in Harry Potter movies. This pensieve allows the participant to save his or her memories so that he or she can review them again from a third-person perspective with the clarity of being back in that memory again. Although we don’t have pensieves in our world, there are some relatively recent innovations that do bring us closer to it. I look at some of these in this post and describe why they are useful to the software developer trying to recall why a particular decision was made or even what the decision was. Most serious engineers have learned to appreciate a medium for saving thoughts, decisions, and results of experiments or discussions for later reference. This is no less valuable for the software developer. Personal Blogs One of my motivations for writing this software development-oriented blog is as a form of a pensieve for observations and lessons learned related to software development. My JavaWorld-syndicated version of this blog includes this very motivation in its description: ‘This blog is intended to provide information to help other developers facing the same issues as well as providing me a method to document things in a well-known location for my own future reference.’ Because of their publicly available online nature, personal blogs are easy to access from almost anywhere. Blogger added a new Gadget a while back that allows me to provide a powerful Google Search-backed search of my blog’s content. This makes it easier than ever to find something I know I wrote about it when I need certain details that I’ve forgotten. Re-reading one of my posts or the example code in one of my posts often brings back many other details related to the post. E-mail With modern e-mail systems offering large amounts of data storage space, it is easier than ever to store information in my mail storage. E-mail may be preferable to a personal blog post if it seems only individually interesting rather than generally interesting or if it contains details that are not appropriate for public consumption. E-mail tends to be easily searchable as well. E-mail is really more of a powerful communication tool than a pensieve substitute, but it can serve that function to a lesser degree. Using e-mail as a pensieve has its drawbacks. Changing e-mail systems can be problematic if previous experience is only available in the older e-mail system. E-mail can also be more temporary in nature in some cases where aggressive e-mail purging occurs. A feature of e-mail that can be both an advantage and a disadvantage is the nature of the multi-way communication that occurs in a given e-mail thread. A particular thread can be rich with details leading to a design decision or other important details, but these same important details can also be difficult to glean from the verbosity of some e-mail threads. Splitting e-mail threads can also make it difficult to confidently reconstruct a particular decision or discussion. Online Collaborative Tools (Google Docs) I have been using Google Docs in a variety of work-related and personal-related areas and really enjoy the collaborative nature of these products. Having others be able to instantly see my changes and my being able to instantly see their changes is very useful. In addition, the ability to see the ‘latest and greatest’ anywhere that I have online access is liberating because I don’t need to worry about having access to the productivity software products on any computers I’m using and, even better, I don’t need to worry about ensuring that the latest version of the file is available on some medium. These online tools have many of the advantages of the Wiki (discussed next), but tend to be useful for smaller groups of people where the ‘overhead’ of the Wiki does not seem justifiable or where the people involved are more comfortable working with productivity software such as spreadsheets, presentations, and documents than they are with Wiki text and HTML. Wiki Most software developers can quickly and easily pick up the basics of any given Wiki product and quickly start using it effectively. Wikis seem to be a natural fit for software developers and in many ways feel to me like an extension of the approach I used years ago of creating static web pages to store information for others’ reference and for my own personal future reference. Wikis are easier to add content to than static web pages and are far easier for multiple authors to edit. One of the major advantages of Wikis over static web pages and even over the online collaborative tools is the built-in versioning. It is often useful to see a previous version of a particular Wiki entry. Versioned Wiki pages are a sort of versioned Pensieve, allowing the developer to determine what (s)he or others was thinking or deciding at any given point in time. Another advantage of the Wiki is the ability to easily link to other HTML material such as Javadoc, online product documentation, bug or defect reports, and related blogs and articles. Conclusion We have many fine tools available to us today for recording important decisions and lessons learned. I have seen these technologies improve dramatically during my career, but the degree of improvement is even larger when compared to the documentation tools described in The Mythical Man-Month. It is exciting to think about what the future holds in store for improving our ability to persist our memories in a fashion that allows us to easily recall them and feel as if we’re experiencing again a moment from our past. Reference: The Software Developer’s Pensieve from our JCG partner Dustin Marx at the Inspired by Actual Events blog....
mongodb-logo

Sorting Spring Data MongoDB collections using @OrderBy

This is already third post about tuning and enhancing Spring Data MongoDB capabilities. This time I found that I miss one JPA feature – @OrderBy annotation. @OrderBy specifies the ordering of the elements of a collection valued association at the point when the association is retrieved. In this article I will show how to implement sorting with @OrderBy annotation with Spring Data MongoDB.   Use case Just a short example of what is it all about for those who did not use JPA @OrderBy before. We’ve got here two classes and one to many relation: package pl.maciejwalkowiak.springdata.mongodb.domain;import org.bson.types.ObjectId; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document;@Document public class Backpack { @Id private ObjectId id;private List<Item> items;... }public class Item { private String name; private int price;... }Backpack is here a main class and contains list of embedded items. When Backpack is loaded from database its items are loaded in order close to insertion order. What if we want to change that and order items by one of its fields? We need to implement sorting by our own and again we will extend AbstractMongoEventListener. Sorting details: introducing @OrderBy In opposite to JPA – sorting in this case sorting cannot be done on database level. We need to take care about it on application side – that can be done in two places:before object is converted into MongoDB data structure – if we want to make sure that objects are sorted properly inside MongoDB collection after object is converted from MongoDB data structure into Java object – if we just want to make sure that inside our application List is sorted properlyIn order to specify in which place sorting should take place I have created SortPhase enumeration: public enum SortPhase { AFTER_CONVERT, BEFORE_CONVERT; }Finally – @OrderBy annotation will contain three almost self describing properties: package pl.maciejwalkowiak.springdata.mongodb;import org.springframework.data.mongodb.core.query.Order;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD }) public @interface OrderBy { /** * Field name */ String value(); Order order() default Order.ASCENDING; SortPhase[] phase() default SortPhase.AFTER_CONVERT; }Implementing SortingMongoEventListener Declarative sorting has to use reflection. To keep code readable I used commons-beanutils but it could have been done manually without using it. Add following dependencies to your project: <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.8.3</version> </dependency><dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency>The final part is SortingMongoEventListener implementation: package pl.maciejwalkowiak.springdata.mongodb;import com.mongodb.DBObject; import org.apache.commons.beanutils.BeanComparator; import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener; import org.springframework.data.mongodb.core.query.Order; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils;import java.lang.reflect.Field; import java.util.Arrays; import java.util.Collections; import java.util.List;/** * MongoEventListener that intercepts object before its converted to BasicDBObject (before it is saved into MongoDB) * and after its loaded from MongoDB. * * @author Maciej Walkowiak */ public class SortingMongoEventListener extends AbstractMongoEventListener { @Override public void onAfterConvert(DBObject dbo, final Object source) { ReflectionUtils.doWithFields(source.getClass(), new SortingFieldCallback(source, SortPhase.AFTER_CONVERT)); }@Override public void onBeforeConvert(Object source) { ReflectionUtils.doWithFields(source.getClass(), new SortingFieldCallback(source, SortPhase.BEFORE_CONVERT)); }/** * Performs sorting with field if: * <ul> * <li>field is an instance of list</li> * <li>is annotated with OrderBy annotation</li> * <li>OrderBy annotation is set to run in same phase as SortingFieldCallback</li> * </ul> */ private static class SortingFieldCallback implements ReflectionUtils.FieldCallback { private Object source; private SortPhase phase;private SortingFieldCallback(Object source, SortPhase phase) { this.source = source; this.phase = phase; }public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { if (field.isAnnotationPresent(OrderBy.class)) { OrderBy orderBy = field.getAnnotation(OrderBy.class);if (Arrays.asList(orderBy.phase()).contains(phase)) { ReflectionUtils.makeAccessible(field); Object fieldValue = field.get(source);sort(fieldValue, orderBy); } } }private void sort(Object fieldValue, OrderBy orderBy) { if (ClassUtils.isAssignable(List.class, fieldValue.getClass())) { final List list = (List) fieldValue;if (orderBy.order() == Order.ASCENDING) { Collections.sort(list, new BeanComparator(orderBy.value())); } else { Collections.sort(list, new BeanComparator(orderBy.value(), Collections.reverseOrder())); } }} } }In order to use it you just need to declare this class as a Spring bean in application context: <bean class="pl.maciejwalkowiak.springdata.mongodb.SortingMongoEventListener" />Example Now its time to add created OrderBy annotation to Backpack class from beginning of this post. Lets say we want to order items by price in descending order: @Document public class Backpack { @Id private ObjectId id;@OrderBy(value = "price", order = Order.DESCENDING) private List<Item> items;... }Thats it. Now every time you load Backpack objects – does not matter if its findAll, findOne or your custom method – items in backpack will be ordered.   Summary SortingMongoEventListener is another example how Spring Data MongoDB event system is powerful. You are welcome to comment and let me know if you think this feature could be a part of Spring Data MongoDB. Reference: Sorting Spring Data MongoDB collections using @OrderBy from our JCG partner Maciej Walkowiak at the Software Development Journey blog....
jaspersoft-jasperreports-logo

JasperReports JSF Plugin Use Cases – Simple List Report

This is the first “use case article” of the JasperReports JSF Plugin Series and I will focus on a simple requirement and I will get deeper in further ones. The starting point is the project setup that we have already done for our book store and I will add to it a list with the different books registered in our database and that list will be available as a report as well. Our application will offer with following features when showing reports to the user:User will be able to select the output format of the report. The report view will be localizable and will be output in the same locale that the user of the application has.Initial Setup To avoid creating all the CRUD functionally I will initialize the table that will contain the values to be shown using a SQL script for the sake of simplicity. Just a few records should be enough to the purpose of this article and thus, I will use following script to feed the book table: insert into book(title, author, published_year, genre, price) values('The Futurogical Congress', 'Stanislaw Lem', '1978', 'SciFi', 2.5); insert into book(title, author, published_year, genre, price) values('Brave New World', 'H. G. Wells', '1975', 'SciFi', 3.99); insert into book(title, author, published_year, genre, price) values('Treasure Island', 'Robert Lewis Stevenson', '1948', 'Adventures', 4.45); insert into book(title, author, published_year, genre, price) values('The Lord of the Rings', 'J. R. Tolkien', '1945', 'Fantasy', 12.23); insert into book(title, author, published_year, genre, price) values('In Cold Blood', 'Truman Capote', '1966', 'Nonfiction', 9.50);I will create a resource bundle that will hold the localised texts for the view and the report. The name of the file will be Messages.properties and I will add it to the package net.sf.jasperreports.jsf.sample.usecases under the resources root folder. File contents will be as follows: report.format.select=Select report formatbookList.pageTitle=Browsing Books bookList.id=Reference ID bookList.title=Title bookList.author=Author bookList.genre=Genre bookList.year=Year bookList.price=PriceI added another file like the previous one but named Messages_es.properties and holding the Spanish translation, you can add your additional preferred languages if interested in support more than one. Previous resource file must be configured in our faces-config.xml file: <faces-config ...> <application> <locale-config> <default-locale>en</default-locale> <supported-locale>es</supported-locale> </locale-config> <resource-bundle> <var>Messages</var> <base-name>net.sf.jasperreports.jsf.sample.usecases.Messages</base-name> </resource-bundle> </application> </faces-config>Since I’m using Maven I will configure a folder inside my project structure to hold the reports’ .jrxml files and configure my POM to run the JasperReports compiler against that folder. The folder name I chose is src/main/jasperreports and the POM configuration for the JasperReports Maven Plugin is as follows: <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jasperreports-maven-plugin</artifactId> <version>1.0-beta-2</version> <executions> <execution> <goals> <goal>compile-reports</goal> </goals> </execution> </executions> <configuration> <outputDirectory>target/jasperreports/jasper</outputDirectory> </configuration> <dependencies> <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>4.5.1</version> </dependency> </dependencies> </plugin>I will also add some extra configuration to the Maven WAR Plugin so it can collect all the .jasper files generated by the JasperReports compiler and pack them inside the application WAR file: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.2</version> <configuration> <webResources> <resource> <directory>src/main/jasperreports</directory> <includes> <include>**/*.jrxml</include> </includes> <targetPath>resources/reports/sources</targetPath> </resource> <resource> <directory>target/jasperreports/jasper</directory> <includes> <include>**/*.jasper</include> </includes> <targetPath>resources/reports/jasper</targetPath> </resource> </webResources> </configuration> </plugin>As you may notice, I’m packaging the JasperReports’ .jrxml files inside the web application archive. When using the plugin we can reference either as the report template resource, the plugin engine is smart enough to recognise the type of file referenced and when using a reference to a report source file the plugin will compile the report on the fly. However, the preferred approach should be always to use a .jasper file as it has better performance than the other one.   Design the Report Template As stated in the intro to this series, the visual design tool for JasperReports I will be using is iReport, there are a lot of tutorials out there about how to use iReport so I will skip that part. However, since I want to design a locale-aware report I must pay attention to the I18n Sample provided at JasperReports’ web site. So, we start iReport and select a blank report template. Since our report will use a SQL based data source, once the visual designer has finished loading we must configure the SQL sentence that will grab the data from the database. To do that we must click on the button at the left of the zoom options in the designer view and select the “Report query” tab:The SQL query I will use to grab the data is the most simple one we can do. After inputting that SQL sentence iReport will show us all the available fields in the lower part of the window. If it could load all the fields without any errors then click the OK button to save them to report: select * from book;All the text that will be outputted in my final report will come from either a resource bundle or the database itself. So, as the JasperReports i18n sample points out, we should use text fields wherever we want to output some text. The report design view will look something like following picture:The XML view of the report template file will be something like the following: <?xml version="1.0" encoding="UTF-8"?> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="booklist" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20"> <property name="ireport.zoom" value="1.5"/> <property name="ireport.x" value="0"/> <property name="ireport.y" value="0"/> <queryString> <![CDATA[select * from book]]> </queryString> <field name="BOOK_ID" class="java.lang.Integer"/> <field name="TITLE" class="java.lang.String"/> <field name="AUTHOR" class="java.lang.String"/> <field name="PUBLISHED_YEAR" class="java.lang.String"/> <field name="GENRE" class="java.lang.String"/> <field name="PRICE" class="java.math.BigDecimal"/> <background> <band splitType="Stretch"/> </background> <title> <band height="38" splitType="Stretch"> <textField> <reportElement x="0" y="0" width="227" height="29"/> <textElement> <font size="18" isBold="true"/> </textElement> <textFieldExpression><![CDATA[$R{bookList.pageTitle}]]></textFieldExpression> </textField> </band> </title> <columnHeader> <band height="27" splitType="Stretch"> <textField> <reportElement x="0" y="0" width="100" height="20"/> <textElement> <font isBold="true"/> </textElement> <textFieldExpression><![CDATA[$R{bookList.id}]]></textFieldExpression> </textField> <textField> <reportElement x="113" y="2" width="155" height="20"/> <textElement> <font isBold="true"/> </textElement> <textFieldExpression><![CDATA[$R{bookList.title}]]></textFieldExpression> </textField> <textField> <reportElement x="285" y="2" width="100" height="20"/> <textElement> <font isBold="true"/> </textElement> <textFieldExpression><![CDATA[$R{bookList.author}]]></textFieldExpression> </textField> <textField> <reportElement x="398" y="2" width="100" height="20"/> <textElement> <font isBold="true"/> </textElement> <textFieldExpression><![CDATA[$R{bookList.year}]]></textFieldExpression> </textField> </band> </columnHeader> <detail> <band height="21" splitType="Stretch"> <textField> <reportElement x="0" y="0" width="100" height="20"/> <textElement/> <textFieldExpression class="java.lang.Integer"><![CDATA[$F{BOOK_ID}]]></textFieldExpression> </textField> <textField> <reportElement x="113" y="0" width="155" height="20"/> <textElement/> <textFieldExpression><![CDATA[$F{TITLE}]]></textFieldExpression> </textField> <textField> <reportElement x="285" y="0" width="100" height="20"/> <textElement/> <textFieldExpression><![CDATA[$F{AUTHOR}]]></textFieldExpression> </textField> <textField> <reportElement x="398" y="0" width="112" height="20"/> <textElement/> <textFieldExpression><![CDATA[$F{PUBLISHED_YEAR}]]></textFieldExpression> </textField> </band> </detail> <columnFooter> <band height="45" splitType="Stretch"/> </columnFooter> <pageFooter> <band height="25" splitType="Stretch"> <textField> <reportElement x="227" y="0" width="100" height="20"/> <textElement textAlignment="Center"/> <textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression> </textField> </band> </pageFooter> <summary> <band height="42" splitType="Stretch"/> </summary> </jasperReport>Save this file inside the src/main/jasperreports folder created earlier and you are ready for the next section. Design the JSF View Our JSF View will based in Facelets, so it will be written as a XHTML file in which we need to declare the different library namespaces that we will be using. For instructions how to setup Facelets go straight to its documentation (JSF 2.x applications support Facelets out-of-the-box without additional configuration). The following snippet shows the contents of the Facelets’ template I will use to render the user interface for the book list. Copy it and save it in a file inside your web application content files. The file name I will use is /book/bookList.xhtml: <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:jr="http://jasperreportjsf.sf.net/tld/jasperreports-jsf-1_3.tld"> <head> <title>Book List - JasperReports JSF Use Cases</title> </head> <body> <h1><h:outputText value="#{Messages['bookList.pageTitle']}"/></h1><div> <h:form id="bookListForm"> <jr:source id="bookSource" type="jndi" value="java:comp/env/jdbc/BookStoreDB"/><h:panelGrid columns="3"> <h:outputLabel for="reportFormat" value="#{Messages['report.format.select']}" /> <h:selectOneMenu id="reportFormat" value="#{bookList.reportFormat}" onchange="document.bookListForm.submit();"> <f:selectItems value="#{bookList.reportFormats}" /> </h:selectOneMenu> <jr:reportLink id="reportLink" format="#{bookList.reportFormat}" target="blank" source="bookSource" value="/resources/reports/jasper/booklist.jasper" resourceBundle="#{Messages}"> <h:outputText value="#{Messages['bookList.action.show']}"/> </jr:reportLink> </h:panelGrid><h:dataTable value="#{bookList.allBooks}" var="book"> <h:column> <f:facet name="header"> <h:outputText value="#{Messages['bookList.title']}"/> </f:facet> <h:outputText value="#{book.title}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="#{Messages['bookList.author']}"/> </f:facet> <h:outputText value="#{book.author}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="#{Messages['bookList.year']}"/> </f:facet> <h:outputText value="#{book.publishedYear}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="#{Messages['bookList.genre']}"/> </f:facet> <h:outputText value="#{book.genre}"/> </h:column> </h:dataTable> </h:form> </div> </body> </html>The highlighted lines are where we are adding the JasperReports JSF Plugin components:First of all, at line 14, we are defining a Report Source Component by means of the <jr:source> tag. This component will not output any data to the rendered HTML but can be referenced by the visual components of the library as way of telling them how to obtain the data they need to render the report contents. From line 21 to 26 we are defining a Report Link Component by means of the <jr:reportLink> tag. This component will output a standard a HTML element pointing to a special URL generated by the plugin’s engine. When clicked on it the plugin’s engine will intercept that URL and replace some of the JSF life-cycle phases to process the report data and generate a result. Notice that the report component has an attribute resourceBundle pointing to the messages bundle we have created in the first section.Note: The resourceBundle attribute has made available in the trunk version (at the moment of writing this lines) of JasperReports JSF Plugin, which uses the 1.3 version of the tag library. For users that are still using the 1.2 version of the tag library they can get a similar result adding a parameter to the report link: <jr:reportLink id="reportLink" format="#{bookList.reportFormat}" target="blank" source="bookSource" value="/resources/reports/jasper/booklist.jasper"> <f:param name="RESOURCE_BUNDLE" value="#{Messages}" /> <h:outputText value="#{Messages['bookList.action.show']}"/> </jr:reportLink>Apart from the highlighted lines, I added code to render a combo box with all the export options supported by JasperReports JSF Plugin and a data table that will layout the different records for the table books. Note: The combo box contains an onchange attribute intended to submit the form with the new value for the report export option. I must done it that way to get the report link properly working in JSF prior to version 2.x as that versions do not have any AJAX support. The JSF view shown above needs a managed bean to work, that managed bean will be providing the values to the user interface: public class BookListView {private BookManager bookManager;private List allBooks;private String reportFormat = &quot;pdf&quot;;public void setBookManager(BookManager bookManager) { this.bookManager = bookManager; }public List getAllBooks() { if (allBooks == null) { allBooks = bookManager.getAllBooks(); } return allBooks; }public String getReportFormat() { return reportFormat; }public void setReportFormat(String reportFormat) { this.reportFormat = reportFormat; }public List getReportFormats() { FacesContext context = FacesContext.getCurrentInstance(); JRFacesContext jrContext = JRFacesContext.getInstance(context); List list = new ArrayList(); for (String format : jrContext.getAvailableExportFormats()) { list.add(new SelectItem(format, format)); } return list; }}The bookManager field is a reference to an interface that will provide with the logic to fetch all the books from the database: public interface BookManager { public List getAllBooks(); }As said in the introduction article to this series, I will not get into the details of additional classes or interfaces needed to implement the use case as it’s up each specific user to decide what framework will be providing the skeleton of the application.   Testing All Together It’s time to check that everything works as it should. So, let’s package our web application, deploy it on our Tomcat server and enter the following URL into your preferred browser: http://localhost:8080/jrjsf-usecases/book/bookList.jsf. Note: The Derby (database) and Tomcat (app server) must be running before performing the deploy operation. So, this is how it should look when our browser outputs the contents of the previous mentioned URL:Now, click on the “Show Report” link to see the outputs of the report filled with the strings from our resource bundle and the data from the database:That is a sample screenshot taken from the PDF view of the report. Use the combo box in the user interface to change the report export format. Conclusion So, all done, this is the simplest way of adding a report to our JavaServer Faces application. I started with a simple sample and I will be adding more complex features to it from time to time. Hope you enjoyed this article and come back for the future publications, the good stuff is yet to come! Reference: JasperReports JSF Plugin Use Cases – Simple List Report from our JCG partner Alonso Dominguez at the Code Nibbles blog....
zk-logo

ZK in Action: MVVM – Form Binding

This is the second episode in our efforts to build a ZK application from the ground up. The previous post dealt with loading and rendering of data into a table using MVVM. In this post, we’ll be introduced to ZK MVVM’s form binding. Objective We’ll build an “Add” function that would enable us to save new entries to the inventory.A Form Appears When “Add” is ClickedNew Entry is Added When “Save” is ClickedZK Features in Action  MVVM : Save, Form Binding, Conditional BindingAdd New Entries with MVVM Form Binding we’ll need to implement these parts:Enhance our ViewModel POJO Add UI markup to present a form and decorate the markup with the appropriate annotationsThe ViewModel Class public class InventoryVM {private List<item> items; private Item newItem; @NotifyChange("newItem") @Command public void createNewItem(){ newItem = new Item("", "",0, 0,new Date()); } @NotifyChange({"newItem","items"}) @Command public void saveItem() throws Exception{ DataService.getInstance().saveItem(newItem); newItem = null; items = getItems(); } @NotifyChange("newItem") @Command public void cancelSave() throws Exception{ newItem = null; } public List<item> getItems() throws Exception{ items = DataService.getInstance().getAllItems(); return items; } }Line 4, we declare an Item object named newItem which will reference the Item instance to be saved to the database. Line 6, @NotifyChange informs the binder to update the UI on the state of the associated ViewModel’s property. In our UI markup shown below, at line 8, we have a Groupbox annotated with visible=”@load(not empty vm.newItem), hence the Groupbox will become visible once createNewItem assigns an instance of Item to newItem. Simply put, @NotifyChange refreshes the UI with respect to the updates on ViewModel’s properties. Line 7, we annotate the createNewItem method with @Command and in our UI markup shown below, at line 4, we have a Toolbarbutton with onClick=”@commnad(createNewItem)”. So when the Toolbarbutton is clicked, the createNewItem method will be invoked. Similarly, from line 12 to 18, we have a saveItem method which is called when its corresponding onClick event is triggered. Once the new Item object is saved to the database cache, we reset the newItem to null and retrieve the new list of items. The changes made to the ViewModel properties newItem (now null again) and items (now with an extra entry) are reflected to the UI using @NotifyChange as before. The Markup <window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('lab.sphota.zk.ctrl.InventoryVM')"> <toolbar> <toolbarbutton label="Add" onClick="@command('createNewItem')" /> </toolbar> <groupbox form="@id('itm') @load(vm.newItem) @save(vm.newItem, before='saveItem')" visible="@load(not empty vm.newItem)"> <caption label="New Item"></caption> <grid width="50%"> <rows> <row> <label value="Item Name" width="100px"></label> <textbox id="name" value="@bind(itm.name)" /> </row> <row> <label value="Model" width="100px"></label> <textbox value="@bind(itm.model)" /> </row> <row> <label value="Unit Price" width="100px"></label> <decimalbox value="@bind(itm.price)" format="#,###.00" constraint="no empty, no negative" /> </row> <row> <label value="Quantity" width="100px"></label> <spinner value="@bind(itm.qty)" constraint="no empty,min 0 max 999: Quantity Must be Greater Than Zero" /> </row> <row> <cell colspan="2" align="center"> <button width="80px" label="Save" onClick="@command('saveItem')" mold="trendy" /> <button width="80px" label="Cancel" onClick="@command('cancelSave')" mold="trendy" /> </cell> </row> </rows> </grid> </groupbox> <listbox> ... </listbox> </window>Line 1, we apply ZK’s default implementation of its BindComposer. It is responsible for instantiating our ViewModel and Binder instances. Line 2, we supply the full class name of the ViewModel we wish to instantiate and give it an ID for future reference Line 4, we assign our ViewModel’s “command method” createNewItem as the onClick event handler for the toolbar button. Line 6, the property newItem in ViewModel is made referenceable throughout the Groupbox using the ID “itm”. Line 6,7, by using form binding, to avoid invalid or incomplete data saved to the ViewModel property, entries in the form are saved to a temporary object until the command method saveItem is called. Line 8, we show the Groupbox to enter a new Item entry only user has clicked the “Add” button; which in turn invokes createNewItem method and assigns the VM property newItem an instance of Item with default value(empty strings and 0s). Line 14, 18, 22, 27, we bind the Item properties with the input elements. @bind is effectively equivalent to @load plus @save.In a Nuteshell To sum up in point form:Using form binding avoids directly modifying data in ViewModel properties by saving form entries to a temporary object. Data is written to the ViewModel properties only if the condition specified is satisfied; in our example, only if the saveItem method is invoked. @Command annotation allows the binder to map UI event handlers to ViewModel command methods. @NotifyChange informs the binder which ViewModel properties had been modified after the command method is executed so changes in data can then be reflected on the UI. We can assign values to any of UI components’ attributes at run-time via MVVM binding to manipulate parameters such as visibility, style, disable/enable, etc.In this post, we’ve not seen how data entries are validated. Before that, we’ll implement the delete and edit functionalities in the next post. Reference ZK Developer Reference Reference: ZK in Action [1] : MVVM – Form Binding from our JCG partner Lance Lu at the Tech Dojo blog....
java-interview-questions-answers

Three steps to follow MVC while building Java Web application

Step #1 DO Always process URL(POST forms, link clicking etc) by servlet / action bean and never by JSPWHY ActionBeans (whatever certain framework call those classes) and rarely servlets are controllers intended for processing user input. JSPs are view engine dedicated to rendering representation of software to client. Separating user input processing and HTML rendering prevents you from temptation of creating huge, multi-purpose, untestable JSPs that are mixing business and representation logic and violating MVC pattern.Step #2 DO Render views by forwarding to JSP located only under /WEB-INF/{JSP folder}WHY Views should be accessible only by design of software and never directly. Putting JSPs within root directory of project brings security issues regarding unwanted access to them from clients.Also practice of hiding all JSPs under /WEB-INF reduces possibility of URL being processed by JSP and not controller and help us to follow step #1.Step #3 DO Pass model from controller to view only by using request attributes or flash scopeWHY All other ways of view being able to access some data are too limited or insecure. Using request parameters directly within view can be the option for malicious user to pass invalid data. Using session for storing information is causing memory consumption and requires mechanisms to clear unused data after expiration. Cookies depends on browser, limited in size and not very friendly to use. From the other hand – request attributes lacks all those drawback and propose clean decoupling of controller responsibility (update model) and view responsibility (read model). Flash scope becomes very handy when it comes to Redirect After Post pattern where request attributes can’t be used.PS: all modern action-based frameworks are using steps described below to achieve their goals. But if you using some old fashioned code or don’t use any framework at all – you still can achieve good clean and easy to use MVC.Reference: Three steps to follow MVC while building Java Web application from our JCG partner Evgeny Shepelyuk at the jk’s blog blog....
zk-logo

ZK in Action: MVVM – Update View Programmatically

In the previous 2 posts we’ve used ZK’s MVVM functionalities to:load data into a table save data with form bindingWe’ve seen when a method is decorated with the annotation @NotifyChange( ) , upon its execution completes, the Binder would be informed of the VM property’s changes so that Binder can update the corresponding UI accordingly. In this post, whilst we implement the functionality of item deletion in our inventory, we’ll see how we can update UI components programmatically at runtime. Objective Build a delete function to our simple inventory CRUD feature.ZK Feature in ActionMVVM : BindUtilsImplement Deletion with MVVM BindUtilsWe will:Add markup for the delete button and assign it an onClick event handler Implement command method ‘deleteItem()‘ in VMThe Markup <window apply='org.zkoss.bind.BindComposer' viewModel='@id('vm') @init('...InventoryVM')'> <toolbar width='100%'> <toolbarbutton label='Add' onClick='@command('createNewItem')' /> <toolbarbutton label='Delete' onClick='@command('deleteItem')' disabled='@load(empty vm.selected)'/> </toolbar>line 5, assign a command method ‘deleteItem‘ to the delete button’s onClick handler line 5, ‘disabled=’@(empty vm.selected)’‘ ensures that the delete button is functional only if an entry in the table has been selectedThe ViewModel Class public class InventoryVM {private Item selected; private List<Item> items; ...@Command public void deleteItem() throws Exception{ if (selected != null){ String str = 'The item with name \'' +selected.getName() +'\' and model \'' +selected.getModel() +'\' will be deleted.';Messagebox.show(str,'Confirm Deletion', Messagebox.OK|Messagebox.CANCEL, Messagebox.QUESTION, new EventListener<event>(){ @Override public void onEvent(Event event) throws Exception { if (event.getName().equals('onOK')){ DataService.getInstance().deleteItem(selected); items = getItems(); BindUtils.postNotifyChange(null, null, InventoryVM.this, 'items'); }); } ... } ... }line 7, we decorate our deleteItem method with @Command so it can be wired as the onClick event handler in our added markup: <toolbarbutton label=’Delete’ onClick=’@command(‘deleteItem’)’ />; line 9, we go ahead with the deletion process only if an item is selected. line 16, we show a Messagebox which prompts the user to confirm the deletion of the selected item. line 20, if user clicks ‘OK’, our program proceeds to delete the selected item. line 23, we call BindUtils.postNotifyChange(String queueName, String queueScope, Object bean, String property) to update our inventory table. By giving the parameter queueScope a null value, the default desktop queue scope is used. The third and forth argument are given as such since we want to notify the Binder that property ‘items’ in our InventoryVM instance has changed. The Binder would then update the UI (remove the item entry in the inventory table).Wrap Up The @NotifyChange annotation lets us update the UI through ZK MVVM’s Binder to reflect changes made to the ViewModel properties. The notification is fired when the annotated method finishes executing. In our implementation, we attached an anonymous event listener class to a Messagebox. In this case, after deleteItem is executed, the annotation @NotifyChange(‘items’) would falsely alert the Binder before the event handling is completed. A programmatic way to reflect state changes in ViewModel to the UI resolves this particular problem conveniently. Next up, editing the entries with MVVM. Reference: ZK in Action [2] : MVVM – Update View Programmatically from our JCG partner Lance Lu at the Tech Dojo blog....
java-logo

java.lang.NoClassDefFoundError: How to resolve – Part 3

This article is part 3 of our NoClassDefFoundError troubleshooting series. As I mentioned in my first article, there are many possible issues that can lead to a NoClassDefFoundError. This article will focus and describe one of the most common causes of this problem: failure of a Java class static initializer block or variable. A sample Java program will be provided and I encourage you to compile and run this example from your workstation in order to properly replicate and understand this type of NoClassDefFoundError problem. Java static initializer revisited The Java programming language provides you with the capability to “statically” initialize variables or a block of code. This is achieved via the “static” variable identifier or the usage of a static {} block at the header of a Java class. Static initializers are guaranteed to be executed only once in the JVM life cycle and are Thread safe by design which make their usage quite appealing for static data initialization such as internal object caches, loggers etc. What is the problem? I will repeat again, static initializers are guaranteed to be executed only once in the JVM life cycle…This means that such code is executed at the Class loading time and never executed again until you restart your JVM. Now what happens if the code executed at that time (@Class loading time) terminates with an unhandled Exception? Welcome to the java.lang.NoClassDefFoundError problem case #2! NoClassDefFoundError problem case 2 – static initializer failure This type of problem is occurring following the failure of static initializer code combined with successive attempts to create a new instance of the affected (non-loaded) class. Sample Java program The following simple Java program is split as per below: – The main Java program NoClassDefFoundErrorSimulator – The affected Java class ClassA – ClassA provides you with a ON/OFF switch allowing you the replicate the type of problem that you want to study This program is simply attempting to create a new instance of ClassA 3 times (one after each other) . It will demonstrate that an initial failure of either a static variable or static block initializer combined with successive attempt to create a new instance of the affected class triggers java.lang.NoClassDefFoundError. #### NoClassDefFoundErrorSimulator.java package org.ph.javaee.tools.jdk7.training2;/** * NoClassDefFoundErrorSimulator * @author Pierre-Hugues Charbonneau * */ public class NoClassDefFoundErrorSimulator { /** * @param args */ public static void main(String[] args) { System.out.println("java.lang.NoClassDefFoundError Simulator - Training 2"); System.out.println("Author: Pierre-Hugues Charbonneau"); System.out.println("http://javaeesupportpatterns.blogspot.com\n\n"); try { // Create a new instance of ClassA (attempt #1) System.out.println("FIRST attempt to create a new instance of ClassA...\n"); ClassA classA = new ClassA(); } catch (Throwable any) { any.printStackTrace(); } try { // Create a new instance of ClassA (attempt #2) System.out.println("\nSECOND attempt to create a new instance of ClassA...\n"); ClassA classA = new ClassA(); } catch (Throwable any) { any.printStackTrace(); } try { // Create a new instance of ClassA (attempt #3) System.out.println("\nTHIRD attempt to create a new instance of ClassA...\n"); ClassA classA = new ClassA(); } catch (Throwable any) { any.printStackTrace(); } System.out.println("\n\ndone!"); } }#### ClassA.java package org.ph.javaee.tools.jdk7.training2;/** * ClassA * @author Pierre-Hugues Charbonneau * */ public class ClassA { private final static String CLAZZ = ClassA.class.getName(); // Problem replication switch ON/OFF private final static boolean REPLICATE_PROBLEM1 = true; // static variable initializer private final static boolean REPLICATE_PROBLEM2 = false; // static block{} initializer // Static variable executed at Class loading time private static String staticVariable = initStaticVariable(); // Static initializer block executed at Class loading time static { // Static block code execution... if (REPLICATE_PROBLEM2) throw new IllegalStateException("ClassA.static{}: Internal Error!"); } public ClassA() { System.out.println("Creating a new instance of "+ClassA.class.getName()+"..."); } /** * * @return */ private static String initStaticVariable() { String stringData = ""; if (REPLICATE_PROBLEM1) throw new IllegalStateException("ClassA.initStaticVariable(): Internal Error!"); return stringData; } }Problem reproduction In order to replicate the problem, we will simply “voluntary” trigger a failure of the static initializer code . Please simply enable the problem type that you want to study e.g. either static variable or static block initializer failure: // Problem replication switch ON (true) / OFF (false) private final static boolean REPLICATE_PROBLEM1 = true; // static variable initializer private final static boolean REPLICATE_PROBLEM2 = false; // static block{} initializerNow, let’s run the program with both switch at OFF (both boolean values at false) ## Baseline (normal execution) java.lang.NoClassDefFoundError Simulator - Training 2 Author: Pierre-Hugues Charbonneauhttp://javaeesupportpatterns.blogspot.comFIRST attempt to create a new instance of ClassA... Creating a new instance of org.ph.javaee.tools.jdk7.training2.ClassA... SECOND attempt to create a new instance of ClassA... Creating a new instance of org.ph.javaee.tools.jdk7.training2.ClassA... THIRD attempt to create a new instance of ClassA... Creating a new instance of org.ph.javaee.tools.jdk7.training2.ClassA... done! For the initial run (baseline), the main program was able to create 3 instances of ClassA successfully with no problem. ## Problem reproduction run (static variable initializer failure) java.lang.NoClassDefFoundError Simulator - Training 2 Author: Pierre-Hugues Charbonneauhttp://javaeesupportpatterns.blogspot.comFIRST attempt to create a new instance of ClassA... java.lang.ExceptionInInitializerError at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:21 ) Caused by: java.lang.IllegalStateException : ClassA.initStaticVariable(): Internal Error! at org.ph.javaee.tools.jdk7.training2.ClassA.initStaticVariable( ClassA.java:37 ) at org.ph.javaee.tools.jdk7.training2.ClassA.<clinit>( ClassA.java:16 ) ... 1 more SECOND attempt to create a new instance of ClassA... java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:30 ) THIRD attempt to create a new instance of ClassA... java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:39> ) done! ## Problem reproduction run (static block initializer failure) java.lang.NoClassDefFoundError Simulator - Training 2 Author: Pierre-Hugues Charbonneauhttp://javaeesupportpatterns.blogspot.comFIRST attempt to create a new instance of ClassA... java.lang.ExceptionInInitializerError at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:21 ) Caused by: java.lang.IllegalStateException> : ClassA.static{}: Internal Error! at org.ph.javaee.tools.jdk7.training2.ClassA.<clinit>( ClassA.java:22 ) ... 1 more SECOND attempt to create a new instance of ClassA... java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:30 ) THIRD attempt to create a new instance of ClassA... java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:39 ) done! What happened? As you can see, the first attempt to create a new instance of ClassA did trigger a java.lang.ExceptionInInitializerError . This exception indicates the failure of our static initializer for our static variable & bloc which is exactly what we wanted to achieve. The key point to understand at this point is that this failure did prevent the whole class loading of ClassA . As you can see, attempt #2 and attempt #3 both generated a java.lang.NoClassDefFoundError, why? Well since the first attempt failed, class loading of ClassA was prevented. Successive attempts to create a new instance of ClassA within the current ClassLoader did generate java.lang.NoClassDefFoundError over and over since ClassA was not found within current ClassLoader. As you can see, in this problem context, the NoClassDefFoundError is just a symptom or consequence of another problem. The original problem is the ExceptionInInitializerError triggered following the failure of the static initializer code. This clearly demonstrates the importance of proper error handling and logging when using Java static initializers. Recommendations and resolution strategies Now find below my recommendations and resolution strategies for NoClassDefFoundError problem case 2: – Review the java.lang.NoClassDefFoundError error and identify the missing Java class – Perform a code walkthrough of the affected class and determine if it contains static initializer code (variables & static block) – Review your server and application logs and determine if any error (e.g. ExceptionInInitializerError) originates from the static initializer code – Once confirmed, analyze the code further and determine the root cause of the initializer code failure. You may need to add some extra logging along with proper error handling to prevent and better handle future failures of your static initializer code going forward Please feel free to post any question or comment. The part 4 will start coverage of NoClassDefFoundError problems related to class loader problems. Reference: java.lang.NoClassDefFoundError: How to resolve – Part 3 from our JCG partner Pierre-Hugues Charbonneau at the Java EE Support Patterns & Java Tutorial blog....
Java Code Geeks and all content copyright © 2010-2015, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close