Authenticate JBoss application using JAAS and LDAP

It is very easy to connect a JBoss to an LDAP server and creating Java EE applications that use the LDAP information for authorization and authentication. Following these simple steps you will be able to configure your JBoss and a web application (configuring an ejb deployment is similar, just read the Java EE API to map the attributes from web.xml to ejb annotations).

For this example I already have an Apache Directory Server running locally, with the sample LDIF with the sevenSeas company imported. You can find the file and tutorial in the Apache DS documentation.

There are two main steps to be able to use LDAP as an authentication mechanism:

  1. Configure JBoss to connect to LDAP server
  2. Configure the application to use the application policy

Configure JBoss to connect to LDAP server

The JBoss connects to the LDAP server using an application-policy, which is configured in %server_path%/conf/login-config.xml
Just add the following entry in the login-config.xml. You can see the description of the important attributes:

  <application-policy name="ApacheDS">
   <authentication>
   <login-module code="org.jboss.security.auth.spi.LdapExtLoginModule" flag="required" >
   <module-option name="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</module-option>
   <module-option name="java.naming.provider.url">ldap://localhost:10389</module-option> <!-- LDAP url-->
   <module-option name="java.naming.security.authentication">simple</module-option>
   <module-option name="bindDN">uid=admin,ou=system</module-option> <!-- LDAP user to connect -->
   <module-option name="bindCredential">secret</module-option> <!-- LDAP password -->
   <module-option name="baseCtxDN">ou=people,o=sevenSeas</module-option>
   <module-option name="baseFilter">(uid={0})</module-option>

   <module-option name="rolesCtxDN">ou=groups,o=sevenSeas</module-option> <!-- context where to search for groups -->
   <module-option name="roleFilter">(uniquemember={1})</module-option> <!-- filter, this searches for groups which have the user set in the attribute 'uniquemember' -->
   <module-option name="roleAttributeID">cn</module-option>
   <module-option name="searchScope">SUBTREE_SCOPE</module-option> <!-- Search for groups in all subtrees -->
   <module-option name="roleRecursion">0</module-option> <!-- how many levels to search recursively inside a group for a user  -->
   <module-option name="allowEmptyPasswords">true</module-option>
   </login-module>
   </authentication>
  </application-policy>

As you can see, the bindCredential is not encrypted. In order to do so, you can check out my post about securing the LdapExtLoginModule

Configure the web application to use the application policy

First, we need to connect the java web application to the application policy defined in JBoss. In order to do this, you need to create the file jboss-web.xml in the WEB-INF folder, the same folder where the web.xml resides.
Here is the content of the file (this works for JBoss 5 in a windows machine, you may need to change the header of the file):

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE jboss-web
    PUBLIC "-//JBoss//DTD Web Application 2.3V2//EN"
    "http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd">

<jboss-web>
  <security-domain>java:/jaas/ApacheDS</security-domain>
</jboss-web>

This will tell the container to use the ApacheDS application-policy we defined previously in JBoss.

After this, we only need to restrict the specific urls or servlets to certain roles. In this example, we will only allow access for users in the group “HMS Bounty”, otherwise a 403 (forbidden) will be issued.
In order to do this, we need to edit the web.xml file, adding the following configuration:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5"
 xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 <servlet>
  <servlet-name>AServlet</servlet-name>
  <servlet-class>com.app.AServlet</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>AServlet</servlet-name>
  <url-pattern>/AServlet</url-pattern> 
 </servlet-mapping>
 
 <!-- ... more servlets and config ...-->
 
 <security-constraint>
  <display-name>All resources</display-name>
  <web-resource-collection>
   <web-resource-name>All resources</web-resource-name>
   <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
   <role-name>HMS Bounty</role-name>
  </auth-constraint>
 </security-constraint>
 <login-config>
  <auth-method>BASIC</auth-method>
 </login-config>

</web-app>

Following this example, you can restrict access to different resources to other roles.

Configure an EJB based WS to use the application policy

If, in turn, you want to secure an EJB based WS, just adding these annotations at the start of the implementing class will do:

@org.jboss.wsf.spi.annotation.WebContext(contextRoot="MyCtxRoot" , authMethod = "BASIC", secureWSDLAccess = false)
@org.jboss.ejb3.annotation.SecurityDomain( "java:/jaas/ApacheDS" )
@RolesAllowed("HMS Bounty")
public class MyWSImplementation implements MyWSInterface{
...

Search LDAP from Java

This post explains how to connect to an LDAP server (in my case Apache DS) and retrieve elements which match a certain filter.

I have deployed an Apache Directory Server version 2.0 and imported the demo LDIF containing users and groups for the “sevenSeas” organization. You can download the file from the apache DS documentation.

This java code connects to the Apache DS deployed locally using the default port and user, and searches the context “ou=groups,o=sevenSeas” for groups the user “Fletcher Christian” belongs to.

import java.util.Properties;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;

public class LdapSearch {
   public static void main(String[] args) throws NamingException {
      InitialLdapContext ctx = constructInitialLdapContext();
      // the name of the context to search
      String contextName = "ou=groups,o=sevenSeas";
      // Filter expression
      String filterExpr = "(uniquemember={0})"; // selects the groups a user belongs to.

      // Filter parameters (name of the user)
      String userDN = "cn=Fletcher Christian,ou=people,o=sevenSeas";
      Object[] filterArgs = { userDN };

      SearchControls constraints = new javax.naming.directory.SearchControls();
      constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); // SUBTREE_SCOPE means recursive search

      NamingEnumeration<SearchResult> search = ctx.search(contextName,
            filterExpr, filterArgs, constraints);
      while (search.hasMoreElements()) {
         System.out.println(search.next().getName());
      }
   }

   private static InitialLdapContext constructInitialLdapContext()
         throws NamingException {
      Properties env = new Properties();
      env.put("java.naming.factory.initial",
            "com.sun.jndi.ldap.LdapCtxFactory");
      // LDAP url
      env.put("java.naming.provider.url", "ldap://localhost:10389");
      // ldap login
      env.put("java.naming.security.principal", "uid=admin,ou=system");
      env.put("java.naming.security.credentials", "secret");

      return new InitialLdapContext(env, null);
   }

}

With the demo LDIF imported in Apache DS the output will be:

cn=HMS Bounty,ou=crews

Access EJB 3.0 in JBoss 5, from JBoss 4 – java.lang.ClassCastException

If you are in a process of migrating JBoss servers you may sometimes need to deploy an EAR in a newer server, while having othres in the older servers, and keep the integration between the apps. I faced this issue when migrating from JBoss 4.3 to JBoss 5, but you may face a similar issue when migrating different versions.

One problem that may arrive when an application in the older server (JBoss 4) tries to access an EJB in the newer (JBoss 5) is this exception when doing a lookup:
java.lang.ClassCastException: javax.naming.Reference cannot be cast to XXX
Being XXX the interface you want to lookup in the JBoss 5 server.

This problem occurs because the application is using by default the client libraries of the JBoss 4 server. To solve this problem, you need to add the client jar files of the JBoss 5 server to the application in JBoss 4.
In order to do this, you need to copy the jars from JBoss 5 jbossall-client.jar and all its dependencies (listed in the META-INF, excluding jnp-client.jar) inside the application EAR file in JBoss 4 (in the lib folder inside the EAR).

This is the full list of jar files that need to be copied from /jboss-as/client inside /lib:
common-annotations.jar
commons-beanutils.jar
commons-collections.jar
commons-digester.jar
commons-logging.jar
concurrent.jar
ejb3-persistence.jar
hibernate-annotations.jar
hibernate-commons-annotations.jar
hibernate-core.jar
hibernate-validator.jar
jboss-aop-client.jar
jboss-appclient.jar
jboss-aspect-jdk50-client.jar
jboss-client.jar
jboss-common-core.jar
jboss-deployers-client-spi.jar
jboss-deployers-client.jar
jboss-deployers-core-spi.jar
jboss-deployers-core.jar
jboss-deployment.jar
jboss-ejb3-common-client.jar
jboss-ejb3-core-client.jar
jboss-ejb3-ext-api-impl.jar
jboss-ejb3-ext-api.jar
jboss-ejb3-proxy-clustered-client.jar
jboss-ejb3-proxy-impl-client.jar
jboss-ejb3-proxy-spi-client.jar
jboss-ejb3-security-client.jar
jboss-ha-client.jar
jboss-ha-legacy-client.jar
jboss-iiop-client.jar
jboss-integration.jar
jboss-j2se.jar
jboss-javaee.jar
jboss-jsr77-client.jar
jboss-logging-jdk.jar
jboss-logging-log4j.jar
jboss-logging-spi.jar
jboss-mdr.jar
jboss-messaging-client.jar
jboss-profileservice-client.jar
jboss-remoting.jar
jboss-security-spi.jar
jboss-serialization.jar
jboss-srp-client.jar
jboss-system-client.jar
jboss-system-jmx-client.jar
jbossall-client.jar
jbosscx-client.jar
jbossjts.jar
jbosssx-as-client.jar
jbosssx-client.jar
jmx-client.jar
jmx-invoker-adaptor-client.jar
jsf-facelets.jar
jsf-tlds.jar
jstl.jar
PagosWebFachada.jar
richfaces-api-3.2.1.GA.jar
richfaces-impl-3.2.1.GA.jar
richfaces-ui-3.2.1.GA.jar
slf4j-api.jar
slf4j-jboss-logging.jar
standard.jar
xmlsec.jar

NOTE: If you fail to copy this list and add also the jnp-client.jar you will get this error when deploying the application:
java.lang.IncompatibleClassChangeError: Class org.jnp.server.NamingServer does not implement the requested interface org.jnp.interfaces.Naming

Getting started with AOP in JBoss 5.1 with a simple example

Introduction

I am writing this post since it took me a while to configure and run my first AOP example in a JBoss application, but I must say after spending some time, I realized it is quite easy, I just couldn’t find a simple example documenting all the needed steps. I hope this post helps you to get quickly started, if that’s the case let me know, or if you ran into other issues. It is always inspiring to read your comments.
In this post I’m not going to introduce Aspect Oriented Programming (AOP), as this is not a recent idea and there are several books you can read. If you need some intro, you can read any of these:

The examples provided in this post will allow you to develop aspects for any class deployed in a JBoss server. If you only want to intercept EJB methods you can use the EJB Interceptors, defined in EJB 3.0. For more info about Interceptors, check out this link and book:

AOP Example in JBoss 5.1

Let’s get started. Reading this link almost did the job, but I still had some things to figure out before everything worked. I also had to take a look at JBoss documentation.
Following these steps you’ll have a very simple and running example of an AOP interceptor which will log calls to methods of a package classes. After having this example up and running, the possibilities are limitless 🙂
I assume you are running with the ‘default’ server configuration. If you use another, you’ll have to ensure you are editing the correct folders (for example, change ‘default’ to ‘all’).

Configure JBoss

  1. Copy the pluggable-instrumentor.jar from the lib/ directory of your JBoss AOP distribution (%JBOSS_PATH%/jboss-as/server/default/deployers/jboss-aop-jboss5.deployer/) to the bin/ directory of your JBoss Enterprise Application Platform.
  2. Edit the startup script of the JBoss server (run.bat or run.sh depending if you are on windows or linux) and add “-javaagent:pluggable-instrumentor.jar” into JAVA_OPTS variable
  3. In case you don’t know, you’ll find this file in %JBOSS_PATH%/jboss-as/bin/.

  4. Edit %JBOSS_PATH%/jboss-as/server/default/conf/bootstrap/aop.xml:
    1. Set the element enableLoadtimeWeaving to “true”
    2. The property will look like

      	<property name="enableLoadtimeWeaving">true</property>
      	
    3. Add to the element include the package you want to instrument or intercept
    4. By default, all packages not listed in the exclude property will be intercepted, so you may skip this step.
      If you choose to explicitly list your package (ie com.mypackage and all subpackages), the include property will look like:

      	<property name="include">org.jboss.test., org.jboss.injbossaop. , com.mypackage. </property>
      	

This is enough to make JBoss run AOP every time you run it with the start scipt. If you want to enable AOP interceptors when running JBoss from Eclipse, you will need to add -javaagent:pluggable-instrumentor.jar to the VM arguments in the server properties.

Logger interceptor

Now, lets build our first AOP interceptor, which will add a log to every call to methods in package and subpackages of com.mypackage.
First, we create an interceptor, a simple Java class which implements org.jboss.aop.advice.Interceptor. In this class we will call invokeNext() to call the original method and log the time taken to run. This is the code:

package com;

import org.apache.log4j.Logger;
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.joinpoint.Invocation;
import org.jboss.aop.joinpoint.MethodInvocation;

public class LogInterceptor implements Interceptor {

	@Override
	public String getName() {
		return "LogInterceptor";
	}

	static Logger logger = Logger.getLogger(LogInterceptor.class);

	@Override
	public Object invoke(Invocation invocation) throws Throwable {
		long time = System.currentTimeMillis();
		try {
			// NEVER FORGET TO CALL invokeNext()
			// unless you want to cancel the call to the destination method
			// (i.e.: a security interceptor)
			return invocation.invokeNext();
		} finally {
			time = System.currentTimeMillis() - time;
			if (invocation instanceof MethodInvocation) {
				MethodInvocation mi = (MethodInvocation) invocation;
				String clazz = "";
				String method = "";
				try {
					clazz = mi.getTargetObject().getClass().toString();
					method = mi.getMethod().getName();
				} catch (Throwable e) {
					logger.error("Error when trying to get target info");
				}
				logger.info("LogInterceptor: " + time + "ms - class: " + clazz
						+ " method: " + method);
			}
		}
	}
}

After this, we create a jboss-aop.xml which will look like this (we are just defining the interceptor and creating a pointcut, which defines when the interceptor will be called):

<?xml version="1.0" encoding="UTF-8"?>
<aop xmlns="urn:jboss:aop-beans:1.0">
  <interceptor name="Int" class="com.LogInterceptor"/>
  <bind pointcut="execution(* com.mypackage.*->*(..))">
    <interceptor-ref name="Int"/>
  </bind >
</aop>

This defines a pointcut to all methods inside package com.mypackage, no matter their return type or parameters. Later on this post I’ll add some more examples of pointcuts for you to narrow down the list of intercepted methods.

After compiling com.LogInterceptor, we’ll just create a jar file, for example aopExample.jar which will contain these files and folders:

com
	LogInterceptor.class
META-INF
	jboss-aop.xml

After this, copy this jar file into the deploy folder together with your application, restart your jboss server, and after running the application (classes inside com.mypackage) you’ll start seeing these logs in JBoss:

21:59:22,254 INFO  [LogInterceptor] LogInterceptor: 2ms - class: class com.mypackage.Hello method: doGet
22:04:43,637 INFO  [LogInterceptor] LogInterceptor: 0ms - class: class com.mypackage.Hello method: doGet

If you want to quickly test this, you can download my testAop.jar and my test application TestWeb.war and put them in your JBoss server.
Here are the links:
testAop.jar
TestWeb.war

TestWeb.war has only one servlet: com.mypackage.Hello which prints Hello world in the browser. The important part here is that testAop.jar is intercepting calls to TestWeb.war. Just point your browser to http://localhost:8180/TestWeb/Hello and look at the server log.

Starting with this example, you can start doing more complex things with AOP, from logging how long it takes a method to run, to creating a security framework.

Pointcuts

Here are some examples of pointcuts if you want to start playing around with these:

  • <bind pointcut=”execution(* com.mypackage.*->*(..))”>
  • Will intercept any method call inside the package com.mypackage.

  • <bind pointcut=”execution(* com.mypackage.MyClass->*(..))”>
  • Will intercept any method call to the class com.mypackage.MyClass

  • <bind pointcut=”execution(* com.mypackage.MyClass->myMethod(..))”&gt
  • Will intercept the method myMethod (with any combination of parameters and return type) in class MyClass .

Interceptor API

When developing an interceptor, you can use the API to access important information regarding the intercepted invocation. You can change the original parameters of the invocation, change the return value, and have access to the destination (class and method) information.

At the invoke(Invocation mi) method, if Invocation is instance of MethodInvocation you can call:

mi.getTargetObject().getClass() to get the intercepted class intercepted.

mi.getMethod().getName() to get the method name which is being intercepted.

Memcached vs DB Cache Comparison

Today I’m going to talk about some performance considerations about web applications and the advantages of having a memory cache.

Introduction

As noted in my previous memcached post, for most applications, there is some data that can be cached in a local cache, so you don’t have to query it every time a users enters your site, as the exchange rates example in my previous post.
For the exchange rates example, you could choose to store the values locally in several formats, you may choose to store the data in a temporal file in the local file system, a database, a memory cache, or whatever comes to your mind, so you don’t need to query the external service again for the rest of the day.
Sometimes, if you already have a DB running that is used by your application, you may want to reuse that in order to store the temporal data, so you don’t need to install any additional applications, for example memcached. As a developer, it may sometimes become a hard task to convince the sysadmin to install a new software in the environment.
In this post I’ll compare the performance between using a local DB as a cache (Postgre SQL) and a memory cache (Memcached). You may use these comparisons as an argument to move to a memory cache (I mention memcached, but there are more, some I mentioned in my previous post, but you can find more using your preferred search engine 😉 ).

Test Environment

For the test environment I installed a local Postgre SQL sever and a Memcached server, both were running simultaneously during the tests.
For every test I inserted a total of 10000 keys and then read them sequentially. After that, I compared the inserts/second and reads/second and made a graph for each test case. The variables considered were: length of the key (10 to 250 characters), size of value object (10KB to 1MB) and the quantity of threads (1 to 40). This means, the horizontal axis represents the variable, and the vertical axis shows the insertions or reads per second, depending the case.

You can find the source code of the tests here. I didn’t develop the source with the intention of sharing it afterwards, so it may be incomplete (the DB cache only has the put and get methods implemented, not the delete or flush) and a bit hard to read if you don’t speak Spanish. If you want to read it and have questions just ask in the comments.

Test Results

Variable length of key

In this test, the variable is the length of the key. The object size is fixed to 6kB. According to memcached, the limit length is 256 characters, so I wondered how this limit affects performance. Here you can see that when adding keys longer than 200 characters, the number of insertions/sec decreases significantly for memcached (red line).

The same tests running against the DB (blue line) show almost a constant number of insertions and reads per second, but far less than memcached. The peak insertions/second in the case of Memcached is 14700 whereas for the DB it is 350.

The reads per second for memcached is more than 3 times the amount of the DB.

Variable object size

In this case the variable is the object size, from 10kB to 1MB. The key length is fixed to 100 characters.
It is very clear how the performance drops in both cases as the size of the inserted object increases. The biggest size inserted is 1MB, since this is the limit for Memcached.

Variable length of key

This last case fixes the length of the key to 100 characters and the size to 6kB. The variable is the number of threads used to read the keys. Every one of these threads read all the 10000 keys stored previously in the cache. In this case, only the read part is important, since the objects are inserted only once into the cache.

Clearly, the reads/second limit for the DB is reached very fast, this is, using more than 4 threads, the reads/sec remain constant between 1500 and 2000.
For memcached, this limit is not reached and adding more threads increases the number of reads/sec. I didn’t try with more than 40 threads, but this shows that from a performance point of view, a single memcached server can be shared 2 or more applications.

Conclusion

In every case, according to the expected result, the memory cache always performs better than the DB, no matter the variable.
Even though memcached looses performance when using big objects or, when using it in a normal range (e.g.: objects smaller than 500kB) it will perform very nice, and more important is that the memcached server can scale very well and also very easy. If the performance isn’t good enough you can always easily add another memcached server in any server with some spare memory and that’s it, the number of reads and writes per second will increase.

Please note, this comparison is not a formal benchmark between these cache because the tests add some overhead. It is developed in Java, and the Java VM has some time and memory overhead. A more formal benchmark would have to use a small footprint language for the client, for example C or Lua. I used Java because my main point wasn’t to get an exact number of inserts a cache can provide, but to get an approximate improvement percentage when using a memory cache, instead of a DB.

I hope you enjoyed reading the post as much as I enjoyed writing it!

Please let me know if you have any comments or suggestions. I would also like you to share experiences using other memory caches, I am open for alternatives 😉 .

Memcached and SpyMemcached

Memcached and SpyMemcached

Hi all, today I’m going to write about Memcached, which I’ve been using for a while now.
Memcached ( http://memcached.org/ ) is a free and open source memory object caching system, which also has a DB integrated version called Coachbase (previously called Membase). The main idea of a memory cache is to hold objects in memory avoiding unneeded DB queries. When using a cache you need to make sure that the data can be recovered from somewhere else when the cache fails, since the data in the cache can be erased when a timeout occurs, when it needs to free up some memory, or the cache server fails. An example of this is the daily currency rates (you can query these values once through a web service, and then store it locally in a cache server), since these values don’t change for several hours, you can store them in a local cache, so you don’t query the web service each time a user navigates to your site.
When storing objects in a Memcached server there are some limits. The maximum size of the object must not exceed 1MB and the key length has a maximum of 256 characters.
Memcached can be compiled for any Linux distribution (download here) or it can be run in Windows after downloading the ported binaries, which can be found here (http://code.jellycan.com/memcached/).
Either way, running and configuring the server is extremely easy. I will be running these examples in Windows, but the Linux way is analogous. The simplest way to run the server is with the command:

memcached

This command starts a memcached server which by default can hold up to 64MB of objects and listens on port 11211. You can change these parameters with the -m and -p options respectively. There are other parameters you can set when starting up the memcached server, but these two are enough to have a functional memcached server. You can look up the other options in the wiki. Here is an example:

#Runs a memcached server which can hold up to 512MB objects and on port 11230
memcached -m 512 -p 11230

Memcached has clients for several languages (C, C++, Java, PHP and so on), all the possible clients are listed here. You can even use it from a telnet client.
Since I am mostly into Java, I’ll talk a bit more about the Java clients. According to the clients page, there are several clients for Java. I didn’t get to try them all, but I went with Spymemcached, since it is the one developed by Couchbase (the creators of memcached), it has support for couchbase and is one of the most recently updated ones. There is another recently updated project called xmemcached, which has a nice documentation.

Jumping right into Spymemcached, it is quite straightforward to use it. Just download the jar file, create a client and start setting keys:

//Create a memcached client (this will also start a thread which will monitor the server availability and communication)
MemcachedClient client=new MemcachedClient(new InetSocketAddress("localhost", 11211));

//Just start putting objects in the cache. 
//Here,"someKey" is the key under which the object will be stored, 
// 3600 is the number of seconds the object will be kept and 
// someObject is any Object that implements Serializable.
client.set("someKey", 3600, someObject);

//This will synchronously retrieve the object from the cache 
Object obj = client.get("someKey");

Even having a cluster of Memcached servers is easy, you just create one MemcachedClient with several addresses. The client decides where to store/retrieve the keys with an internal hashing method.

//Create the Memcached client and use it, simple as that
MemcachedClient c=new MemcachedClient(AddrUtil.getAddresses("localhost:11211 localhost:11212"));

There is also a CacheMap class which allows you to access the cache as it were a Map:

MemcachedClient c=new MemcachedClient(AddrUtil.getAddresses("localhost:11211"));
//Here, 100 is the default timeout to use when adding elements to the cache, "prefix" is the string that will be prepended to all the keys in this map
CacheMap map = new CacheMap(c,100,"prefix");

//...
//use map
mapa.put("k1", someObject);

//Retrieve the element using the map
Object obj1 = mapa.get("k1");
//or even using the MemcachedClient (prepending the prefix we used for this map):
Object obj2 = c.get("prefixk1");

Finally I want to mention that there are several alternatives for a caching system (these examples are designed to work with Java platform):

  1. Apache JCS: It has several caching levels, memory, disk, database, etc. It also seems a bit more complex to install and configure. link
  2. OSCache: Works inside the same VM which the application is running, but works. It wasn’t updated since long ago
  3. JCache: It’s an old api, which is getting refreshed with Java EE 7, end of 2012. link

That’s it for now, as simple as that you can start using Memcached 🙂
I hope you enjoyed this post, let me know your comments!
On my next post I’ll add some comparisons between using a Database as a cache and Memcached.

Eclipse – Debug java program without source code – jd-eclipse and realignment

Hi all,

I have been trying to debug java programs without having the source code (having only the jar files with .class). The main goal of this task was to be able to debug through .class files and being able to step through the code having the debugger always showing the correct line of the code.

Finally I succeeded with the help of a combination of jd-eclipse and its extension jd-eclipse realignment fragment.

The process for installing this is quite simple:

  1. Install JD-Eclipse following the steps provided in the JD-Eclipse site (the process is quite simple)  http://java.decompiler.free.fr/?q=jdeclipse
  2. Restart Eclipse
  3. Download Realignment realignment.jd.ide.eclipse_1.0.2.jar – https://sourceforge.net/projects/realignmentjd/files/
  4. Copy the file to the <Eclipse installation folder>\dropins
  5. Restart Eclipse
  6. Go to Windows -> Preferences
  7. Navigate to General -> Editors -> File Associations
  8. Select *.class in the File types section, select Realignment for JD Class File Editor in the Associated editors section and click the Default button.
  9. Press OK and start debugging!

The association should look like this:

Let me know if you face any problems with this procedure and I’ll try to help!

Note: I have empirically found out that in order for the source to be found, if the jar files being used in the project belong to a different project, they need to be added to the build path as “Add External JARs…“.Otherwise if “Add Jar”, is used you will get this message when stepping into a class from that JAR: