Featured FREE Whitepapers

What's New Here?

java-logo

How to analyze Thread Dump – IBM VM

This article is part 4 of our Thread Dump analysis series which will provide you with an overview of what is a JVM Thread Dump for the IBM VM and the different Threads and data points that you will find. As you will see and learn, the IBM VM Thread Dump format is different but provides even more out-of-the-box troubleshooting data. At this point, you should know how Threads interact with the Java EE container and what a Thread Dump is. Before we go any further in the deep dive analysis patterns, you also need to understand the IBM VM Thread Dump format since this is the typical Thread Dump data to expect when using IBM WAS on IBM VM. IBM VM Thread Dump breakdown overview In order for you to better understand, find below a diagram showing you a visual breakdown of an IBM 1.6 VM Thread Dump and its common data points found:   As you can, there are extra runtime data that you will not find from a HotSpot VM Thread Dump. Please keep in mind that you may not need to review all these data points but you still need to understand what data is available depending of your problem case. The rest of the article will cover each Thread Dump portion in more detail. # Thread Dump generation event  The first portion provides you with detail on how this Thread Dump was generated. IBM Thread Dump can be generated as a result of a “signal 3” or “user” e.g. kill -3 <Java pid> or automatically as a result of severe JVM conditions such as an OutOfMemoryError. 0SECTION TITLE subcomponent dump routineNULL ===============================1TISIGINFO Dump Event "user" (00004000) received1TIDATETIME Date: 2012/03/12 at 20:52:131TIFILENAME Javacore filename: /apps/wl11g/domains/app/javacore.20120312.205205.1949928.0004.txt1TIREQFLAGS Request Flags: 0x81 (exclusive+preempt)1TIPREPSTATE Prep State: 0x4 (exclusive_vm_access) 0SECTION TITLE subcomponent dump routineNULL ===============================1TISIGINFO OUTOFMEMORY received1TIDATETIME Date: 2012/06/01 at 09:52:121TIFILENAME Javacore filename: /usr/WebSphere/AppServer/javacore311328.1338524532.txt# HW and OS environment detail The next section provides you with some detail on the current hardware and OS that this IBM VM is running from: 0SECTION GPINFO subcomponent dump routineNULL ================================2XHOSLEVEL OS Level : AIX 5.32XHCPUS Processors -3XHCPUARCH Architecture : ppc643XHNUMCPUS How Many : 63XHNUMASUP NUMA is either not supported or has been disabled by user# JRE detail and Java start-up arguments This section is very useful as it provides you with a full view on your JRE major version and patch level along with all JVM start-up arguments. 0SECTION ENVINFO subcomponent dump routineNULL =================================1CIJAVAVERSION JRE 1.6.0 IBM J9 2.4 AIX ppc64-64 build jvmap6460sr9-20101124_692951CIVMVERSION VM build 20101124_0692951CIJITVERSION JIT enabled, AOT enabled - r9_20101028_17488ifx21CIGCVERSION GC - 20101027_AA1CIRUNNINGAS Running as a standalone JVM…………………………………………………………………………………………# User and environment variables This section provides you with a listing of current user and environment variables such as File Descriptor limit. 1CIUSERLIMITS User Limits (in bytes except for NOFILE and NPROC)NULL------------------------------------------------------------------------NULL type soft limit hard limit 2CIUSERLIMIT RLIMIT_AS unlimited unlimited2CIUSERLIMIT RLIMIT_CORE 1073741312 unlimited2CIUSERLIMIT RLIMIT_CPU unlimited unlimited2CIUSERLIMIT RLIMIT_DATA unlimited unlimited2CIUSERLIMIT RLIMIT_FSIZE unlimited unlimited2CIUSERLIMIT RLIMIT_NOFILE 4096 40962CIUSERLIMIT RLIMIT_RSS 33554432 unlimited2CIUSERLIMIT RLIMIT_STACK 33554432 4294967296 # Java Heap detail and GC history Similar to HotSpot VM 1.6+, IBM VM Thread Dump also contains information on the Java Heap capacity and utilization along with memory segments allocated for each memory space of the Java process. Please keep in mind that deeper Java Heap analysis will require you to analyze the Heap Dump binary snapshot as per below tutorial. http://javaeesupportpatterns.blogspot.com/2011/02/ibm-sdk-heap-dump-httpsession-footprint.html Finally, an history of the garbage collection process is also present. 0SECTION MEMINFO subcomponent dump routineNULL =================================1STHEAPFREE Bytes of Heap Space Free: 51104BC81STHEAPALLOC Bytes of Heap Space Allocated: 800000001STSEGTYPE Internal Memory ………………………………………………………………………………………… 1STSEGTYPE Object Memory ………………………………………………………………………………………… 1STSEGTYPE Class Memory ………………………………………………………………………………………… 1STSEGTYPE JIT Code Cache ………………………………………………………………………………………… 1STSEGTYPE JIT Data Cache ………………………………………………………………………………………… STGCHTYPE GC History3STHSTTYPE 00:52:07:523048405 GMT j9mm.51 - SystemGC end: newspace=466136480/483183616 oldspace=899251600/1610612736 loa=80530432/805304323STHSTTYPE 00:52:07:523046694 GMT j9mm.139 - Reference count end: weak=40149 soft=87504 phantom=33 threshold=17 maxThreshold=323STHSTTYPE 00:52:07:522164027 GMT j9mm.91 - GlobalGC end: workstackoverflow=0 overflowcount=0 weakrefs=40149 soft=87504 threshold=17 phantom=33 finalizers=4947 newspace=466136480/483183616 oldspace=899251600/1610612736 loa=80530432/805304323STHSTTYPE 00:52:07:522152764 GMT j9mm.90 - GlobalGC collect complete# Java and JVM object monitor lock and deadlock detail This Thread Dump portion is very important. Quite often Thread problems involve Threads waiting between each other due to locks on particular Object monitors e.g. Thread B waiting to acquire a lock on Object monitor held by Thread A. Deadlock conditions can also be triggered from time to time; especially for non-Thread safe implementations. The IBM VM Thread Dump provides a separate section where you can analyze lock(s) held by each Thread including waiting chain(s) e.g. Many Threads waiting to acquire the same Object monitor lock. 0SECTION LOCKS subcomponent dump routineNULL ===============================NULL1LKPOOLINFO Monitor pool info:2LKPOOLTOTAL Current total number of monitors: 1034NULL1LKMONPOOLDUMP Monitor Pool Dump (flat & inflated object-monitors):2LKMONINUSE sys_mon_t:0x0000000115B53060 infl_mon_t: 0x0000000115B530A0:3LKMONOBJECT java/util/Timer$TimerImpl@0x0700000000C92AA0/0x0700000000C92AB8: <unowned>3LKNOTIFYQ Waiting to be notified:3LKWAITNOTIFY "Thread-7" (0x0000000114CAB400) …………………………………………………………………………## Threads waiting chain 2LKMONINUSE sys_mon_t:0x000000012462FE00 infl_mon_t: 0x000000012462FE40:3LKMONOBJECT com/inc/server/app/Request@0x07000000142ADF30/0x07000000142ADF48:owner "Thread-30" (0x000000012537F300), entry count 13LKNOTIFYQ Waiting to be notified:3LKWAITNOTIFY "Thread-26" (0x0000000125221F00)3LKWAITNOTIFY "Thread-27" (0x0000000125252000)3LKWAITNOTIFY "Thread-28" (0x000000012527B800)3LKWAITNOTIFY "Thread-29" (0x00000001252DDA00)3LKWAITNOTIFY "Thread-31" (0x0000000125386200)3LKWAITNOTIFY "Thread-32" (0x0000000125423600)3LKWAITNOTIFY "Thread-33" (0x000000012548C500)3LKWAITNOTIFY "Thread-34" (0x00000001255D6000)3LKWAITNOTIFY "Thread-35" (0x00000001255F7900) …………………………………………………………………………# Java EE middleware, third party & custom application Threads Similar to the HotSpot VM Thread Dump format, this portion is the core of the Thread Dump and where you will typically spend most of your analysis time. The number of Threads found will depend on your middleware software that you use, third party libraries (that might have its own Threads) and your application (if creating any custom Thread, which is generally not a best practice). The following Thread in the example below is in BLOCK state which typically means it is waiting to acquire a lock on an Object monitor. You will need to search in the earlier section and determine which Thread is holding the lock so you can pinpoint the root cause. 3XMTHREADINFO "[STUCK] ExecuteThread: '162' for queue: 'weblogic.kernel.Default (self-tuning)'" J9VMThread:0x000000013ACF0800, j9thread_t:0x000000013AC88B20, java/lang/Thread:0x070000001F945798, state:B, prio=13XMTHREADINFO1 (native thread ID:0x1AD0F3, native priority:0x1, native policy:UNKNOWN)3XMTHREADINFO3 Java callstack:4XESTACKTRACE at org/springframework/jms/connection/SingleConnectionFactory.createConnection(SingleConnectionFactory.java:207(Compiled Code))4XESTACKTRACE at org/springframework/jms/connection/SingleConnectionFactory.createQueueConnection(SingleConnectionFactory.java:222(Compiled Code))4XESTACKTRACE at org/springframework/jms/core /JmsTemplate102.createConnection(JmsTemplate102.java:169(Compiled Code))4XESTACKTRACE at org/springframework/jms/core /JmsTemplate.execute(JmsTemplate.java:418(Compiled Code))4XESTACKTRACE at org/springframework/jms /core/JmsTemplate.send(JmsTemplate.java:475(Compiled Code))4XESTACKTRACE at org/springframework/jms /core/JmsTemplate.send(JmsTemplate.java:467(Compiled Code)) …………………………………………………………………………………………………………# JVM class loader summary Finally, the last section of the IBM VM Thread Dump provides you with a detailed class loader summary. This is very crucial data when dealing with Class Loader related issues and leaks. You will find the number and type of loaded Classes for each active Class loader in the running JVM. I suggest that you review the following case study for a complete tutorial on how to pinpoint root cause for this type of issues when using IBM VM. http://javaeesupportpatterns.blogspot.com/2011/04/class-loader-memory-leak-debugging.html 0SECTION CLASSES subcomponent dump routineNULL =================================1CLTEXTCLLOS Classloader summaries1CLTEXTCLLSS 12345678: 1=primordial,2=extension,3=shareable ,4=middleware,5=system,6=trusted,7=application,8=delegating2CLTEXTCLLOADER p---st-- Loader *System*(0x0700000000878898)3CLNMBRLOADEDLIB Number of loaded libraries 63CLNMBRLOADEDCL Number of loaded classes 37212CLTEXTCLLOADER -x--st-- Loader sun/misc /Launcher$ExtClassLoader(0x0700000000AE8F40), Parent *none*(0x0000000000000000)3CLNMBRLOADEDLIB Number of loaded libraries 03CLNMBRLOADEDCL Number of loaded classes 912CLTEXTCLLOADER -----ta- Loader sun/misc/Launcher$AppClassLoader(0x07000000008786D0) , Parent sun/misc/Launcher$ExtClassLoader(0x0700000000AE8F40)3CLNMBRLOADEDLIB Number of loaded libraries 33CLNMBRLOADEDCL Number of loaded classes 15178 ……………………………………………………………………………………………I hope this article has helped to understand the basic view of an IBM VM Thread Dump. The next article (part 5) will provide you with a tutorial on how to analyze a JVM Thread Dump via a step by step tutorial and technique I have used over the last 10 years. Reference: How to analyze Thread Dump – Part 4: IBM VM from our JCG partner Pierre-Hugues Charbonneau at the Java EE Support Patterns & Java Tutorial blog....
oracle-jdeveloper-logo

Java Decompiler in JDeveloper

Java Decompiler is a standalone graphical utility that displays Java source codes of  “.class” files. Below is snapshot of Java Decompiler programYou can download this program from here I will illustrate how to use this program as External Tool in Jdeveloper Integration between Java Decompiler and Jdeveloper You can add this program to external programs in Jdeveloper and integrate it to open class files located in Jdeveloper Follow below step: 1-open Tools menu > External Tools.. from Jdeveloper2-Click New button to add new external program to Jdeveloper  3-Choose Tool type External Program and then click Next4-Enter program path at your machine in program executable and enter ${file.path} in Arguments and click on next5-You can write name that will be displayed in context menu later for example Java Decompiler and then click next6-Check check boxes like the below image and then click next and then Finish7- Now you can allocate any class file in application navigator and right click it and then choose Java Decompiler from context menu  8- It will open Java Decompiler program and it automatically open source code of UcmClient.class Reference: Java Decompiler in Jdeveloper from our JCG partner Mahmoud A. ElSayed at the Dive in Oracle blog....
google-logo

Spring vs Guice: The one critical difference that matters

Spring objects are recognized based on their namesIt doesn’t matter whether you use XML or Java config, a Spring scope is roughly like a Map<String, Object> structure. This means that you cannot have two objects with the same name. Why is this a bad thing? If you have a large application with lots of @Configuration classes or XML files, it’s very easy to accidentally use the same name twice.The worst part of this is that using the same with several objects, they silently override each other until only one actually remains in the ApplicationContext. These objects can also be of different types and the declaration order is what really determines which object wins. The problem here is that if you want to make reusable modules based on Spring, you will basically be forced to use a prefix in the name or something else to ensure you won’t have a name clash.Guice objects are recognized based on their classesA Guice scope is basically like a Map<Class<?>, Object> structure. This means that you cannot have two objects of the same type without using extra metadata (e.g. qualifiers). This design choice has different pros and cons, but overall I think it’s the saner one. If you create reusable modules, you mostly have to make sure that you don’t export any objects of common types (e.g. String). With type-based scopes you can always create a wrapped class for common types, while with name-based scopes you would always have to use unique names based on lucky guesses. Guice also has PrivateModules so you can use Guice for all injection, but only export some of the objects in the scope.  Example codeHere’s a naive example of a Spring application that breaks runtime because of silent bean overriding. Main.java This class instantiates the application context, registers the configuration classes and tries to get a MyBean from the context. package springbreak;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();ctx.register(GoodConfig.class); ctx.register(EvilConfig.class);ctx.refresh(); ctx.start();System.out.println(ctx.getBean(MyBean.class).getValue());ctx.stop(); } } MyBean.java This is just an example type of bean that we expect to get from the application context. package springbreak;public interface MyBean { String getValue(); } GoodConfig.java This is a configuration class that exports a MyBean package springbreak;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class GoodConfig {private static class MyBeanImpl implements MyBean { public String getValue() { return "I'm a bean"; } }@Bean public MyBean myBean() { return new MyBeanImpl(); }} EvilConfig.java This configuration class exports a String with the name myBean. It’s not a very realistic example but shows the basic idea. package springbreak;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class EvilConfig {@Bean public String myBean() { return "I'm a string!"; }} Analyzing the exampleCan you guess what happens when you run the example? Here’s the basic idea:GoodConfig exports a MyBeanImpl with the name “myBean” EvilConfig exports a String with the name “myBean” replacing the one from GoodConfig even though the types won’t match Main gets a NoSuchBeanDefinitionException “No unique bean of type [springbreak.MyBean] is defined” So, basically a MyBeanImpl is replaced by a String and there won’t be a bean that implements MyBean. The worst part is that if you reverse the @Configuration class registration order, the code will work because then a String will be replaced by a MyBeanImpl. Now, imagine you have 20 nicely encapsulated modules with potentially conflicting names…I’ve banged my head against the wall several times trying to debug problems in a situation like that.Spring (as of version 3.0.6) offers no possibility to alter the naming of @Configuration class exported beans. If you want to create safely reusable modules, you will have to use some kind of fully qualified names in the methods that export beans (e.g goodConfigMyBean, evilConfigMyBean).I like Spring (especially non-DI-container parts), but in new projects I will refuse to use a library that is so fundamentally broken. And yes, using the same name twice is a developer error, but any library that is prone to such errors can be considered worse than an alternative that attempts to minimize them. Reference: Spring vs Guice: The one critical difference that matters from our JCG partner Joonas Javanainen at the Jawsy Solutions technical blog blog....
enterprise-java-logo

Expose Java service as a web service

This tutorial addresses a most practical scenario which is being faced by a developer. Most of the time, We may need to expose some of our existing services as web services. This situation can be encountered in different stages of project life cycle. If It is the initial stage, then You are almost safe and You can well prepare for that. But, What will happen, this requirement comes just after half of the development has finished or the system is running in production environment. This will be little tricky if the web services have not been taken into consideration for initial project architecture. You may involve with different kind of project architectures and use different kind of technologies. As a developer, You are not allowed to change some architectural stuff and configurations since there may be lots of dependencies. Most of the tutorials on the Internet explains the basic stuff of creating a web service. Some time, ‘Hello world’ application or sometime it may be simple calculator like that. These tutorials are good to have the basic understanding about the web services. But the real world scenario’s are ten time complex than that and have to face difficulties when following those kind of tutorials. Practical scenario With this tutorial, I am going to explain, How We really address a real world requirement that came through your supervisor. I am going to explain the same kind of scenario, which I faced recently. A health care organisation is running a plenty of pharmacies all around the island. They have a web application which handles all the inventories, pricing and billing, issuing pharmacy items etc. They needed to expose their pharmacy items prices through a web service so that their client application in the pharmacy can access those via the web service. Their web application has been developed within struts2, spring and hibernated integrated environment. It has all the spring managed DAO classes and also the service classes. The application uses spring’s auto wiring technique, component scanning, transaction management etc. With these kind of background, I needed to expose pharmacy item prices as a web service. That is some of the methods from our current pharmacy service are needed to be exposed to outside via a web service. I will show you, How to achieve this kind of requirement with a minimal modification to our existing project. Additional Libraries I am going to implement the web service with JAX-WS. I have used JAX-WS 2.2 for my project. You can download the required JAX-WS version from here. This provides few tools that can be used to generate web service and it’s client stuff. After downloading the required version of library, extract it some where in your local machine. I have placed it in my home folder. ie: /home/semika/jaxws-ri-2.2 Implementing web service I already have spring managed service classes and DAO classes for pharmacy item which are being used internally by the web application. Those are not exposed to out side. Suppose, We need to expose findAll() method which returns a list of ‘PharmacyItem’ of ‘PharmacyService’ interface as a web service. For Your convenience, I will show you the ‘PharmacyServiceImpl’ java class which is used to perform normal pharmacy item operations. This is a usual spring mange bean. Keep in mind, methods of this class can only be used for internal operations of our web application currently. Those are not exposed as web services. PharmacyServiceImpl.java /** * */ package com.slauto.service.pharmacy.impl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import com.slauto.exceptions.ServiceException; import com.slauto.model.pharmacy.PharmacyItem; import com.slauto.persist.pharmacy.api.PharmacyItemDao; import com.slauto.service.pharmacy.api.PharmacyItemService;/** * @author semika * */ @Service('pharmacyItemService') public class PharmacyItemServiceImpl implements PharmacyItemService {@Autowired private PharmacyItemDao pharmacyItemDao; @Override public List<Pharmacyitem> findAll() throws ServiceException { return pharmacyItemDao.findAllPharmacyItems(); } } As You can see, I have auto wired instance of ‘PharmacyItemDao’ with in the implementation class. As We all know, this is a spring managed service implementation class. Next, We will implement the web service end point class for above spring managed service bean to expose it’s methods as a web service methods. For the clarity, I created a separate class as web service end point. PharmacyItemServiceEndPoint.java package com.slauto.service.ws; import javax.jws.WebMethod; import javax.jws.WebService;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.slauto.exceptions.DataAccessException; import com.slauto.model.pharmacy.PharmacyItem; import com.slauto.service.pharmacy.api.PharmacyItemService;/** * @author semika * */ @WebService(serviceName='pharmacyItemService') public class PharmacyItemServiceEndPoint { @WebMethod public List<Pharmacyitem> findAll() throws DataAccessException { ApplicationContext context = new ClassPathXmlApplicationContext('applicationContext.xml'); PharmacyItemService pharmacyItemService = (PharmacyItemService)context.getBean('pharmacyItemService'); return pharmacyItemService.findAll(); } } As You can see here, I am using ‘pharmacyItemService’ bean which is used by our web application to access the relevant service method. The ‘pharmacyItemService’ is a usual spring mange bean which is used to perform day to day pharmacy item operation. Nothing special on that. Specially note that @WebService and @WebMethod annotation which indicates this class works as a web service end point. Here, I am getting service class instance via application context. Further, We can auto wire web service end point classes with spring by extending end point classes from ‘ SpringBeanAutowiringSupport‘ provided by spring. In that case, We do not need to create application context instance as I have done above. I could not make that work, that is why, I used the above technique. With ‘ SpringBeanAutowiringSupport‘, when deploying web service (explain bellow), I encountered an exception which was hard for me to resolve that. So I choose this technique. Any way, I do not like, what I have used above :) . Generating web service I am using a apt, wsgen and wsimport tools provided by JAX-WS to generate the portable artefacts used in JAX-WS services. The relevant ant targets for the ‘ build.xml‘ file will be as follows. Your may need following property declared at the top of the ‘build.xml’ file. Property: <property name='tomcat.home' value='/home/semika/apache-tomcat-7.0.25' /> <property name='jaxws.home' value='/home/semika/jaxws-ri-2.2' /> <property name='build.classes.home' value='${basedir}/WEB-INF/classes' /> <property name='java.home' value='/home/semika/java/jdk1.6.0_30'> Class path: <path id='project.class.path'> <pathelement location='${java.home}/../lib/tools.jar' /> <fileset dir='${jaxws.home}/lib'> <include name='*.jar' /> </fileset> <pathelement location='${basedir}/WEB-INF/classes' /> <fileset dir='${basedir}/WEB-INF/lib' includes='*.jar' /> </path> JAX-WS apt tool target: <target name='apt' depends='javac'> <taskdef name='apt' classname='com.sun.tools.ws.ant.Apt'> <classpath refid='project.class.path' /> </taskdef> <apt fork='true' debug='true' verbose='true' destdir='${basedir}/WEB-INF/classes' sourcedestdir='${basedir}/WEB-INF/src' sourcepath='${basedir}/WEB-INF/src'> <classpath> <path refid='project.class.path' /> </classpath> <option key='r' value='${basedir}/WEB-INF' /> <source dir='${basedir}/WEB-INF/src'> <include name='**/*.java'/> </source> </apt> </target> If you want to know further about apt tool provided by JAX-WS, look into this. When running apt target, it scans the source path (src folder) and generates the required *.class and *.java files for the classes annotated with @WebService. In this case, for ‘PharmacyItemServiceEndPoint.java’. If You look into the package where ‘PharmacyItemServiceEndPoint’ is in, You can see, it has a new package called ‘ jaxws‘ created. Inside that package, I could see following three java files. DataAccessExceptionBean.java FindAll.java FindAllResponse.java These classes are generated by the tool and it varies based on your service implementation and dependent classes which you are involving to your web service. Actually, you don’t need to much worry about these generated stuff. Similarly, You can see the relevant *.class files under /WEB-INF/classes folder. JAX-WS wsgen tool target: <target name='wsgen' depends='apt'> <taskdef name='wsgen' classname='com.sun.tools.ws.ant.WsGen'> <classpath path='project.class.path'/> </taskdef> <wsgen xendorsed='true' sei='com.slauto.service.ws.PharmacyItemServiceEndPoint' destdir='${basedir}/WEB-INF/classes' resourcedestdir='${wsdl.dir}' sourcedestdir='${basedir}/WEB-INF/src' keep='true' verbose='true' genwsdl='true'> <classpath refid='project.class.path'/> </wsgen> </target> The wsgen tool will generate the WSDL file for our end point web service class. After running this target, have a look on ${wsdl.dir} location. You can see our WSDL file has been generated. If you want to know further about wsgen tool provided by JAX-WS, look into this. Deploying Web service I wanted to deploy the web service with the usual server start up. SoI had to add the following configuration into the web.xml file. <listener> <listener-class> com.sun.xml.ws.transport.http.servlet.WSServletContextListener </listener-class> </listener> <servlet> <servlet-name>pharmacyItemService</servlet-name> <servlet-class> com.sun.xml.ws.transport.http.servlet.WSServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>pharmacyItemService</servlet-name> <url-pattern>/pharmacyItemService</url-pattern> </servlet-mapping> As I told you before when deploying the web service with the end point class extended from ‘ SpringBeanAutowiringSupport‘, it gives an exception. That is why, I decided to get the service bean via application context. If you manage this situation, please just post it. And also, You need to create sun-jaxws.xml under the WEB-INF folder and declare the web service end point as follows. <?xml version='1.0' encoding='UTF-8'?> <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'> <endpoint name='pharmacyItemService' implementation='com.slauto.service.ws.PharmacyItemServiceEndPoint' url-pattern='/pharmacyItemService'/> </endpoints> I am using apache tomcat 7.0.25 to deploy the web service. You will need to tell tomcat where it can find JAX-WS libraries when the tomcat is starting up. You can edit the ‘ catalina.properties‘ file located in CATALINA_HOME/conf folder. Look for the common.loader property. It will mostly look like follows. common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar Modify it as follows. common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,/home/semika/jaxws-ri-2.2/lib/*.jar As You can see, I have added my JAX-WS library path at the end of comma separated list. These classes are made visible to both tomcat internal classes and to all web applications deployed in the tomcat container. Now, You can copy your .war file into tomcat’s webapps folder and start the tomcat. Your web service should be deployed. To confirm your web service is deployed properly, You can check for it’s WSDL. For WSDL file, You should check the URL in following format. http://localhost:8080/<your context name>/pharmacyItemService?wsdl If You can see your WSDL file on the browser, You are done, You have success fully deployed the web service. Generating Web service client Now, We have a deployed web service. Next, We will see how to write client class to access the web service with java program. You can create a simple java project and use the following build.xml file there. I have placed the complete build.xml file for client generation. I am using wsimport tool coming with JAX-WS to generate the web service client artefacts. <?xml version='1.0' encoding='utf-8' ?> <project name='WS-client' default='wsimport' basedir='.'> <property name='jaxws.home' value='/home/semika/jaxws-ri-2.2' /> <property name='java.home' value='/home/semika/java/jdk1.6.0_30'/> <path id='jaxws.classpath'> <pathelement location='${java.home}/../lib/tools.jar' /> <fileset dir='${jaxws.home}/lib'> <include name='*.jar' /> </fileset> </path> <target name='wsimport'> <taskdef name='wsimport' classname='com.sun.tools.ws.ant.WsImport'> <classpath path='jaxws.classpath'/> </taskdef> <wsimport xendorsed='true' debug='true' verbose='true' keep='true' destdir='src' package='com.slauto.service' wsdl='http://localhost:8080/slautomanage/pharmacyItemService?wsdl'> </wsimport> </target> </project> If You want to know further about wsimport tool, you can look into this. After running the above target, just have a look on the package where you have specified under wsimport attributes. You will see set of java files generated. You can compile and bundle these into a single client.jar file and can be used with any of the java project which need this web service. I have created very simple java class to fetch the pharmacy items information through the web service. Client.java package com.slauto.client;import java.util.List;import com.slauto.service.PharmacyItem; import com.slauto.service.PharmacyItemService; import com.slauto.service.PharmacyItemServiceEndPoint;/** * @author semika * */ public class Client {/** * @param args */ public static void main(String[] args) { PharmacyItemService p = new PharmacyItemService(); PharmacyItemServiceEndPoint ep = p.getPharmacyItemServiceEndPointPort(); List<PharmacyItem> pharmacyItems = ep.findAll(); for (PharmacyItem pharmacyItem : pharmacyItems) { System.out.println(pharmacyItem.getCode()); } } } It is wonderful isn’t it ?. You will see list of pharmacy item codes displayed just after running this class. These pharmacy information are coming through web service deployed by a web application developed with heavily complicated environment. That is it from this tutorial. I hope this will be helpful for you and if you pick something up from this tutorial, don’t forget to put a comment. Reference: How to expose an exsisting service as a web service ? from our JCG partner Semika loku kaluge at the Code Box blog....
jboss-resteasy-logo

RESTEasy Tutorial Part-1: Basics

RESTEasy is a JAX-RS implementation from JBoss/RedHat and is in-built in JBoss 6 onwards. Here I am going to show you how to develop a Simple RESTful Web Services application using RESTEasy and JBossAS7.1.1.FINAL.                 Step#1: Configure RESTEasy dependencies using Maven. <project xmlns='http:maven.apache.orgPOM4.0.0' xmlns:xsi='http:www.w3.org2001XMLSchema-instance' xsi:schemaLocation='http:maven.apache.orgPOM4.0.0 http:maven.apache.orgmaven-v4_0_0.xsd'> <modelVersion>4.0.0<modelVersion> <groupId>com.sivalabs<groupId> <artifactId>resteasy-demo<artifactId> <version>0.1<version> <packaging>war<packaging> <name>resteasy-demo Maven Webapp<name> <build> <finalName>resteasy-demo<finalName> <build> <dependencies> <dependency> <groupId>junit<groupId> <artifactId>junit<artifactId> <version>4.8.2<version> <scope>test<scope> <dependency> <dependency> <groupId>org.jboss.resteasy<groupId> <artifactId>resteasy-jaxrs<artifactId> <version>2.3.2.FINAL<version> <scope>provided<scope> <dependency> <dependency> <groupId>org.jboss.resteasy<groupId> <artifactId>resteasy-jaxb-provider<artifactId> <version>2.3.2.FINAL<version> <scope>provided<scope> <dependency> <dependency> <groupId>org.jboss.resteasy<groupId> <artifactId>jaxrs-api<artifactId> <version>2.3.0.GA<version> <scope>provided<scope> <dependency> <dependency> <groupId>org.apache.httpcomponents<groupId> <artifactId>httpclient<artifactId> <version>4.1.2<version> <scope>provided<scope> <dependency> <dependencies> <project> Step#2: Configure RESTEasy in web.xml <web-app xmlns:xsi='http:www.w3.org2001XMLSchema-instance' xmlns='http:java.sun.comxmlnsjavaee' xmlns:web='http:java.sun.comxmlnsjavaeeweb-app_2_5.xsd' xsi:schemaLocation='http:java.sun.comxmlnsjavaee http:java.sun.comxmlnsjavaeeweb-app_3_0.xsd' id='WebApp_ID' version='3.0'> <listener> <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap<listener-class> <listener> <servlet> <servlet-name>Resteasy<servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher<servlet-class> <servlet> <servlet-mapping> <servlet-name>Resteasy<servlet-name> <url-pattern>rest*<url-pattern> <servlet-mapping> <context-param> <param-name>resteasy.servlet.mapping.prefix<param-name> <param-value>rest<param-value> <context-param> <context-param> <param-name>resteasy.scan<param-name> <param-value>true<param-value> <context-param> <web-app> Step#3: Create User domain class, MockUserTable class to store User objects in-memory for testing purpose and UserResource class to expose CRUD operations on User as RESTful webservices. package com.sivalabs.resteasydemo; import java.util.Date; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class User { private Integer id; private String name; private String email; private Date dob; setters and getters } package com.sivalabs.resteasydemo; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import com.sivalabs.resteasydemo.User; public class MockUserTable { private static Map<Integer, User> USER_MAP = new HashMap<Integer, User>(); static { USER_MAP.put(1, new User(1,'admin','admin@gmail.com',new Date())); USER_MAP.put(2, new User(2,'test','test@gmail.com',new Date())); } public static void save(User user){ USER_MAP.put(user.getId(), user); } public static User getById(Integer id){ return USER_MAP.get(id); } public static List<User> getAll(){ List<User> users = new ArrayList<User>(USER_MAP.values()); return users; } public static void delete(Integer id){ USER_MAP.remove(id); } } package com.sivalabs.resteasydemo; import java.util.List; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import com.sivalabs.resteasydemo.MockUserTable; @Path('users') @Produces(MediaType.APPLICATION_XML) public class UserResource { @Path('') @GET public Response getUsersXML() { List<User> users = MockUserTable.getAll(); GenericEntity<List<User>> ge = new GenericEntity<List<User>>(users){}; return Response.ok(ge).build(); } @Path('{id}') @GET public Response getUserXMLById(@PathParam('id') Integer id) { return Response.ok(MockUserTable.getById(id)).build(); } @Path('') @POST public Response saveUser(User user) { MockUserTable.save(user); return Response.ok('<status>success<status>').build(); } @Path('{id}') @DELETE public Response deleteUser(@PathParam('id') Integer id) { MockUserTable.delete(id); return Response.ok('<status>success<status>').build(); } } Step#6: JUnit TestCase to test the REST Webservice. package com.sivalabs.resteasydemo; import java.util.List; import org.jboss.resteasy.client.ClientRequest; import org.jboss.resteasy.client.ClientResponse; import org.jboss.resteasy.util.GenericType; import org.junit.Assert; import org.junit.Test; import com.sivalabs.resteasydemo.User; public class UserResourceTest { static final String ROOT_URL = 'http:localhost:8080resteasy-demorest'; @Test public void testGetUsers() throws Exception { ClientRequest request = new ClientRequest(ROOT_URL+'users'); ClientResponse<List<User>> response = request.get(new GenericType<List<User>>(){}); List<User> users = response.getEntity(); Assert.assertNotNull(users); } @Test public void testGetUserById() throws Exception { ClientRequest request = new ClientRequest(ROOT_URL+'users1'); ClientResponse<User> response = request.get(User.class); User user = response.getEntity(); Assert.assertNotNull(user); } @Test public void testSaveUser() throws Exception { User user = new User(); user.setId(3); user.setName('User3'); user.setEmail('user3@gmail.com'); ClientRequest request = new ClientRequest(ROOT_URL+'users'); request.body('applicationxml', user); ClientResponse<String> response = request.post(String.class); String statusXML = response.getEntity(); Assert.assertNotNull(statusXML); } @Test public void testDeleteUser() throws Exception { ClientRequest request = new ClientRequest(ROOT_URL+'users2'); ClientResponse<String> response = request.delete(String.class); String statusXML = response.getEntity(); Assert.assertNotNull(statusXML); } } Step#7: To test the REST service we can use the REST Client Tool. You can download REST Client Tool at http://code.google.com/a/eclipselabs.org/p/restclient-tool/ Important Things to Keep in mind: 1. org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap Listener should be registered before any other listener. 2. You should configure resteasy.servlet.mapping.prefix <context-param> if the HttpServletDispatcher servlet url-pattern is anything other than /* Continue to the second part of this tutorial.Reference: RESTEasy Tutorial Part-1: Basics from our JCG partner Siva Reddy at the My Experiments on Technology blog....
jboss-resteasy-logo

RESTEasy Tutorial Part-2: Spring Integration

RESTEasy provides support for Spring integration which enables us to expose Spring beans as RESTful WebServices.                     Step#1: Configure RESTEasy+Spring dependencies using Maven. <project xmlns='http:maven.apache.orgPOM4.0.0' xmlns:xsi='http:www.w3.org2001XMLSchema-instance' xsi:schemaLocation='http:maven.apache.orgPOM4.0.0 http:maven.apache.orgmaven-v4_0_0.xsd'> <modelVersion>4.0.0<modelVersion> <groupId>com.sivalabs<groupId> <artifactId>resteasy-demo<artifactId> <version>0.1<version> <packaging>war<packaging> <properties> <project.build.sourceEncoding>UTF-8<project.build.sourceEncoding> <org.springframework.version>3.1.0.RELEASE<org.springframework.version> <slf4j.version>1.6.1<slf4j.version> <java.version>1.6<java.version> <junit.version>4.8.2<junit.version> <resteasy.version>2.3.2.Final<resteasy.version> <properties> <build> <finalName>resteasy-demo<finalName> <build> <dependencies> <dependency> <groupId>junit<groupId> <artifactId>junit<artifactId> <scope>test<scope> <dependency> <dependency> <groupId>org.slf4j<groupId> <artifactId>slf4j-api<artifactId> <version>${slf4j.version}<version> <dependency> <dependency> <groupId>org.slf4j<groupId> <artifactId>jcl-over-slf4j<artifactId> <version>${slf4j.version}<version> <scope>runtime<scope> <dependency> <dependency> <groupId>org.slf4j<groupId> <artifactId>slf4j-log4j12<artifactId> <version>${slf4j.version}<version> <scope>runtime<scope> <dependency> <dependency> <groupId>log4j<groupId> <artifactId>log4j<artifactId> <version>1.2.16<version> <scope>runtime<scope> <dependency> <dependency> <groupId>org.springframework<groupId> <artifactId>spring-context-support<artifactId> <version>${org.springframework.version}<version> <exclusions> <exclusion> <artifactId>commons-logging<artifactId> <groupId>commons-logging<groupId> <exclusion> <exclusions> <dependency> <dependency> <groupId>org.springframework<groupId> <artifactId>spring-web<artifactId> <version>${org.springframework.version}<version> <dependency> <dependency> <groupId>org.jboss.resteasy<groupId> <artifactId>resteasy-jaxrs<artifactId> <version>${resteasy.version}<version> <scope>provided<scope> <dependency> <dependency> <groupId>org.jboss.resteasy<groupId> <artifactId>resteasy-jaxb-provider<artifactId> <version>${resteasy.version}<version> <scope>provided<scope> <dependency> <dependency> <groupId>org.jboss.resteasy<groupId> <artifactId>jaxrs-api<artifactId> <version>2.3.0.GA<version> <scope>provided<scope> <dependency> <dependency> <groupId>org.jboss.resteasy<groupId> <artifactId>resteasy-spring<artifactId> <version>2.3.0.GA<version> <exclusions> <exclusion> <artifactId>commons-logging<artifactId> <groupId>commons-logging<groupId> <exclusion> <exclusion> <artifactId>org.jboss.resteasy<artifactId> <groupId>resteasy-jaxb-provider<groupId> <exclusion> <exclusion> <artifactId>jaxb-impl<artifactId> <groupId>com.sun.xml.bind<groupId> <exclusion> <exclusion> <artifactId>sjsxp<artifactId> <groupId>com.sun.xml.stream<groupId> <exclusion> <exclusion> <artifactId>jsr250-api<artifactId> <groupId>javax.annotation<groupId> <exclusion> <exclusion> <artifactId>resteasy-jaxb-provider<artifactId> <groupId>org.jboss.resteasy<groupId> <exclusion> <exclusion> <artifactId>activation<artifactId> <groupId>javax.activation<groupId> <exclusion> <exclusions> <dependency> <dependency> <groupId>javax.servlet<groupId> <artifactId>servlet-api<artifactId> <version>2.5<version> <scope>provided<scope> <dependency> <dependency> <groupId>org.apache.httpcomponents<groupId> <artifactId>httpclient<artifactId> <version>4.1.2<version> <dependency> <dependencies> <project> Step#2: Configure RESTEasy+Spring in web.xml <web-app xmlns:xsi='http:www.w3.org2001XMLSchema-instance' xmlns='http:java.sun.comxmlnsjavaee' xmlns:web='http:java.sun.comxmlnsjavaeeweb-app_2_5.xsd' xsi:schemaLocation='http:java.sun.comxmlnsjavaee http:java.sun.comxmlnsjavaeeweb-app_3_0.xsd' id='WebApp_ID' version='3.0'> <listener> <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap<listener-class> <listener> <listener> <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener<listener-class> <listener> <servlet> <servlet-name>Resteasy<servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher<servlet-class> <servlet> <servlet-mapping> <servlet-name>Resteasy<servlet-name> <url-pattern>rest*<url-pattern> <servlet-mapping> <context-param> <param-name>contextConfigLocation<param-name> <param-value>classpath:applicationContext.xml<param-value> <context-param> <context-param> <param-name>resteasy.servlet.mapping.prefix<param-name> <param-value>rest<param-value> <context-param> <context-param> <param-name>resteasy.scan<param-name> <param-value>true<param-value> <context-param> <web-app> Step#3: Create a Spring Service class UserService and update UserResource to use UserService bean. package com.sivalabs.resteasydemo; import java.util.List; import org.springframework.stereotype.Service; import com.sivalabs.resteasydemo.MockUserTable; @Service public class UserService { public void save(User user){ MockUserTable.save(user); } public User getById(Integer id){ return MockUserTable.getById(id); } public List<User> getAll(){ return MockUserTable.getAll(); } public void delete(Integer id){ MockUserTable.delete(id); } } package com.sivalabs.resteasydemo; import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component @Path('users') @Produces(MediaType.APPLICATION_XML) @Consumes(MediaType.APPLICATION_XML) public class UserResource { @Autowired private UserService userService; @Path('') @GET public Response getUsersXML() { List<User> users = userService.getAll(); GenericEntity<List<User>> ge = new GenericEntity<List<User>>(users){}; return Response.ok(ge).build(); } @Path('{id}') @GET public Response getUserXMLById(@PathParam('id') Integer id) { User user = userService.getById(id); return Response.ok(user).build(); } @Path('') @POST public Response saveUser(User user) { userService.save(user); return Response.ok('<status>success<status>').build(); } @Path('{id}') @DELETE public Response deleteUser(@PathParam('id') Integer id) { userService.delete(id); return Response.ok('<status>success<status>').build(); } } package com.sivalabs.resteasydemo; import java.util.List; import org.springframework.stereotype.Service; import com.sivalabs.resteasydemo.MockUserTable; @Service public class UserService { public void save(User user){ MockUserTable.save(user); } public User getById(Integer id){ return MockUserTable.getById(id); } public List<User> getAll(){ return MockUserTable.getAll(); } public void delete(Integer id){ MockUserTable.delete(id); } } package com.sivalabs.resteasydemo; import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component @Path('users') @Produces(MediaType.APPLICATION_XML) @Consumes(MediaType.APPLICATION_XML) public class UserResource { @Autowired private UserService userService; @Path('') @GET public Response getUsersXML() { List<User> users = userService.getAll(); GenericEntity<List<User>> ge = new GenericEntity<List<User>>(users){}; return Response.ok(ge).build(); } @Path('{id}') @GET public Response getUserXMLById(@PathParam('id') Integer id) { User user = userService.getById(id); return Response.ok(user).build(); } @Path('') @POST public Response saveUser(User user) { userService.save(user); return Response.ok('<status>success<status>').build(); } @Path('{id}') @DELETE public Response deleteUser(@PathParam('id') Integer id) { userService.delete(id); return Response.ok('<status>success<status>').build(); } } applicationContext.xml <?xml version='1.0' encoding='UTF-8'?> <beans xmlns='http:www.springframework.orgschemabeans' xmlns:xsi='http:www.w3.org2001XMLSchema-instance' xmlns:p='http:www.springframework.orgschemap' xmlns:context='http:www.springframework.orgschemacontext' xsi:schemaLocation='http:www.springframework.orgschemabeans http:www.springframework.orgschemabeansspring-beans.xsd http:www.springframework.orgschemacontext http:www.springframework.orgschemacontextspring-context.xsd'> <context:annotation-config> <context:component-scan base-package='com.sivalabs.resteasydemo'> <beans> Step#4: Same JUnit TestCase to test the REST Webservice described in Part-1. package com.sivalabs.resteasydemo; import java.util.List; import org.jboss.resteasy.client.ClientRequest; import org.jboss.resteasy.client.ClientResponse; import org.jboss.resteasy.util.GenericType; import org.junit.Assert; import org.junit.Test; import com.sivalabs.resteasydemo.User; public class UserResourceTest { static final String ROOT_URL = 'http:localhost:8080resteasy-demorest'; @Test public void testGetUsers() throws Exception { ClientRequest request = new ClientRequest(ROOT_URL+'users'); ClientResponse<List<User>> response = request.get(new GenericType<List<User>>(){}); List<User> users = response.getEntity(); Assert.assertNotNull(users); } @Test public void testGetUserById() throws Exception { ClientRequest request = new ClientRequest(ROOT_URL+'users1'); ClientResponse<User> response = request.get(User.class); User user = response.getEntity(); Assert.assertNotNull(user); } @Test public void testSaveUser() throws Exception { User user = new User(); user.setId(3); user.setName('User3'); user.setEmail('user3@gmail.com'); ClientRequest request = new ClientRequest(ROOT_URL+'users'); request.body('applicationxml', user); ClientResponse<String> response = request.post(String.class); String statusXML = response.getEntity(); Assert.assertNotNull(statusXML); } @Test public void testDeleteUser() throws Exception { ClientRequest request = new ClientRequest(ROOT_URL+'users2'); ClientResponse<String> response = request.delete(String.class); String statusXML = response.getEntity(); Assert.assertNotNull(statusXML); } }Important Things to Keep in mind: 1. org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap Listener should be registered before any other listener. 2. You should configure resteasy.servlet.mapping.prefix @lt;context-param> if the HttpServletDispatcher servlet url-pattern is anything other than /* 3. You should register REST Resource as Spring bean by annotating with @Component or @Service. Reference: RESTEasy Tutorial Part-2: Spring Integration from our JCG partner Siva Reddy at the My Experiments on Technology blog....
eclipse-logo

Eclipse Project: Releases, Plans, and Reviews

For each release, an Eclipse project is required to provide a project plan. The project plan is created at the beginning of a release cycle and may be modified throughout the cycle. The plan tells the community what the main areas of focus are in the project. This lets, for example, contributors know what kinds of contributions are going to be valuable so they can direct their attention accordingly. It also lets adopters know what to expect from the project for an upcoming release (which may help them to decide to get involved).At the end of a release cycle, an Eclipse project is required to provide a release review document. For project committers, it serves as a retrospective. It is a chance to look back and reflect on the work done, decide what worked and what didn’t work, and start thinking about the next release cycle. For adopters it is confirmation of the plan and a last chance to update their own plans for how they will incorporate the project code into their own development schedule. For the rest of the community, the review document serves as a description of the changes and a way to learn about what’s new, what’s interesting, and what they should care about.Our current system keeps track of all this information in a variety of different locations. Project plans are represented as XML files and are stored somewhere within the Eclipse infrastructure (the website, a source repository, or the download site). Basic information about the release, including the name and date is specified in release records in the project metadata in the Eclipse Developer Portal. Release records are relatively limited in terms of the information they can contain; they are restricted to just the basic information, along with links to the project plan, and new and noteworthy documents.Release review documentation is currently provided in a variety of different formats (e.g. HTML, PDF, PPT, ODP). When a project wants to do a release, they need to tell me. I create a record in the Developer Portal and point that record to the review document that we now store in a corresponding Bugzilla record. Unfortunately, the current system makes no explicit connect connection between the release and the corresponding review document (I’ve added some code that uses some heuristics to figure it out).Sounds awful. Right?The new system that Nathan and I are working on brings all these elements together. A project can specify any number of releases, projecting as far as they’d like into the future. The project plan, rather than being in a separately-managed document, is part of the release record. It can be specified at the beginning of a release cycle and updated throughout. The review information is also attached directly to the release record; it too can be updated throughout the release cycle. I think one of the key benefits is that all of the information is kept together in a very consistent form that can be easily organized and disseminated in different ways. Revision management is built in so it’s easy to tell who made changes, compare and revert changes, and so on.In my opinion, Nathan’s done a great job with the look and feel. Here is what the BIRT project’s 4.2 release looks like:Note the separate tabs for different elements of the release. Note also that this is just display-only: I don’t have the necessary access to edit this project’s releases. I do, however, have access rights to edit information for the Dash project’s releases:When editing, separate tabs provide access to the description, plan, and review items. And, again, there’s revision tracking and management.So the big question: will you use it? Or do we need to provide the ability to attach separate plan and review documents?I’ll be showing this off at EclipseCon 2012 at a BoF. If you can’t attend the BoF, corner me: I’ll be prepared to demo what we have to anybody wants to see it. We’re going to roll out a version of this that you can play with in the weeks following EclipseCon; with a plan to roll it out as a replacement for the Developer Portal and Data-Driven Project Websites post-Juno (i.e. July 2012). Reference: Releases, Plans, and Reviews from our JCG partner Wayne Beaton at the Eclipse Hints, Tips, and Random Musings blog....
enterprise-java-logo

Java JAAS form based authentication

Implementing a login module using JAAS is an of advance topic and also most of the developers have rare chance of involving with this kind of development. But the basic implementation of JAAS login module is not that much hard implementation.That is because, I intended to post this.Here, I am explaining, how to implement a tomcat managed authentication module. This implementation is not container dependent one. We can use it with any container with slight configuration change.As the first step, We need to create a login module class which implements javax.security.auth.spi.LoginModule interface. This interface exposes 5 methods that must be implemented by our login module class. Those are initialize(), login(), commit(), abort(), logout().initialize() method is passed four arguments .The ‘Subject’ is what, We need to authenticate. The subject can represents the related information for a single login user. It can represent identities like ‘username’, ‘password’ etc. And also, it can represents the roles assigned to the user. All these identities should be represent as java.security.Principal. So We should create separate classes to distinguish these entities by implementing java.security.Principal. In my tutorial, I have created separate classes for username, password and role as JAASUserPrincipal, JAASPasswordPrincipal and JAASRolePrincipal. Subject’s getPrincipals() method returns a set of java.security.Principal associated with the subject. To distinguish these, it is important of Creating separate classes for each identity.The ‘ CallbackHandler‘ is used to communicate with the user. When authenticating the user by the login module, the login module invokes the handle() method of the CallbackHandler instance to get the user name and password. We do not want to worry about CallbackHandler instance yet. Because the container manages to provide the required callbakcs. The tomcat provides JAASCallbackHandler for this purpose. But, If We want to invoke the authentication explicitly, We need to create our own call back handler class by implementing the javax.security.auth.callback.CallbackHandler. I will explain this at the end of the tutorial.The next important argument for initialize() method is ‘options’. These options where We declare those in ‘ jass.config‘ file. With the initialisation of login module, map of options declared in ‘jass.config’ file are provided. I will explain the ‘jaas.config’ file of our tutorial later.Next, I will show the full source code for our principal classes. JAASUserPrincipal.java package com.rainyday.server.login;import java.io.Serializable; import java.security.Principal;/** * @author semika * */ public class JAASUserPrincipal implements Principal, Serializable {private String name; /** * @param name */ public JAASUserPrincipal(String name) { if (name == null) { throw new NullPointerException("NULL user name"); } this.name = name; } @Override public String getName() { return name; }@Override public String toString() { return "UserPrincipal [name=" + name + "]"; }@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; }@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; JAASUserPrincipal other = (JAASUserPrincipal) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }JAASRolePrincipal.java package com.rainyday.server.login;import java.io.Serializable; import java.security.Principal;/** * @author semika * */ public class JAASRolePrincipal implements Principal, Serializable {private String name; /** * @param name */ public JAASRolePrincipal(String name) { if (name == null) { throw new NullPointerException("NULL role name"); } this.name = name; }@Override public String getName() { return name; }@Override public String toString() { return "JASSRolePrincipal [name=" + name + "]"; }@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; }@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; JAASRolePrincipal other = (JAASRolePrincipal) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } JAASPasswordPrincipal.java package com.rainyday.server.login;import java.io.Serializable; import java.security.Principal;/** * @author semika * */ public class JAASPasswordPrincipal implements Principal, Serializable {private String name; /** * @param name */ public JAASPasswordPrincipal(String name) { if (name == null) { throw new NullPointerException("NULL password."); } this.name = name; }@Override public String getName() { return name; }@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; }@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; JAASPasswordPrincipal other = (JAASPasswordPrincipal) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; }@Override public String toString() { return "JAASPasswordPrincipal [name=" + name + "]"; }}The above three classes are exactly similar. But, We need to create separate classes for each principal to distinguish them.The login() method of login module performs the authentication. This validates the user entered user name and password with the database. Now, You may have a problem, How login details entered by the user comes into the login() method. As I explained earlier, the call back handler brings the login identities into the login() method. From the login() method, the login module invokes the handle() method of call back handler by passing the required call backs into it. Then handle() method populates those call backs with the required information and make available to login() method.The commit() method is invoked by the login module after the successful authentication. The subject can be populated with associated principals. For example, We can retrieve user assigned roles from the database and attached those to the subject.The next, I will explain the required configurations to work this login module.We should create ‘jass.config’ file and should be placed that file under ‘$CATALINA_HOME/conf‘. The ‘jass.config’ file of this tutorial is as follows. rainyDay { com.rainyday.server.login.JAASLoginModule required dbDriver="com.mysql.jdbc.Driver" dbURL="jdbc:mysql://localhost/rainyday" dbUser="root" dbPassword="abc123" userQuery="select username from secu_user where secu_user.username=? and secu_user.password=?" roleQuery="select secu_user_role.rolename from secu_user, secu_user_role " + "where secu_user.username=secu_user_role.username and secu_user.username=?" debug=true; };‘jass.config’ file should have this similar format. In addition to the login module declaration, You can declare options as your wish. These options are made available by login module with ‘options’ map in initialize() method argument. Additionally, We should tell the tomcat, Where to locate the ‘jaas.config’ file by adding it’s path to JAVA_OPTS environment variable. I have added this into ‘catalina.sh’ file under $CATALINA_HOME/bin as follows. JAVA_OPTS=”$JAVA_OPTS -Djava.security.auth.login.config==../conf/jaas.config” Next, You need to declare the JAASRealm configurations. You can add a new ‘Realm’ entry into the server.xml file under $CATALINA_HOME/conf. In our tutorial, the ‘Realm’ entry is as follows.                   <Realm className="org.apache.catalina.realm.JAASRealm" appName="rainyDay" userClassNames="com.rainyday.server.login.JASSUserPrincipal,com.rainyday.server.login.JAASPasswordPrincipal" roleClassNames="com.rainyday.server.login.JASSRolePrincipal"/>For apache tomcat’s realm configuration, You can view this documentation. The complete source code for our jaas login module. JAASLoginModule.java package com.rainyday.server.login;import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map;import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule;import org.apache.log4j.Logger;/** * @author semika * */ public class JAASLoginModule implements LoginModule { private static Logger LOGGER = Logger.getLogger(JAASLoginModule.class); // initial state private Subject subject; private CallbackHandler callbackHandler; private Map sharedState; private Map options;// configurable option private boolean debug = false; // the authentication status private boolean succeeded = false; private boolean commitSucceeded = false; //user credentials private String username = null; private char[] password = null; //user principle private JAASUserPrincipal userPrincipal = null; private JAASPasswordPrincipal passwordPrincipal = null; public JAASLoginModule() { super(); }@Override public void initialize(Subject subject, CallbackHandler callbackHandler, Map<string, ?=""> sharedState, Map<string, ?=""> options) { this.subject = subject; this.callbackHandler = callbackHandler; this.sharedState = sharedState; this.options = options; debug = "true".equalsIgnoreCase((String)options.get("debug")); }@Override public boolean login() throws LoginException { if (callbackHandler == null){ throw new LoginException("Error: no CallbackHandler available " + "to garner authentication information from the user"); } Callback[] callbacks = new Callback[2]; callbacks[0] = new NameCallback("username"); callbacks[1] = new PasswordCallback("password: ", false); try { callbackHandler.handle(callbacks); username = ((NameCallback)callbacks[0]).getName(); password = ((PasswordCallback)callbacks[1]).getPassword(); if (debug) { LOGGER.debug("Username :" + username); LOGGER.debug("Password : " + password); } if (username == null || password == null) { LOGGER.error("Callback handler does not return login data properly"); throw new LoginException("Callback handler does not return login data properly"); } if (isValidUser()) { //validate user. succeeded = true; return true; } } catch (IOException e) { e.printStackTrace(); } catch (UnsupportedCallbackException e) { e.printStackTrace(); } return false; }@Override public boolean commit() throws LoginException { if (succeeded == false) { return false; } else { userPrincipal = new JAASUserPrincipal(username); if (!subject.getPrincipals().contains(userPrincipal)) { subject.getPrincipals().add(userPrincipal); LOGGER.debug("User principal added:" + userPrincipal); } passwordPrincipal = new JAASPasswordPrincipal(new String(password)); if (!subject.getPrincipals().contains(passwordPrincipal)) { subject.getPrincipals().add(passwordPrincipal); LOGGER.debug("Password principal added: " + passwordPrincipal); } //populate subject with roles. List<string> roles = getRoles(); for (String role: roles) { JAASRolePrincipal rolePrincipal = new JAASRolePrincipal(role); if (!subject.getPrincipals().contains(rolePrincipal)) { subject.getPrincipals().add(rolePrincipal); LOGGER.debug("Role principal added: " + rolePrincipal); } } commitSucceeded = true; LOGGER.info("Login subject were successfully populated with principals and roles"); return true; } }@Override public boolean abort() throws LoginException { if (succeeded == false) { return false; } else if (succeeded == true && commitSucceeded == false) { succeeded = false; username = null; if (password != null) { password = null; } userPrincipal = null; } else { logout(); } return true; }@Override public boolean logout() throws LoginException { subject.getPrincipals().remove(userPrincipal); succeeded = false; succeeded = commitSucceeded; username = null; if (password != null) { for (int i = 0; i < password.length; i++){ password[i] = ' '; password = null; } } userPrincipal = null; return true; } private boolean isValidUser() throws LoginException {String sql = (String)options.get("userQuery"); Connection con = null; ResultSet rs = null; PreparedStatement stmt = null; try { con = getConnection(); stmt = con.prepareStatement(sql); stmt.setString(1, username); stmt.setString(2, new String(password)); rs = stmt.executeQuery(); if (rs.next()) { //User exist with the given user name and password. return true; } } catch (Exception e) { LOGGER.error("Error when loading user from the database " + e); e.printStackTrace(); } finally { try { rs.close(); } catch (SQLException e) { LOGGER.error("Error when closing result set." + e); } try { stmt.close(); } catch (SQLException e) { LOGGER.error("Error when closing statement." + e); } try { con.close(); } catch (SQLException e) { LOGGER.error("Error when closing connection." + e); } } return false; }/** * Returns list of roles assigned to authenticated user. * @return */ private List<string> getRoles() { Connection con = null; ResultSet rs = null; PreparedStatement stmt = null; List<string> roleList = new ArrayList<string>(); try { con = getConnection(); String sql = (String)options.get("roleQuery"); stmt = con.prepareStatement(sql); stmt.setString(1, username); rs = stmt.executeQuery(); if (rs.next()) { roleList.add(rs.getString("rolename")); } } catch (Exception e) { LOGGER.error("Error when loading user from the database " + e); e.printStackTrace(); } finally { try { rs.close(); } catch (SQLException e) { LOGGER.error("Error when closing result set." + e); } try { stmt.close(); } catch (SQLException e) { LOGGER.error("Error when closing statement." + e); } try { con.close(); } catch (SQLException e) { LOGGER.error("Error when closing connection." + e); } } return roleList; } /** * Returns JDBC connection * @return * @throws LoginException */ private Connection getConnection() throws LoginException { String dBUser = (String)options.get("dbUser"); String dBPassword = (String)options.get("dbPassword"); String dBUrl = (String)options.get("dbURL"); String dBDriver = (String)options.get("dbDriver");Connection con = null; try { //loading driver Class.forName (dBDriver).newInstance(); con = DriverManager.getConnection (dBUrl, dBUser, dBPassword); } catch (Exception e) { LOGGER.error("Error when creating database connection" + e); e.printStackTrace(); } finally { } return con; } }The abort() method of the login module will be invoked if something went wrong within the login() or commit() method execution. In this kind of situation, We can not say that the authentication process was successfully completed and the required clean up operations can be done within the abort() method, if the authentication process encountered a failure.We can utilise the ‘options’ map which was initialise within the initialize() method of the login module to get the configuration information declared within the ‘jass.config’ file. You can come up with a good technique to get JDBC connection object. I did not concentrate on that with in this tutorial and only wanted to show you the mechanism, How the things should be done.By now, We have completed the thing which are required for basic JAAS authentication module. Next, We should configure our security constraints in web.xml file. <login-config> <auth-method>FORM</auth-method> <realm-name>rainyDay</realm-name> <form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/error.jsp</form-error-page> </form-login-config> </login-config> <security-role> <role-name>*</role-name> </security-role> <security-constraint> <web-resource-collection> <web-resource-name>Rainy day</web-resource-name> <url-pattern>/</url-pattern> <http-method>POST</http-method> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <role-name>*</role-name> </auth-constraint> </security-constraint> With the above security constraints, if some request comes to a particular resource in the protected area of the application with out the authentication, the request will be redirected to the ‘login’ page. Next, I will show you the simple HTML form which invokes our login module with the submission of the form. <form id="loginForm" name="loginForm" method="post" action="j_security_check"> User Name : <input id="username" type="text" name="j_username" class="textbox"></input> Password : <input id="password" type="password" name="j_password" class="textbox"></input> <input name="login" type="submit" value="LOGIN" id="submit" class="button blue"> </form> So, We are done with that.This is very basic implementation of JAAS. The advantage of this kind of JAAS module is, We can switch to a different login module implementation just with a single configuration change and without doing any modification to our existing code. And also this is container independent. If You want to deploy this with jBoss server, instead of ‘jass.config’, You can use ‘login-config.xml’ file in jboss conf folder. As I promised you to explain, How to invoke this kind of login module explicitly, here it is. There are some circumstances, We need to authenticate a particular user with pragmatically, but still We should use our implemented login module. In this kind of situation, the big problem is providing user identities (user name, password etc) to the our login module. In the above case, We used a ‘CallbackHandler’ class which is ‘JAASCallbackHander’ provided by apache catalina. But, Here We can not use and We have to implement our own call back handler class.JAASCallbackHandler.java package com.rainyday.server.login;import java.io.IOException;import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException;import org.apache.log4j.Logger;/** * @author semika * */ public class JAASCallbackHandler implements CallbackHandler {private static final Logger LOGGER = Logger.getLogger(JAASCallbackHandler.class); private String username = null; private String password = null; /** * @param username * @param password */ public JAASCallbackHandler(String username, String password) { this.username = username; this.password = password; }@Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { LOGGER.info("Callback Handler invoked "); for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { NameCallback nameCallback = (NameCallback) callbacks[i]; nameCallback.setName(username); } else if (callbacks[i] instanceof PasswordCallback) { PasswordCallback passwordCallback = (PasswordCallback) callbacks[i]; passwordCallback.setPassword(password.toCharArray()); } else { throw new UnsupportedCallbackException(callbacks[i], "The submitted Callback is unsupported"); } } } }Next, We have to create an instance of ‘ LoginContext’ to invoke the authentication explicitly. LoginContext lc = null; try { lc = new LoginContext("rainyDay", new JAASCallbackHandler(username, password)); lc.login(); //get the subject. Subject subject = lc.getSubject(); //get principals subject.getPrincipals(); LOGGER.info("established new logincontext"); } catch (LoginException e) { LOGGER.error("Authentication failed " + e); }If We end up with the execution of above code without any exception, that implies the authentication was succeeded. If an exception was encountered, authentication has failed.That’s all from this tutorials. http://docs.oracle.com/javaee/1.4/tutorial/doc/Security5.html was a good tutorial for me to understand login authentication. Reference: Java form based authentication from our JCG partner Semika loku kaluge at the Code Box blog....
software-development-2-logo

Class diagram generation from Java source

UMLGraph allows the declarative specification and drawing of UML class and sequence diagrams. The specification is done in text diagrams, that are then transformed into the appropriate graphical representations.UMLGraph is implemented as a javadoc doclet (a program satisfying the doclet API that specifies the content and format of the output generated by the javadoc tool). Furthermore, the output of UMLGraph needs to be post-processed with the Graphviz dot program. Therefore, to draw class diagrams with UMLGraph class you will need to have javadoc and Graphviz installed on your computer. Maven plugin details UMLGraph can be easily integrated with existing maven based application. Below is the maven plugin details which needs to be configured: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <configuration> <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet> <docletArtifact> <groupId>org.umlgraph</groupId> <artifactId>doclet</artifactId> <version>5.1</version> </docletArtifact> <additionalparam>-horizontal -attributes -enumconstants -enumerations -operations -types -visibility -inferrel -inferdep -hide java.* -inferrel -collpackages java.util.*</additionalparam> <show>public</show> </configuration> </plugin> UMLGraph depends upon Graphviz which must be already installed on the machine. Also in the above maven setting if you configure ‘GRAPHVIZ_HOME’ environment variable you need not specify the docletpath in plugin details. Steps to configure UMLGraphDownload and install Graphviz Set GRAPHVIZ_HOME environment variable. Add the above plugin details in your POM.xml, configure additionalparams per your need. execute ‘mvn javadoc:javadoc’.Sample  Below is the sample generated using above configuration over our Pizza entity pizza_class_diagram.pngMore configuration You can configure this diagram per your needs. Please refer UMLGraph class diagram options for more configuration. Reference: Class diagram generation from Java source from our JCG partner Abhishek Jain at the NS.Infra blog....
eclipse-logo

Eclipse Community Survey 2012

Each year we survey the Eclipse community to gather some insight into what developers are doing with Eclipse and open source. We have published the results and the detailed data is available [xls] [ods]. Embedded version of the report is at the end of this post. Each year there are always some key trends shown in the results [2011 results]. Here are some insights that appeared for me: 1. Git Momentum Continues to Grow Git definitely has the momentum in the source code management market. Git/Github usage increased from 13% (2011) to 27% (2012). Subversion continues to decline but is still the most popular. For the first time this year we broke out Git and Github. I was surprised to see the vast majority of people specify Git (23%) and only 4.5% specify GitHub. This seems to show a lot of internal Git usage. Potentially a great opportunity for tool providers. 2. Maven Usage Accelerating Maven usage increased from 31% (2011) to 42% (2012). This might be a reflection on better integration with Eclipse and Maven. If so, kudos to the m2eclipse project team and Tycho. 3. Spring and EJBs continue to be popular server frameworks. Equinox and OSGi increasing too. Both Spring and EJBs continue to be the most popular frameworks for people doing server side development. Spring continues to be the most popular but EJBs gain some ground in 2012. It was great to see Equinox and OSGi runtimes almost double their usage from 6.8% (2011) to 12.3% (2012) 4. Mobile computing = Android + iOS Not surprisingly, mobile computing is dominated by Android and iOS. More people have deployed mobile applications, 43% have developed internal or external applications, compared to 35% in 2011. Android and Apple iOS continue to dominate as the key platforms. It is a bit surprising that more developers are not using cross platform frameworks. 60% claim to use only the Mobile OS SDK. jQuery Mobile (28.6%) and PhoneGap (17.9%) are the most popular mobile frameworks. 5. What motivates a developer? This year we asked some questions to explore what motivates a developer to participate in open source and spend their free time building applications Motivation to participate in open source projects seems to be driven by 1) sense of responsibility – 54% stated they participate to ‘give back and support’ and 36% due to their belief in the FOSS ethos, 2) learning – 36% claim it is a great way to learn new technologies, and 3) improving the project – 33% claim they participate due to a needed feature or bug fix. Somewhat surprisingly only 11% claimed it was due to being paid to contribute and 6% was an effective way to promote consulting business. We also asked how many developers build software/applications in their free time, outside of work. I was a bit surprised that 84% claimed to spend some amount of personal time developing software. The key reason is to learn new technologies, 74% answered they ‘enjoy programming and learning new technologies’ and 71% ‘keep my skills sharp’. An important lesson for anyone in the software industry that is targeting developers: Make it easy for developer to learn your technology. 6. Corporate policies towards open source becoming more positive Each year we ask what is the corporate policy towards open source participation. It is nice to see we are seeing movement towards more positive policies towards contributions and participation. 61% reported their corporate policies allowed them to actively participate in open source projects compared to 58% in 2011. We definitely need to get more companies to allow active participation but at least we are moving in the right direction. Thank you to everyone that participate in the survey. I always enjoy seeing the results. Please feel free to leave a comment on what you find interesting in the results. Eclipse survey 2012 report [final] View more from IanSkerrett Reference: Eclipse Community Survey Result for 2012 from our JCG partner Ian Skerrett at the Ian Skerrett’s blog blog....
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
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.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books