Seam Maven Refimpl

Featured

Know IT Objectnet developers have created a Mavenized Seam project template. Due to the lack of Maven support in the Seam project, we felt the need to get a project started for the topic. After some research and development, the base was ready to be put in use. We felt that it was only right to make the project available to the public, and put together a google code project. As of now the project is aimed at running on the JBoss-4.2.3 and JBoss-5.x application servers deployed as an EAR project.

You can check out the code from google code: http://code.google.com/p/seam-maven-refimpl/

Also check out the tutorial pages: http://www.glxn.net/seam-maven-refimpl/doc/tutorial/

Issues and feature requests can be posted here: http://code.google.com/p/seam-maven-refimpl/issues/list

QRGen, a small wrapper on top of ZXING for generating QRCodes in java

A couple of months ago I was looking at creating QR codes in java, and found ZXING, which is pretty awesome, you should check it out.

For convenience I made a simple wrapper API on top of zxing.

To put it to use just add the repository definition and dependency to your project:

example maven pom.xml

<dependencies>
  <dependency>
    <groupId>net.glxn</groupId>
    <artifactId>qrgen</artifactId>
    <version>1.1</version>
  </dependency>
</dependencies>

<repositories>
  <repository>
    <id>QRGen</id>
    <name>QRGen Repo</name>
    <url>http://kenglxn.github.com/QRGen/repository</url>
  </repository>
</repositories>

example build.gradle:

repositories {
  maven {
    url "http://kenglxn.github.com/QRGen/repository"
  }
}
dependencies {
  compile ("net.glxn:qrgen:1.1")
}

After that you can put it to use in your project:

// get QR file from text using defaults
File file = QRCode.from("Hello World").file();
// get QR stream from text using defaults
ByteArrayOutputStream stream = QRCode.from("Hello World").stream();

// override the image type to be JPG
QRCode.from("Hello World").to(ImageType.JPG).file();
QRCode.from("Hello World").to(ImageType.JPG).stream();

// override image size to be 250x250
QRCode.from("Hello World").withSize(250, 250).file();
QRCode.from("Hello World").withSize(250, 250).stream();

// override size and image type
QRCode.from("Hello World").to(ImageType.GIF).withSize(250, 250).file();
QRCode.from("Hello World").to(ImageType.GIF).withSize(250, 250).stream();

// supply own outputstream
QRCode.from("Hello World").to(ImageType.PNG).writeTo(outputStream);

See the github page for more info: http://kenglxn.github.com/QRGen/

If you’d rather use ZXING directly, you will be able to since it is a transitive dependency of QRGen, but you could also just add the ZXING repository definition and dependency to your project:

    <dependencies>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>2.0</version>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <id>google-releases</id>
            <url>https://oss.sonatype.org/content/repositories/releases</url>
        </repository>
    </repositories>

Hosting maven artifact with github pages

Using the steps described in the Github pages doc: http://pages.github.com/ we will create a directory hosting our website and maven repository on github.

First we clone the project to a new directory that will be dedicated to the gh-pages content root branch.
(If you want to get fancy you can do subfolders for each of the root branches, but we’ll not be doing that here.)

 ~ $ git clone git@github.com:kenglxn/QRGen.git QRGen_pages
 ~ $ cd QRGen_pages/

To initialize the gh-pages branch do the following:

 ~/dev/git/QRGen_pages (master) $ git symbolic-ref HEAD refs/heads/gh-pages
 ~/dev/git/QRGen_pages (master) $ rm .git/index
 ~/dev/git/QRGen_pages (master) $ git clean -fdx

You are now on the gh-pages branch will be hosted under your account e.g. (http://kenglxn.github.com/QRGen/)
Here we can create a page with some content for the users of our project, and also host our project as a maven artifact.

To host our project as a maven artifact we need to deploy it to a folder under gh-pages directory.

Create repository folder.

 ~/dev/git/QRGen_pages (gh-pages) $ mkdir repository

Add distributionManagement section to the project pom.xml with the full path to the repository folder

 ~/dev/git/QRGen_pages (gh-pages) $ cd ../QRGen
 ~/dev/git/QRGen_pages (gh-pages) $ vi pom.xml

    <distributionManagement>
        <repository>
            <id>gh-pages</id>
            <url>file:///${basedir}/../QRGen_pages/repository/</url>
        </repository>
    </distributionManagement>

At this point we can deploy the project with the following command

mvn clean deploy -DperformRelease=true

Then we cd back to the gh-pages folder and check the result

 ~/dev/git/QRGen (master) $ cd -
/Users/kenglxn/dev/git/QRGen_pages
 ~/dev/git/QRGen_pages (gh-pages) $ ls -al repository/*/*/*
total 24
drwxr-xr-x   6 kenglxn  staff  204 Mar  6 15:06 .
drwxr-xr-x   3 kenglxn  staff  102 Mar  6 15:06 ..
drwxr-xr-x  14 kenglxn  staff  476 Mar  6 15:06 1.0
-rw-r--r--   1 kenglxn  staff  289 Mar  6 15:06 maven-metadata.xml
-rw-r--r--   1 kenglxn  staff   32 Mar  6 15:06 maven-metadata.xml.md5
-rw-r--r--   1 kenglxn  staff   40 Mar  6 15:06 maven-metadata.xml.sha1

Everything looks as expected, now we add the repository folder to git, commit it, and push to gh-pages

 ~/dev/git/QRGen_pages (gh-pages) $ git add repository
 ~/dev/git/QRGen_pages (gh-pages) $ git ci -m "added repository folder with deployed artifact version 1.0"
 ~/dev/git/QRGen_pages (gh-pages) $ git push origin gh-pages

Our repository is now hosted on github and ready to use (e.g. http://kenglxn.github.com/QRGen/repository)
Keep in mind that gh-pages does not support directory listing, but this should not stop maven clients from getting the artifact.

Now people can use your project as a dependency. Following are examples of minimal project descriptors for gradle and maven
Gradle:

group = 'net.glxn'
version = '1.0'
apply plugin: "application"
mainClassName = "net.glxn.DepTest"
repositories {
    mavenCentral()
    maven {
        url "http://kenglxn.github.com/QRGen/repository"
    }
}
dependencies {
    compile ("net.glxn:qrgen:1.0")
}

Maven pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>net.glxn</groupId>
  <artifactId>deptest</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>qrgen-deptest</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>net.glxn</groupId>
      <artifactId>qrgen</artifactId>
      <version>1.0</version>
    </dependency>
  </dependencies>

  <repositories>
    <repository>
      <id>QRGen</id>
      <name>QRGen Repo</name>
      <url>http://kenglxn.github.com/QRGen/repository</url>
    </repository>
  </repositories>
</project>

My Bash PS1 with git branch info

I spent an hour playing around with my bash PS1 setting.
I wanted some useful information about which git branch I am on, and some colors.

After reading a couple of articles on it like this one and this one I tried it a bit myself and ended up with this:

Here is the PS1 code:

PS1_END_SIGN=

export PS1='\[\e[1;33m\] \w\[\e[1;36m\]$(git branch &>/dev/null; if [ $? -eq 0 ]; then echo " ($(git branch | grep '^*' |sed s/\*\ //))"; fi) \[\e[1;37m\]$PS1_END_SIGN\[\e[00m\] '

The PS1_END_SIGN can be set to anything you want. I chose lambda.
The PS1 setting includes some coloring and output of the current branch if you are in a git repository.

Pomodoro Technique and my idea for a decent android app

I’m a big fan of the pomodoro technique.
The pomodoro technique is basically working for a set amount of time, then taking small breaks before returning to work.

A couple of the reasons i like it are:

  1. it boosts focus
  2. reduces stress
  3. prevents me from sitting still for a long time without break
  4. forces me to do something else, like take a 5 minute walk (good for health)
  5. gives the brain time to work for you, actually enabling me to sometimes see that I’m on the wrong track early.
  6. Can easily be combined with agile methods

There are probably more things that I have forgotten right now, but my main point is that I think it is a good way to work.

I currently use ChromoDoro, a great plugin, except for one thing: It’s a plugin. I don’t want my break to be spent in front of the computer, but rather on a walk to the watering hole or similar, and taking the computer with me is not an option.

So how about a nice pomodoro plugin for android, there are some out there which can be downloaded, but i figure “Hey, what a great opportunity to get introduced to android application development ” :)

I have added a repository on github at http://github.com/kenglxn/Pomodroid, and will be adding code to it as I find the time.

Here are my user stories so far:

  • as a user I should be able to set pomodoro time, and break time, so that I can have the timer fit my workhabits.
  • as a user I should be able to set the pomodoro timer to vibrate, so that I wont disturb my co-workers with my pomodoro weirdness.
  • as a user I should be able to start the timer so that my worksessions can begin.
  • as a user I should be able to stop the session before timer runs out, so that I can handle interruptions.
  • as an application I should pause the pomodoro timer when the user recieves a phonecall, so that I can account for interruptions.
  • as a user I should be asked to give a reason for the interruption, so that I can later review my flow efficiency
  • as a user I should be able to access statistics of my interruptions, so that I can reflect on my flow efficiency, and perhaps find ways to improve it.

These user stories and more will be added to the issues section of Pomodroid project.

Making a swing project using IntelliJ IDEA GUI builder with maven, Including executable jar

In this post I’ll quickly show how to get a maven project under Idea running with the GUI builder, and show you the config you need to build an executable jar for it as well.

IntelliJ IDEA has a great built in tool for making swing projects called GUI Builder, here’s a nice live demo.

The problem comes when using the gui builder with maven, since the builder uses form files that are specific for IDEA. Thankfully there is a maven plugin to help with this issue: The Maven 2 IDEA UI Designer Plugin.

To have a concrete example to work with, we’ll create a simple Swing app for sending JMS Messages to a destination queue. The code will be located at http://github.com/kenglxn/JMSUtility

So lets get started by setting up the project:

  1. Start IDEA and create a new project. Choose to create from scratch.
  2. in the module section choose maven module and give it a name
  3. In the next screen you can set maven artifact properties and if you wish choose an archetype, we’ll be creating from scratch, so skip the archetype and click the finish button
  4. Great, now we have a fresh maven project that we can work with

So now it’s just a matter of adding the dependencies we need, and writing some code.  We’ll add some dependencies for tests, string manipulation and JMS.
Here’s a snippet of the dependencies added to the pom.xml so far:

<dependencies>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-core</artifactId>
        <version>5.3.0</version>
    </dependency>

    <dependency>
        <groupId>com.intellij</groupId>
        <artifactId>forms_rt</artifactId>
        <version>5.0</version>
    </dependency>
    <!-- TEST SCOPE -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.7</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Next step is writing some code and tests.

We’ll start off by making the UI using the built in GUI Builder in IDEA, using the GridLayout. You could of course use JGoodies Forms layout, or even something else you prefer.

  1. create a new package, again I like to use alt+insert hotkey while the target directory is active. I chose net.glxn.jmsutility as the name for my package

  2. Next we create a new GUI Form in the newly added package and give the form a name. Here I chose GridLayoutManager by IntelliJ, this will need to be added to the pom.

  3. IDEA now kindly shows us the fresh GUI builder view, here we add our components from the palette. Take a look at the live demo of the GUI Builder to get started yourself.

  4. We now have enough code to run the application. commit:4164296182c8efc3f0c97be8f5be1a7a1f2cdeb3

  5. So now IDEA is able to run the GUI, and tests

That’s it for the GUI building.
Our next step is to get this build running equally smooth in maven. Lets see what the output is with the current code (http://github.com/kenglxn/JMSUtility/tree/130462ca99bc7f05980fd129674d41ef975a5e92)

So we see that maven isn’t happy with us. Let’s fix it by adding the following to the pom:

<build>
    <finalName>JMSUtil</finalName>
    <plugins>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.0.2</version>
            <configuration>
                <sourcee>1.6</sourcee>
                <target>1.6</target>
            </configuration>
        </plugin>

    </plugins>
</build>

Now we run the test again and get:

Here we see that the build is ok, but the tests fail. This is what I was talking about earlier in regards to the idea forms not being built with maven.
Lets look at the surefire report and see what it says. I’m going to use the “analyze stacktrace” functionality in IDEA to get a pretty view of the content of the surefire report, since gedit isn’t very helpful at that. To do this go to the Analyze menu and at the bottom select “Analyze stacktrace”, and in the dialog paste in your stacktrace and click ok:

This tells us that the helpButton field is null when it tries to attach an ActionListener in the constructor

public JMSUtility() {
    helpButton.addActionListener(new ActionListener() { ... }

The way we solve this is to import the Maven 2 IDEA UI Designer Plugin into the pom:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>ideauidesigner-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>javac2</goal>
            </goals>
        </execution>
    </executions>

    <configuration>
        <fork>true</fork>
        <debug>true</debug>
        <failOnError>true</failOnError>
    </configuration>
</plugin>

Let’s see what the maven build does now by running clean install

How about that? The sweet taste of build success :)

This means now that the plugin is working. The next and final step is to create an executable jar via maven for this project. For this we will use the maven-jar-plugin to get a jar with the correct manifest and the maven-archive-plugin to get a lib directory with the dependencies in it which the manifest will refer to.
So, just add the following to the pom:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>net.glxn.jmsutility.JMSUtility</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

At this point you should have a pom that looks like this: http://github.com/kenglxn/JMSUtility/blob/b217473ab420550ac81f149c2de22497e3bef303/pom.xml
Now let’s run the executable jar by going to the target folder and running ‘java -jar JMSUtil.jar’

And that’s it. You now have a maven build with tests and automatic building of the executable jar.

Feel free to clone the code and do whatever you like with it, just dont blame me :P

The distribution zip with jar and lib can be downloaded directly here: http://github.com/kenglxn/JMSUtility/raw/master/dist/JMSUtility.zip

RESOURCES:
http://maven.apache.org/shared/maven-archiver/index.html
http://mojo.codehaus.org/ideauidesigner-maven-plugin/
http://maven.apache.org/plugins/maven-dependency-plugin/examples/copying-project-dependencies.html
http://repo1.maven.org/maven2/com/intellij/forms_rt/
http://www.jetbrains.com/idea/features/gui_builder.html

Using Arquillian to test against a remote jboss container from within IDEA

I recently got introduced to Arquillian. Arquillian is a JBoss project for providing better testing to the java ee stack.
Arquillian utilizes ShrinkWrap, another great project, for creating virtual archives as deployments to the container.
It’s all pretty damn slick :)
I encourage you to take a dive into the community. It’s well organized and alive.

In this post I’m going to look at running Arquillian against jboss as 6 remotely from within Intellij IDEA.

First off I have generated a project using the minimal Java EE Weld archetype. The Weld Archvetype will in the near future have support for generating the Arquillian part of the project as well.

To get the project into IDEA is really simple, just choose ‘open project’ and select the pom of the generated maven project.
IDEA will then take a couple of minutes setting things up.

For Arquillian magic to work, we need to add junit (or you could use testng if you prefer), and the arquillian dependency to the pom.

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.8.1</version>
	<scope>test</scope>
</dependency>

<dependency>
	<groupId>org.jboss.arquillian</groupId>
	<artifactId>arquillian-junit</artifactId>
	<version>1.0.0-SNAPSHOT</version>
	<scope>test</scope>
</dependency>

Then we add a profile to the pom for running the tests against the remote jboss container.

<profiles>
	<profile>
		<id>jbossas-remote-60</id>
		<dependencies>
			<dependency>
				<groupId>org.jboss.arquillian.container</groupId>
				<artifactId>arquillian-jbossas-remote-60</artifactId>
				<version>1.0.0-SNAPSHOT</version>
				<scope>test</scope>
			</dependency>
		</dependencies>
	</profile>
</profiles>

Notice that I have set the scope on the profile to test.
The reason for this is that i use IDEA to deploy the project to the server (not maven), and I don’t want to toggle the profile in maven plugin all the time.
If the profile is activated when you do a redeploy, then IDEA will(rightfully so) think you want these dependencies deployed as part of the project and deployment will fail.

So, let’s have some fun.

For my test case I have created a very simple Bean:

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@RequestScoped
@Named
public class HelloAction {

    private String input;
    private String output;

    public void say() {
        output = "You said: " + input;
		System.out.println(output);
    }

    public String getOutput() {
        return output;
    }

    public void setOutput(String output) {
        this.output = output;
    }

    public String getInput() {
        return input;
    }

    public void setInput(String input) {
        this.input = input;
    }
}

I want to deploy this bean to the container, and test it. The Following test case does the trick:

import org.jboss.arquillian.api.Deployment;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ArchivePaths;
import org.jboss.shrinkwrap.api.Archives;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.impl.base.asset.ByteArrayAsset;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import javax.inject.Inject;

@RunWith(org.jboss.arquillian.junit.Arquillian.class)
public class HelloTestCase {
   @Deployment
   public static Archive&lt;?&gt; createDeployment() {
            JavaArchive archive = Archives.create("test.jar", JavaArchive.class)
                 .addClasses(HelloAction.class)
                 .addManifestResource(new ByteArrayAsset("<beans></beans>".getBytes()),
                                 ArchivePaths.create("beans.xml"));

            return archive;
   }

   @Inject
   HelloAction helloAction;

   @Test
   public void helloBeanShouldSayHello() {
       helloAction.setInput("hello");
       helloAction.say();
       Assert.assertEquals("You said: hello", helloAction.getOutput());
   }
}

The @Deployment method describes the virtual archive I want deployed to the container.
Here I create a simple archive and add the class I want to test.
For CDI beans to work you will have to add the beans.xml to the archive.

We also need to add jndi.properties file to the project. This is needed for Arquillian to be able to connect to the remote container. Make sure that java.naming.provider.url reflects the IP of your remote server instance.
Place jndi.properties file under src/test/resources:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://localhost:1099

Now we simply run the test from within IDEA using right click > run test, or ctrl+shift+f10.
Just remember that this is a test running against a remote jboss container, so jboss needs to be running ;)

We see the test runs green:

And that the server has the expected output in the log:

Just for kicks, let’s break the test by changing the input to “yo”:

TIP: If you want to debug your test, you have to remember that your code is running in the remote container. Running the test in debug mode will not work. You will have to start the container in debug mode to do this.

See the Arquillian FAQ page for more tips.

Solving Sudoku using java swing and junit

Was working on sudoku puzzles during easter holiday. Became bored, and being the nerd I am decided to practice my swing and created a tool to help solve it.
Keep in mind that this is a “quickie” job, created in couple days work.
Just extract and run:

java -jar jSudoku.jar

Comes with one predefined sample.
jSudokuSolver.zip

Or you can run the app with Java Web Start by clicking this link: jsudoku (should open with java, won’t work on chrome ref: http://code.google.com/p/chromium/issues/detail?id=10877)

Feel free to use the source for whatever you wish.
If you want you can clone my git repo http://github.com/kenglxn/JSudoku:

git clone git://github.com/kenglxn/JSudoku.git

I based my implementation on a sudoku puzzle found in a magazine. I picked a puzzle from the magazine and made this the sample. Then i wrote a test to confirm the solver worked for the two axis, and the sub-grid. Then the last test to confirm the solver get’s the expected solution. Code for the test is pasted below.

Heres the sample (click for larger image):

And here’s the sample solved (click for larger image):

This is the recursive method that does all the work:

void solvePuzzle(Integer numberOfEmptyCellsBefore) {
	createWorkingSetOfShallowCopyCells();
	calculatePossibleValuesAndSetCellValues();
	commitChangesToAllCells();

	Integer numberOfEmptyCells = getNumberOfEmptyCellsInGrid();
	if (!numberOfEmptyCells.equals(numberOfEmptyCellsBefore)) {
		solvePuzzle(numberOfEmptyCells);
	}
}

Heres a paste of the junit test that i used to build the logic:
(ignore the closing xml tags at the bottom, google code formatter plugin generates these due to unclosed tags in the java code…)

package net.glxn.sudoku;

import org.junit.Assert;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;

public class JSudokuTestCase {
    @Test
    public void shouldSolveforXSibling() {
        String expected = "9";

        JSudoku jSudoku = new JSudoku();
        ArrayList<Cell> xSiblings = jSudoku.textField9.xSiblings;
        ArrayList<String> stringList = new ArrayList<String>();
        stringList.addAll(Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8"));

        for (Cell xSib : xSiblings) {
            xSib.setText(stringList.get(0));
            stringList.remove(0);
        }

        jSudoku.solvePuzzle(jSudoku.getNumberOfEmptyCellsInGrid());

        Assert.assertEquals(expected, jSudoku.textField9.getText());
    }

    @Test
    public void shouldSolveforYSibling() {
        String expected = "9";

        JSudoku jSudoku = new JSudoku();
        ArrayList<Cell> ysiblings = jSudoku.textField9.ySiblings;
        ArrayList<String> stringList = new ArrayList<String>();
        stringList.addAll(Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8"));

        for (Cell ySib : ysiblings) {
            ySib.setText(stringList.get(0));
            stringList.remove(0);
        }

        jSudoku.solvePuzzle(jSudoku.getNumberOfEmptyCellsInGrid());

        Assert.assertEquals(expected, jSudoku.textField9.getText());
    }

    @Test
    public void shouldSolveforSubGridSibling() {
        String expected = "9";

        JSudoku jSudoku = new JSudoku();
        ArrayList<Cell> ysiblings = jSudoku.textField9.subGridSiblings;
        ArrayList<String> stringList = new ArrayList<String>();
        stringList.addAll(Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8"));

        for (Cell ySib : ysiblings) {
            ySib.setText(stringList.get(0));
            stringList.remove(0);
        }

        jSudoku.solvePuzzle(jSudoku.getNumberOfEmptyCellsInGrid());

        Assert.assertEquals(expected, jSudoku.textField9.getText());
    }

    @Test
    public void shouldBeAbleToSolveSample() {
        JSudoku jSudoku = new JSudoku();
        jSudoku.loadSample();

        confirmSample(jSudoku);

        jSudoku.solvePuzzle(jSudoku.getNumberOfEmptyCellsInGrid());

        confirmWholeGrid(jSudoku);
    }

    private void confirmSample(JSudoku jSudoku) {
        confirmExpectedValueAtCoord(jSudoku, 2, 1, 1);
        confirmExpectedValueAtCoord(jSudoku, 4, 1, 9);
        confirmExpectedValueAtCoord(jSudoku, 5, 1, 5);
        confirmExpectedValueAtCoord(jSudoku, 7, 1, 7);

        confirmExpectedValueAtCoord(jSudoku, 2, 2, 5);
        confirmExpectedValueAtCoord(jSudoku, 5, 2, 3);

        confirmExpectedValueAtCoord(jSudoku, 2, 3, 9);
        confirmExpectedValueAtCoord(jSudoku, 4, 3, 6);
        confirmExpectedValueAtCoord(jSudoku, 9, 3, 5);

        confirmExpectedValueAtCoord(jSudoku, 1, 4, 2);
        confirmExpectedValueAtCoord(jSudoku, 3, 4, 6);
        confirmExpectedValueAtCoord(jSudoku, 6, 4, 8);

        confirmExpectedValueAtCoord(jSudoku, 3, 5, 8);
        confirmExpectedValueAtCoord(jSudoku, 7, 5, 4);

        confirmExpectedValueAtCoord(jSudoku, 4, 6, 3);
        confirmExpectedValueAtCoord(jSudoku, 7, 6, 6);
        confirmExpectedValueAtCoord(jSudoku, 9, 6, 9);

        confirmExpectedValueAtCoord(jSudoku, 1, 7, 4);
        confirmExpectedValueAtCoord(jSudoku, 6, 7, 3);
        confirmExpectedValueAtCoord(jSudoku, 8, 7, 5);

        confirmExpectedValueAtCoord(jSudoku, 5, 8, 8);
        confirmExpectedValueAtCoord(jSudoku, 8, 8, 6);

        confirmExpectedValueAtCoord(jSudoku, 3, 9, 1);
        confirmExpectedValueAtCoord(jSudoku, 5, 9, 4);
        confirmExpectedValueAtCoord(jSudoku, 6, 9, 5);
        confirmExpectedValueAtCoord(jSudoku, 8, 9, 2);
    }

    private void confirmWholeGrid(JSudoku jSudoku) {
        confirmExpectedValueAtCoord(jSudoku, 1, 1, 8);
        confirmExpectedValueAtCoord(jSudoku, 2, 1, 1);
        confirmExpectedValueAtCoord(jSudoku, 3, 1, 2);
        confirmExpectedValueAtCoord(jSudoku, 4, 1, 9);
        confirmExpectedValueAtCoord(jSudoku, 5, 1, 5);
        confirmExpectedValueAtCoord(jSudoku, 6, 1, 4);
        confirmExpectedValueAtCoord(jSudoku, 7, 1, 7);
        confirmExpectedValueAtCoord(jSudoku, 8, 1, 3);
        confirmExpectedValueAtCoord(jSudoku, 9, 1, 6);

        confirmExpectedValueAtCoord(jSudoku, 1, 2, 6);
        confirmExpectedValueAtCoord(jSudoku, 2, 2, 5);
        confirmExpectedValueAtCoord(jSudoku, 3, 2, 4);
        confirmExpectedValueAtCoord(jSudoku, 4, 2, 8);
        confirmExpectedValueAtCoord(jSudoku, 5, 2, 3);
        confirmExpectedValueAtCoord(jSudoku, 6, 2, 7);
        confirmExpectedValueAtCoord(jSudoku, 7, 2, 2);
        confirmExpectedValueAtCoord(jSudoku, 8, 2, 9);
        confirmExpectedValueAtCoord(jSudoku, 9, 2, 1);

        confirmExpectedValueAtCoord(jSudoku, 1, 3, 7);
        confirmExpectedValueAtCoord(jSudoku, 2, 3, 9);
        confirmExpectedValueAtCoord(jSudoku, 3, 3, 3);
        confirmExpectedValueAtCoord(jSudoku, 4, 3, 6);
        confirmExpectedValueAtCoord(jSudoku, 5, 3, 2);
        confirmExpectedValueAtCoord(jSudoku, 6, 3, 1);
        confirmExpectedValueAtCoord(jSudoku, 7, 3, 8);
        confirmExpectedValueAtCoord(jSudoku, 8, 3, 4);
        confirmExpectedValueAtCoord(jSudoku, 9, 3, 5);

        confirmExpectedValueAtCoord(jSudoku, 1, 4, 2);
        confirmExpectedValueAtCoord(jSudoku, 2, 4, 7);
        confirmExpectedValueAtCoord(jSudoku, 3, 4, 6);
        confirmExpectedValueAtCoord(jSudoku, 4, 4, 4);
        confirmExpectedValueAtCoord(jSudoku, 5, 4, 9);
        confirmExpectedValueAtCoord(jSudoku, 6, 4, 8);
        confirmExpectedValueAtCoord(jSudoku, 7, 4, 5);
        confirmExpectedValueAtCoord(jSudoku, 8, 4, 1);
        confirmExpectedValueAtCoord(jSudoku, 9, 4, 3);

        confirmExpectedValueAtCoord(jSudoku, 1, 5, 9);
        confirmExpectedValueAtCoord(jSudoku, 2, 5, 3);
        confirmExpectedValueAtCoord(jSudoku, 3, 5, 8);
        confirmExpectedValueAtCoord(jSudoku, 4, 5, 5);
        confirmExpectedValueAtCoord(jSudoku, 5, 5, 1);
        confirmExpectedValueAtCoord(jSudoku, 6, 5, 6);
        confirmExpectedValueAtCoord(jSudoku, 7, 5, 4);
        confirmExpectedValueAtCoord(jSudoku, 8, 5, 7);
        confirmExpectedValueAtCoord(jSudoku, 9, 5, 2);

        confirmExpectedValueAtCoord(jSudoku, 1, 6, 1);
        confirmExpectedValueAtCoord(jSudoku, 2, 6, 4);
        confirmExpectedValueAtCoord(jSudoku, 3, 6, 5);
        confirmExpectedValueAtCoord(jSudoku, 4, 6, 3);
        confirmExpectedValueAtCoord(jSudoku, 5, 6, 7);
        confirmExpectedValueAtCoord(jSudoku, 6, 6, 2);
        confirmExpectedValueAtCoord(jSudoku, 7, 6, 6);
        confirmExpectedValueAtCoord(jSudoku, 8, 6, 8);
        confirmExpectedValueAtCoord(jSudoku, 9, 6, 9);

        confirmExpectedValueAtCoord(jSudoku, 1, 7, 4);
        confirmExpectedValueAtCoord(jSudoku, 2, 7, 8);
        confirmExpectedValueAtCoord(jSudoku, 3, 7, 9);
        confirmExpectedValueAtCoord(jSudoku, 4, 7, 2);
        confirmExpectedValueAtCoord(jSudoku, 5, 7, 6);
        confirmExpectedValueAtCoord(jSudoku, 6, 7, 3);
        confirmExpectedValueAtCoord(jSudoku, 7, 7, 1);
        confirmExpectedValueAtCoord(jSudoku, 8, 7, 5);
        confirmExpectedValueAtCoord(jSudoku, 9, 7, 7);

        confirmExpectedValueAtCoord(jSudoku, 1, 8, 5);
        confirmExpectedValueAtCoord(jSudoku, 2, 8, 2);
        confirmExpectedValueAtCoord(jSudoku, 3, 8, 7);
        confirmExpectedValueAtCoord(jSudoku, 4, 8, 1);
        confirmExpectedValueAtCoord(jSudoku, 5, 8, 8);
        confirmExpectedValueAtCoord(jSudoku, 6, 8, 9);
        confirmExpectedValueAtCoord(jSudoku, 7, 8, 3);
        confirmExpectedValueAtCoord(jSudoku, 8, 8, 6);
        confirmExpectedValueAtCoord(jSudoku, 9, 8, 4);

        confirmExpectedValueAtCoord(jSudoku, 1, 9, 3);
        confirmExpectedValueAtCoord(jSudoku, 2, 9, 6);
        confirmExpectedValueAtCoord(jSudoku, 3, 9, 1);
        confirmExpectedValueAtCoord(jSudoku, 4, 9, 7);
        confirmExpectedValueAtCoord(jSudoku, 5, 9, 4);
        confirmExpectedValueAtCoord(jSudoku, 6, 9, 5);
        confirmExpectedValueAtCoord(jSudoku, 7, 9, 9);
        confirmExpectedValueAtCoord(jSudoku, 8, 9, 2);
        confirmExpectedValueAtCoord(jSudoku, 9, 9, 8);
    }

    private void confirmExpectedValueAtCoord(JSudoku jSudoku, int x, int y, Integer expected) {
        Assert.assertEquals("Confirm ["+x+","+y+"] = "+ expected, expected, jSudoku.getCellAtCoord(x, y, jSudoku.allCells).getIntValue());
    }
}

Implementing @RequestParam in CDI/WELD using Qualifier and InjectionPoint as @HttpParam

Implementing @RequestParam as @HttpParam is quite easy. This is the example discussed in the Weld Reference Documentation. What we do is set up a Qualifier like this:

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface HttpParam {
    public String value() default "";
}

Then all we need to do is create a Producer Method: and utilize the InjectionPoint metadata to set the proper value based on either the name of the attribute or the value of the annotation. This example will ensure that both:

 @Inject @HttpParam("trackId")
 String currentTrackId;

and

 @Inject @HttpParam
 String trackId;

Makes the request parameter “trackId” available to the field. Example url: http://www.glxn.net/listen?trackId=16180339 will set currentTrackId in the first example above to 16180339, and in the second set trackId to the same value.

public class HttpParamProducer {

    @Inject
    FacesContext facesContext;

    @Produces
    @HttpParam
    String getHttpParameter(InjectionPoint ip) {
        String name = ip.getAnnotated().getAnnotation(HttpParam.class).value();
        if ("".equals(name)) name = ip.getMember().getName();
        return facesContext.getExternalContext()
                .getRequestParameterMap()
                .get(name);
    }
}

Now we can access the request parameter in our Bean simply by annotating the field with @Inject and @HttpParam. In the example below I am injecting the @SessionScoped bean SpotifyWeb, and calling its wrap method to enrich my request parameter “trackId” using a Producer method to create a @Named parameter “trackReqParam” available to another bean, or in my case the view. So in my view page i print out #{trackReqParam} and it shows the initial request parameter trackId with some modification done in the wrap method. Just a simple example of it’s application.
The key here is that you can’t inject a request parameter to a session scoped bean and expect it to not live in the dependent scope of its parent. That means if you do inject it to a session scoped bean, it is injected and set once, then lives in that scope until the scope is terminated.
This enforces good design in my opinion. If you are using a session scoped bean and want values from it, it’s variables and methods are readily available to a request scoped bean, so just inject it and do your work there. This ensures a slim application.

@RequestScoped
public class TrackProducer {

    @Inject @HttpParam
    String trackId;

    @Inject
    SpotifyWeb spotifyWeb;

    @Produces
    @Named("trackReqParam")
    String getTrack() {
        return spotifyWeb.wrap(trackId);
    }
}

You may also want to look at Injection point metadata API for Web Beans by Gavin King

Simple CDI/WELD login example

[Gliffy Diagram is Private]

View

<h:form id="spotifylogin" class="loginform spotifyform">
    <h2>Spotify login</h2>
    <p>Please log in to your spotify account</p>

    <h:outputLabel for="spotifyusername" value="Username:"></h:outputLabel>
    <h:inputText id="spotifyusername" value="#{spotiWelder.username}"></h:inputText>
    <h:message for="spotifyusername" errorClass="invalid"></h:message>

    <h:outputLabel for="spotifypassword" value="Password:"></h:outputLabel>
    <h:inputSecret id="spotifypassword" value="#{spotiWelder.password}"></h:inputSecret>
    <h:message for="spotifypassword" errorClass="invalid"></h:message>

    <h:commandButton id="login" action="#{spotifyWeb.login}" value="Log in!"></h:commandButton>
</h:form>

Entity

@Entity
public class SpotiWelder implements Serializable {

    private static final long serialVersionUID = -6625241632523446019L;

    private Long id;

    private String username;

    private String password;

    public SpotiWelder() {
    }

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @NotNull
    @NotEmpty
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @NotNull
    @NotEmpty
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Action Bean

@SessionScoped
@Named
public class SpotifyWeb implements Serializable {

    private static final long serialVersionUID = -352191768337315102L;

    private Logger log;

    SpotiWelder spotiWelder = new SpotiWelder();

    @Inject
    FacesContext facesContext;

    public SpotifyWeb() {
        this.log = Logger.getLogger(this.getClass().getSimpleName());
        connection = new SpotiWeldConnection();
    }

    @PostConstruct
    public void initialize() {
        log.info(this.getClass().getSimpleName() + " was constructed");
    }

    public void login() {
        connection.login(spotiWelder.getUsername(), spotiWelder.getPassword());

        log.info("succesful login for " + loggedInUser);
        facesContext.addMessage(null, new FacesMessage("Welcome " + loggedInUser.getName()));
    }

    @Produces @Named
    public SpotiWelder getSpotiWelder() {
        return spotiWelder;
    }
}
  • Remember to add an empty constructor to your entity when using via @Producer methods. If not you might get the dreaded “java.lang.IllegalArgumentException: Object: foo is not a known entity type.”
  • Remeber to add @GeneratedValue to @Id field on Entity.

related:
http://seamframework.org/Community/JPAEntityIsUnknownWhenUsingTheModelAnnotation
http://www.seamframework.org/Community/ErrorWhenUsingSessionScopedAndEntityAnnotation