I came up with some neat code for data preparation today. For unit testing you often have to prepare data. Unit tests should act as documentation for how the code works and thus it should be as easy to quickly read and digest as possible.

I’ll walk though several attempts at coming up with unit testing data.

First run


Alert a1 = new Alert();
a1.setText("test text");
a1.setTimestamp(new Date());
a1.setToken("token1");
interestedInThisToken.add("token1");

Alert a2 = new Alert();
a2.setText("test text");
a2.setTimestamp(new Date());
a2.setToken("token2");

Alert a3 = new Alert();
a3.setText("test text");
a3.setTimestamp(new Date());
a3.setToken("token1");
interestedInThisToken.add("token3");

Second Run

Run one was reasonably readable, but when you are building a lot of data or setting more fields there ends up being a fair bit of gruff you need to wade through to see the pertinent details. Lets clean that up a bit by introducing a helper function.


addAlert("test text", new Date(), "token1");
interestedInThisToken.add("token1");
addAlert("test text", new Date(), "token2");
addAlert("test text", new Date(), "token3");
interestedInThisToken.add("token3");

That’s much better. But we can go one better to get rid of that extra line. One problem with that line is you are repeating text and may get it wrong and thus make bad data. Obviously this is something you want to avoid when creating test data that is meant to prove your code is correct. So you could do this:


String tokenText = "token1";
addAlert("test text", new Date(), tokenText);
interestedInThisToken.add(tokenText);

But now an extra line has been added. Surely we can inline this by passing a flag.


addAlert("test text", new Date(), "token1", ADD_TOKEN_TO_INTERESTED_LIST);

We just overload addAlert() to take a boolean.

That’s not too bad. But let’s complicate the matter. Say we want to output the list of tokens we collect sometimes, and other times we just want the text. Easy, add another argument and overload addAlert() again:


addAlert("test text", new Date(), "token1", ADD_TOKEN_TO_INTERESTED_LIST, OUTPUT_AS_LIST);

But now we need 4 methods:


addAlert(....)
addAlert(boolean)
addAlert(int)
addAlert(boolean, int)

If we add another argument then we need another 4 methods. Its not a very scalable idea.

Third Run

There are a number of solutions and I’d like to write about the one I’ve developed.


public abstract class BaseArg {
	private static BaseArg instance = null;
	private List baseArgs = new ArrayList<>();
	private String lastBaseArg;

	private BaseArg() {
	}

	private static void make() {
		if (instance == null) {
			instance = new BaseArg();
		}
	}

	/**
	 * Clear the list of args (the list has been around since the JVM started).
	 */
	public static void clear() {
		if (instance != null) {
			instance.baseArgs.clear();
			instance.lastBaseArg = null;
		}
	}

	/**
	 * Add subsequent arg after the first one is added through {@link #create(String)}
	 * 
	 * @param arg
	 */
	public void add(String arg) {
		this.lastBaseArg = arg;
		this.baseArgs.add(arg);
	}

	/**
	 * 
	 * @return the arg just added
	 */
	public String out() {
		return lastBaseArg;
	}

	/**
	 * 
	 * @return the list of all args added (ie. since the JVM started). Call {@link #clear()} to clear the list of
	 *         args.
	 */
	public List outAsList() {
		return baseArgs;
	}

	/**
	 * This is the first method to call.
	 * 
	 * @param arg
	 *            we are saving.
	 * @return the new instance we can call other methods on.
	 */
	public static BaseArg create(String arg) {
		make();
		instance.add(arg);
		return instance;
	}

	/**
	 * We don't want the added arg to be added to the List since we only want to add ones that are of interest to us.
	 */
	public BaseArg noList() {
		baseArgs.remove(baseArgs.size() - 1);
		return instance;
	}
}

Some of you may recognise the Singleton pattern.

Just create the class for the type you want to pass in as arguments. This one is just for Strings, however you could easily create a Generics version for any type:


public class Token extends BaseArg {
}

Now you can write your data building code more succinctly and with infinite possible ways to modify how the data is being worked:


# token1 is added to the list
addAlert("test text", new Date(), Token.create("token1").outAsList());

outAsList() says to output the full list


# token2 is NOT added to the list
addAlert("test text", new Date(), Token.create("token2").noList().out());

noList() says not to add the argument to the list
out() says to output just the text ie. ‘token2’

I can spot 2 potential problems here but they are easily fixed, and this is code only developers are going to work with anyway:

  1. What if you want to have 2 lists – 1 for things interested in, the other for the list of tokens. ANS: No problems just update the baseArg class or even a subclass if that is better
  2. What if you don’t make the fix as per point 1 and and then still say .noList().outAsList(); Although not a bug it seems silly that you’d pass a new token in but not do anything with it. If you do want to prevent this problem then you could update outAsList() to only output the list if the last item is the same as lastBaseArg.

Happy testing!

Written on August 31st, 2013 , Java, Unit Testing Tags:

I followed Markus Eisele’s great article on creating a JDBCRealm in Glassfish – jdbc-realm-glassfish312-primefaces342.html.

However I tried getting this to work by building in Eclipse instead of Netbeans and it proved not so straight-forward. It turns out that the extra work was minimal; it just took me a little effort to work this out.

Increase log levels

My first advice when you have no idea of what is going on with your JEE deployed application is to increase the log levels on your application server – Glassfish in this case. Find them at:

Glassfish > Configurations > Server-config > Logger Settings > Log Levels (tab)

Differences between Netbeans and Eclipse

Netbeans ‘just works’, but at the cost of some flexibility and power. Eclipse is Fucken awesome, with awesome (or large) being the operative word.

For example is this case (and which is the main difference I’m discussing).

The deployment descriptor glassfish-resources.xml is used to setup the JDBC Connector and Resource. Unfortunately, as I learnt, its not a deployment descriptor in the sense that it is read by the Application Server (Glassfish here) when its in the WEB-INF or META-INF directory.

What Netbeans does is run the following under-the-hood.


asadmin add-resources WEB-INF/glassfish-resources.xml

And that precisely is what you need to do when developing this using Eclipse. Either that or define the JDBC Connector and Resource manually in Glassfish. However its better to move such actions to a file that can be replayed (which you need to do after you remove and re-add the Glassfish server in Eclipse which I seem to need to do every now and then).

Other gotchas

Other steps needed as modifications to Markus’ article are:

  • Database configuration can’t be done through the IDE to the same extent – use MySQL Workbench or just the mysql command-line for MySQL, or whatever tools for your database of choice.
  • The section on JDBC Connector and Resource and Extract from Existing Connection to creaqte the glassfish-resources.xml doesn’t have a counterpart in Eclipse. Instead either do in Netbeans and copy the contents to a new xml file in the WEB-INF directory, or create the same file from an example on the web (eg. http://javahowto.blogspot.com.au/2011/02/sample-glassfish-resourcesxml.html) and populate with your values.
  • The Additionally we still need Primefaces part doesn’t need a fancy wizard with a checkbox. Simply add Primefaces as a dependency in your Maven pom. Group=org.primefaces, Artifact=primefaces, Version=3.4.2 (current)
  • For the jsf / xhtml files, just create html files and select the Facelets Composite Page (WTP needs to be installed). Or simply create a file called whatever.xhtml in the appropriate directory. Then just populate with what’s in Markus’ article.
  • The New > Other > GlassFish > GlassFish Descriptor” section just requires you create a WEB-INF/glassfish-web.xml file and populate with the given <security-role-mapping>
Written on June 13th, 2013 , authentication, Java, JSF Tags: , ,

I’ve been on holidays, leaving the evening after updating my Mac to the latest Java.

This update essentially (for 10.7 and 10.8) users, removed Apple’s involvement in Java for the platform completely by removing Java Preferences and making the default Java 7. More info at Cnet.com / Java Preferences missing after latest OS X Java update.

Anyway, I was receiving emails from Crash Plan telling me I haven’t backed up for days. Mmm I thought, I wonder what my wife has done :).

I got home and sure enough the CP menu-bar icon was grayed out and there was a message saying “Unable to connnect to the local backup engine”. My wife was not the cause (not that I really thought that anyway but still gotta wonder).

I opened Console and I found it saying:

26/10/12 11:07:59.610 PM com.apple.launchd: (com.crashplan.engine[2566]) Tried to setup shared memory more than once

Suggestions were that CrashPlan needed to up the -Xmx Java max memory setting. Made no difference.

I then looked a bit deeper and found /Library/Logs/CrashPlan, and in particular the engine_error.log.

It said:

java.lang.ExceptionInInitializerError
at com.code42.os.mac.io.IOPolicy.setIoPolicy(IOPolicy.java:69)
at com.backup42.service.CPService.start(CPService.java:383)
at com.backup42.service.CPService.main(CPService.java:1622)
Caused by: com.jniwrapper.LibraryNotFoundException: Cannot find JNIWrapper native library (libjniwrap.jnilib) in java.library.path: /var/root/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.:/Applications/CrashPlan.app/Contents/Resources/Java/lib

java -version

tells me its Java 1.7 which made me thing something was odd since I set 1.6 as the default.

I tried to open Java Preferences, which on the Mac let you set which version of Java is the default. It no longer existed. I found the cnet article liked to above (Cnet.com / Java Preferences missing after latest OS X Java update) telling me the Java ecosystem on the Mac is changing.

I searched on “Crash Plan mac osx java 7” and I found this java.dzone article. It said to change the version of Java used for the Crash Plan service back to 1.6 in the /Library/LaunchDaemons/com.crashplan.engine.plist Launch Daemon file. See that article for precise instructions.

Following this remedy fixed the problem. As a bonus I can drop my Java max memory (back to the 512k)!

Written on October 26th, 2012 , Java, Mac OS X Tags: , ,

I saw InjectionPoint mentioned breifly by Adam Bien in his JavaOne 2011 Presentation JavaEE 6 Cool Parts (around about 0:50).

There wasn’t much information about it though I found the Javadoc at http://docs.oracle.com/javaee/6/api/javax/enterprise/inject/spi/InjectionPoint.html and it had all I needed to know.

For example, the following producer method creates injectable Loggers. The log category of a Logger depends upon the class of the object into which it is injected.

@Produces
Logger createLogger(InjectionPoint injectionPoint) {
return Logger.getLogger( injectionPoint.getMember().getDeclaringClass().getName() );
}

And it works!

//index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>Facelet Title
  </h:head>
  <h:body>
    Hello from Facelets
    <h:form>
      <h:commandButton value="Injector seat!" action="#{messenger.hello}"/>
    </h:form>
  </h:body>
</html>
// Messenger.java
package boundary;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.inject.Named;

/**
 *
 * @author bsmith
 */
@Named
public class Messenger {
    @Inject String data;
    @Inject Logger log;

    public void hello() {
        System.out.println("Hello!  I want: "+data);
        log.log(Level.SEVERE, "("+log.getName()+") I am logging some data: "+data);
    }
}
// Configuration.java
package control;

import java.util.logging.Logger;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;

/**
 *
 * @author bsmith
 */
public class Configuration {
    @Produces
    public String getData(InjectionPoint ip) {
        System.out.println("ip.toString: "+ip.toString());
        System.out.println("ip.getAnnotated: "+ip.getAnnotated());
        System.out.println("ip.getBean: "+ip.getBean());
        return "data";
    }

    @Produces
    public Logger getLogger(InjectionPoint ip) {
        return Logger.getLogger( ip.getMember().getDeclaringClass().getName() );
    }
}

INFO: com.tintuna_Injection_war_1.0-SNAPSHOT was successfully deployed in 398 milliseconds.
INFO: ip.toString: [field] @Inject boundary.Messenger.data
INFO: ip.getAnnotated: [field] @Inject boundary.Messenger.data
INFO: ip.getBean: Managed Bean [class boundary.Messenger] with qualifiers [@Any @Default @Named]
INFO: Hello!  I want: data
SEVERE: (boundary.Messenger) I am logging some data: data
Written on October 13th, 2012 , EJB, Java Tags: , ,

EJB Asynchronous moves the task of handling concurrent threads to the container to manage. Java’s concurrency cannot be used in the normal way; by creating Thread runners, with wait() and notify() and so on.  Adam Bien talked about managing threads in JavaEE 6 using an Executor on his blog.

Asynch is easier though it does seem to me to be less powerful.  However the power of an Executor would seem to trump the low-level benefits of using Threads directly. See this Lars Vogel tutorial on Java Concurrency for what they allow you to do.

I digress; back to Async where it seems to be easier then Threads and Executor’s.

I will show an example simple usage, making use of isDone() in the client and how to use cancel().

Example simple usage

From Enterprise Java Beans 3.1 book page 60ish:

// for some Session Bean with an interface
@Asynchronous
@Override
public Future hashAsync(final String input) throws IllegalArgumentException, EncryptionException
{
    // Get the real hash
    final String hash = this.hash(input);
    // Wrap and return
    return new AsyncResult(hash);
}

// And used by the client like this
public void someMethod() {
    // Declare the input
    final String input = "Async Hashing Input";
    // Hash
    final Future hashFuture = myEjbProxyReference.hashAsync(input);
    // Now we're free to do whatever work we want here while the EJB invocation runs concurrently
    // ...[work]
    // At this point we need the hash, so get the result,
    // and block for up to 10 seconds to get it
    final String hash = hashFuture.get(10,TimeUnit.SECONDS);
    log.info("Hash of \"" + input + "\": " + hash);
}

When is the Asynch method done?

You’d use the following code in some way such as set an Observer on it for population in a GUI. That’s an exercise for the reader.

  final String input = "Async Hashing Input";
  // Hash
  final Future hashFuture = myEjbProxyReference.hashAsync(input);
  if (hashFuture.isDone()) {
    final String hash = hashFuture.get();
  }

Cancelling and making the most of Asynch code

I found this quite confusing, as did others.

I did some searching and the gestault switch flicked when I read IBM discussion of Developing client code that calls EJB asynchronous methods in Websphere.

What follows is my interpretation.

In the client we have:

  final String input = "Async Hashing Input";
  // Hash
  final Future hashFuture = myEjbProxyReference.hashAsync(input);
  ...
  if (hashFuture.cancel()) {
      // it was cancelled and got a true return value - what does this mean?;
  } else {
      // it was cancelled and got a false return value - what does this mean?
  }

And the Asynchronous method in the Session Bean is:

public Future run() throws Exception {
    ...
    while (myContext.wasCancelCalled() == false) {
        // do work can do in stages
    }
    return new AsyncResult(result);
}

The contents of the while loop is some task we can break down into smaller chunks and each chunk is done in a trip around the while loop. The guard on the loop is what checks if the operation has been cancelled.

But what does the return value from the if (hashFuture.cancel()) mean?

  • true – means that the cancel happened before the Asynch method was dispatched (ie. the run()method never started)
  • false – means that the run() method started. In which case the while loop in the Asynch method was necessary to cancel the operation.
  • mayInterruptIfRunning – if true means that once the run() method has started the container won’t stop it. Thus the while loop will have no affect.

I’m doing study for the BUSINESS COMPONENT DEVELOPMENT WITH EJB TECHNOLOGY, JAVA EE 6 certification and although I didn’t think I needed to know such details for the exam, it bugged me and I just had to find out. And the truth of the matter is that I don’t know what will be on the exam.

I hope this helps anyone else doing this study or just wanting to know.

I now have a question, be it another itch I must scratch – how to use the features of Asynch I’ve just discussed with Executor’s…..

Written on September 11th, 2012 , EJB, Java Tags: , , ,

Brooke Smith is proudly powered by WordPress and the Theme Adventure by Eric Schwarz
Entries (RSS) and Comments (RSS).

Brooke Smith

Portfolio and site of a software engineer