Thursday, December 22, 2011

Fix Jackson/JAXB JSON Serialization Problem with Spring Data Neo4j @NodeEntity Objects

Spring Data Neo4j @NodeEntity-annotated objects are proxy-enriched by Spring Data Neo4j aspects using AspectJ. There are times we want to expose these objects via JAX-RS REST API or JAX-WS / SOAP web services and then (by default) we will have problems.

The error stacktrace messages (here using JBoss AS 7.0.2) are along the lines of:

HTTP Status 500 - org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.neo4j.graphdb.DynamicRelationshipType and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.satukancinta.domain.User["enjoyActivities"]->org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet[0]->com.satukancinta.domain.Activity["persistentState"]->org.neo4j.rest.graphdb.entity.RestNode["relationships"]->org.neo4j.rest.graphdb.entity.RestRelationship["type"])


type Status report

message org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.neo4j.graphdb.DynamicRelationshipType and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.satukancinta.domain.User["enjoyActivities"]->org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet[0]->com.satukancinta.domain.Activity["persistentState"]->org.neo4j.rest.graphdb.entity.RestNode["relationships"]->org.neo4j.rest.graphdb.entity.RestRelationship["type"])

description The server encountered an internal error (org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.neo4j.graphdb.DynamicRelationshipType and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.satukancinta.domain.User["enjoyActivities"]->org.springframework.data.neo4j.fieldaccess.ManagedFieldAccessorSet[0]->com.satukancinta.domain.Activity["persistentState"]->org.neo4j.rest.graphdb.entity.RestNode["relationships"]->org.neo4j.rest.graphdb.entity.RestRelationship["type"])) that prevented it from fulfilling this request.

To solve this problem, annotate your entity class with @JsonAutoDetect(JsonMethod.NONE) :

import org.codehaus.jackson.annotate.JsonAutoDetect;

import org.codehaus.jackson.annotate.JsonMethod;

import org.codehaus.jackson.annotate.JsonProperty;


@NodeEntity @JsonAutoDetect(JsonMethod.NONE)

public class User implements NodeBacked {

then manually annotate each property you want to serialize with @JsonProperty :

@JsonProperty

public String getName() {

return name;

}

Now the JAX-RS Application works as intended and everybody is happy. :-) There's also a StackOverflow thread that discusses this problem.

To learn more about Java Web Development using Java EE 6, I highly recommend The Java EE 6 Tutorial: Basic Concepts (4th Edition) (Java Series) by Eric Jendrock, Ian Evans, Devika Gollapudi and Kim Haase.

How to Resolve Spring Data Neo4j / Jersey / Jackson Conflict with JBoss AS 7 RESTEasy

I'm using Spring Data Neo4j REST Client which uses Jersey JAX-RS Client. Unfortunately when deployed to JBoss AS 7.0.2, it conflicts with the built-in RESTEasy deployer (bug DATAGRAPH-159).

In order to run the application, jersey-server must be excluded :

<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-neo4j-rest</artifactId> <version>${spring-data-neo4j.version}</version> <exclusions> ... <exclusion> <artifactId>jersey-server</artifactId> <groupId>com.sun.jersey</groupId> </exclusion> </exclusions> </dependency>

Another issue I came across is my web application is also a JAX-RS Service Application, therefore it requires JBoss RESTEasy. Unfortunately Jackson JSON Provider which is a dependency of Neo4j REST Client and Jersey JAX-RS Client conflicts with RESTEasy's Jackson Provider, with the following exception stacktrace message:

java.lang.RuntimeException: Unable to instantiate MessageBodyReader  org.jboss.resteasy.spi.ResteasyProviderFactory.registerProvider(ResteasyProviderFactory.java:760)  org.jboss.resteasy.spi.ResteasyProviderFactory.registerProvider(ResteasyProviderFactory.java:742)  org.jboss.resteasy.spi.ResteasyDeployment.registerProvider(ResteasyDeployment.java:505)  org.jboss.resteasy.spi.ResteasyDeployment.registration(ResteasyDeployment.java:305)  org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:225)  org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.init(ServletContainerDispatcher.java:67)  org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.init(HttpServletDispatcher.java:36)  org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:139)  org.jboss.as.web.NamingValve.invoke(NamingValve.java:57)  org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)  org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)  org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:897)  org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:626)  org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:2054)  java.lang.Thread.run(Thread.java:722)

root cause

java.lang.RuntimeException: Illegal to inject a message body into a singleton into public org.codehaus.jackson.jaxrs.JacksonJsonProvider(org.codehaus.jackson.map.ObjectMapper,org.codehaus.jackson.jaxrs.Annotations[])  org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:209)  org.jboss.resteasy.core.ConstructorInjectorImpl.injectableArguments(ConstructorInjectorImpl.java:63)  org.jboss.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:129)  org.jboss.resteasy.spi.ResteasyProviderFactory.getProviderInstance(ResteasyProviderFactory.java:1038)

I thought this was issue RESTEASY-503, because JBoss AS 7.0.2 happened to use the somewhat buggy RESTEasy 2.2.1.GA. But it turns out there is an easy fix to this problem, thanks to Configuring Module Classloading in JBoss AS 7.

Edit src/main/webapp/WEB-INF/jboss-deployment-structure.xml as follows:


<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">

<deployment>

<dependencies>

<module name="org.codehaus.jackson.jackson-jaxrs"/>

<module name="org.codehaus.jackson.jackson-core-asl"/>

<module name="org.codehaus.jackson.jackson-mapper-asl"/>

</dependencies>

</deployment>

</jboss-deployment-structure>

Now Spring Data Neo4j, Jersey Client with JSON Jackson Provider, and my JAX-RS Application served by RESTEasy, all can coexist in the same web application WAR. :-)

To learn more about Java Web Development using Java EE 6, I highly recommend The Java EE 6 Tutorial: Basic Concepts (4th Edition) (Java Series) by Eric Jendrock, Ian Evans, Devika Gollapudi and Kim Haase.

Wednesday, December 7, 2011

I don't "get" JSON Output in Pentaho Data Integration (PDI) / Kettle

I don't understand how to use the JSON Output step properly in Kettle aka Pentaho Data Integration (PDI).

With "Nr of rows in a bloc" set to 0 or 3, I got:

{
  "categories": [
    {
      "code": "WORKAHOLIC-CHIC"
    },
    {
      "name": "Workaholic Chic"
    },
    {
      "description": "Move ! Move ! move...!!\nLight Up Your Day... with a perfect match, \nPadanan busana kerja Professsional look, Powerfull & Fashionable,\nwhich got several design for different mood,  multifunction,\nMemorable style!\nLet’s be and stay Tuneeca...\n"
    }
  ]
}

which is basically only the last record.

With "Nr of rows in a bloc" set to 1, I got:

{
  "categories": [
    {
      "code": "AKSESORI-LIGHT-UP-YOUR-DAY"
    },
    {
      "name": "Aksesori Light Up Your Day"
    },
    {
      "description": "-"
    },
    {
      "code": "AKSESORIS-APRIL-2009"
    },
...

What I'm trying to get is:

{ "categories": [
  { "code": "AKSESORI-LIGHT-UP-YOUR-DAY",
     "name": "Aksesori Light Up Your Day"
     "description": "Very cool" },
  { "code": .........

Contrast this with the XML Output, which I get the following correct output right from first try:

<?xml version="1.0" encoding="UTF-8"?>
<categories>
  <category>
    <code>AKSESORI-LIGHT-UP-YOUR-DAY</code>
    <name>Aksesori Light Up Your Day</name>
    <description>-</description>
  </category>
  <category>
    <code>AKSESORIS-APRIL-2009</code>
...

An additional plus is that XML Output already performs a bit of output pretty formatting, which I appreciate very much. (JSON Output outputs everything in a single line)

Those two Output steps gets the same input data.

Any ideas ?

Wednesday, October 26, 2011

Seam Framework Java EE Library version 3.1.0.Beta4 Released

As per usual, let's get the links out of the way first:

Download Seam 3.1.0.Beta4

Reference Documentation

API Documentation

Report Issues

For Maven users, there is a new version of the Seam Bill of Materials:

<dependency> <groupId>org.jboss.seam</groupId> <artifactId>seam-bom</artifactId> <version>3.1.0.Beta4</version> <type>pom</type> <scope>import</scope> </dependency>

I know that we promised a CR1 release for Seam 3.1 at about this time, however the Seam QA team have done their jobs a little too well and identified a number of issues with the Beta3 release which we wanted to get fixed before we go to a candidate release. The great news for this release is that we've fixed 68 issues - you can view the issue list here:

https://issues.jboss.org/secure/IssueNavigator.jspa?mode=hide&requestId=12315988

Included in this release is a number of new features, improved documentation and a brand new Arquillian-based structure for our test suites to make it easier to test each module on multiple containers. We've also squashed a great deal of bugs, improved stability, plus made a number of other minor improvements.

As we still have quite a few open issues remaining for the Seam 3.1 release, we will likely release another beta in the next couple of weeks. We want this release to be rock solid, so please try out the beta and let us know if you find any problems.

(Article copied verbatim from in.relation.to)

To learn more about Java Web Development using Java EE 6, I highly recommend The Java EE 6 Tutorial: Basic Concepts (4th Edition) (Java Series) by Eric Jendrock, Ian Evans, Devika Gollapudi and Kim Haase.

Friday, September 30, 2011

m2e/m2eclipse-wtp 0.14.0 Released: Eclipse IDE Integration for Java EE 6 / Web Application Maven projects

Maven Integration for Eclipse WTP 0.14.0, a.k.a m2eclipse-wtp, a.k.a m2e-wtp is out the door. This new release brings its share of new features and enhancements, as well as a bunch of bug fixes. The complete release notes are available here.

m2e-wtp 0.14.0 works with Eclipse Helios and Indigo, requires at least m2e 1.0 and mavenarchiver plugin > 0.14.0 (0.15.0 should be automatically installed). As usual, m2e-wtp can be installed from :

So what's new and noteworthy in 0.14.0? Let's see :

New support for Application Client projects

Application Client packaging has been introduced with the new maven-acr-plugin. Support for app-client type dependencies has been added in maven-ear-plugin 2.6. Since Application Client projects are natively supported in WTP, we added a new configurator for app-client projects. When an app-client project is imported / configured via m2e, the Application Client Facet will be automatically installed, its version inferred from the contents of META-INF/application-client.xml. Filtering of the deployment descriptor is supported.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-acr-plugin</artifactId>
  <version>1.0</version>
  <extensions>true</extensions>
  <configuration>
    <archive>
      <manifest>
        <mainClass>foo.bar.appclient.Main</mainClass>
      </manifest>
    </archive>
    <filterDeploymentDescriptor>true</filterDeploymentDescriptor>
  </configuration>
</plugin>

appclient.png

New support for Web Fragment projects

If a project contains a META-INF/web-fragment.xml in it's compilation output folder, the Web Fragment Facet is automatically installed upon maven project configuration (the Utility Facet is removed if necessary). Note that, as per the Java EE6 spec - and WTP is very picky about it-, Web Fragment projects *must* use Java 1.6. Failure to comply will fail the configuration and an error marker will be displayed.

webfragment.png

The use of target/m2e-wtp/web-resources is now optional

On some occasions however, having target/m2e-wtp/web-resources/ might cause some troubles (incompatibilities with WTP editors, IBM RAD, using Servlet.getRealPath(...) in your code).
As a workaround, you can choose to not use target/m2e-wtp/web-resources/ and generate the pom.properties and MANIFEST.MF files in your source directory instead (It'll be your responsibility to add these files to your SCM ignore list).
In order to remove target/m2e-wtp/web-resources/ from the list of deployed folders, you need to change some preferences :
  • on your project only : right-click on the project > Properties > Maven > WTP : check "Enable Project Specific Settings" and uncheck "Maven Archiver generates files under the build directory"
  • on the whole workspace : Window > Preferences > Maven > WTP : uncheck "Maven Archiver generates files under the build directory"

war-preferences.png
Please note that this setting will be overridden if web resource filtering is in use, that is if the maven-war-plugin configuration declares <webResources> or sets <filterDeploymentDescriptor> to true. The reason is simple : you don't want to see your source files overwritten by the filtering mechanism (and it would also lead to some not-so-funny build loops).

Custom file name mapping for web project dependencies

Since the maven-war-plugin allows file name customization for librairies and TLDs, based on patterns (http://maven.apache.org/plugins/maven-war-plugin/examples/file-name-mapping.html), we added the the same feature in m2e-wtp. That will allow you to use a version-less name mapping for dependencies, like :

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-war-plugin</artifactId>
  <version>2.1.1</version>
  <configuration>
    <outputFileNameMapping>@{groupId}@-@{artifactId}@.@{extension}@</outputFileNameMapping>
  </configuration>
</plugin>

The trick here is, in order to support non default filename mappings of dependencies listed in the Maven Library, the artifact is copied to the build directory (the target/ folder by default) under its new name. So if you happen to run a clean build of your project, wiping out that directory, you will need to manually run "Maven > Update Project configuration" on your project.

Option to not publish overlay changes automatically

In order to support publishing of overlay changes automatically, m2e-wtp aggressively cleared the cache of the servers your application is deployed to. However, The overlay feature still being in an experimental state, we decided to be more conservative with regard to server publishing, so a new "Automatically republish servers on overlay modification" preference has been added to Window > Preferences > Server > Overlays.

overlay-republishing-preference.png
Overlays support is not bound to Maven, that's why it's under the Server preferences.

Support for the new tag="defaultRootSource" introduced in WTP 3.3.1

When several source folders are declared in the .settings/org.eclipse.wst.common.component file, WTP prior to 3.3.1 (Indigo SR1) tended to generate files (web.xml, faces-config.xml, ...) in the first folder it found. Since web projects define target/m2e-wtp/web-resources as the first source folder (target/m2e-wtp/ear-resources/ for EAR projects), that would cause some issues. In WTP 3.3.1, a new tag has been introduced, designed to indicate which source folder should be used by default, when files need to be looked for / generated. m2e-wtp now adds this tag when WTP 3.3.1 is installed :

<project-modules id="moduleCoreId" project-version="1.5.0">
    <wb-module deploy-name="web-0.0.1-SNAPSHOT">
        <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
        <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
         <property name="context-root" value="multi-web"/>
        <property name="java-output-path" value="/multi-web/target/classes"/>
    </wb-module>
</project-modules>

A bit of documentation

As many projects, unfortunately, m2e-wtp doesn't shine in the documentation area. I've been using the github Wiki (https://github.com/sonatype/m2eclipse-wtp/wiki) to start a relatively modest FAQ. I'm planning on adding more content in the near future, but I'm also hoping the community at large will want to contribute some docs of its own. You just need a github account to be able to edit the Wiki.


As always, if you find any issue, please open a bug report at https://issues.sonatype.org/browse/MECLIPSEWTP (and don't forget to attach some test projects).

Happy coding.

Fred.
https://twitter.com/#!/fbricon

(the article above is copied verbatim from Planet JBoss)

Hendy's personal note:
To learn more about Java Web Development using Eclipse IDE and Java EE 6, I highly recommend The Java EE 6 Tutorial: Basic Concepts (4th Edition) (Java Series) by Eric Jendrock, Ian Evans, Devika Gollapudi and Kim Haase.

Monday, September 19, 2011

JBoss Tools 3.3.0.M3 Released: Eclipse Plug-ins for Java EE 6 + JSF 2.0 Web Development

It's time for a new fresh milestone update of JBoss Tools:

grease_jboss_tools.png

3.3 M3 (Greased Lightning)

[Download] [Update Site] [What's New] [Forums] [JIRA] [Twitter]

 

 

JBoss Tools is a set of plugins for Eclipse Java IDE that complements, enhances and goes beyond the support that exist for JBoss and related technologies in the default Eclipse distribution. For this release we continue to move Maven, CDI, Java EE 6 support forward and also add in a few new "surprise" features.

To know more about Java EE 6, I highly recommend The Java EE 6 Tutorial: Basic Concepts (4th Edition) (Java Series) by Eric Jendrock, Ian Evans, Devika Gollapudi and Kim Haase


Installation

 

As always, get and install Eclipse 3.7 (Indigo) JEE bundle - with the JEE bundle you majority of the dependencies letting you save bandwidth:

 

Once you have installed Eclipse, you either find us on Eclipse Marketplace under "JBoss Tools (Indigo)" or use our update site directly.

 

The updatesite URL to use from Help > Install New Software... is:

 

http://download.jboss.org/jbosstools/updates/development/indigo/


Maven Profile Selection

In this release we've therefore included an UI which allows you to easily set/change the profiles on single and multiple projects.

 

This is especially something that becomes useful when you use Arquillian where it is a common practice to use Maven profiles to toggle the various dependency sets for each server you wish to test against.

 

It works by you selecting the relevant project(s), press Ctrl+Alt+P or use Maven > Select Maven Profiles... and a dialog box appears allowing you to enable/disable the available profiles for the project(s):

 

maven-profile-selection-single-project.jpg

 

Easier Remote Debugging

Ever been tired of having to manually configure ports, projects and source path lookups for debugging on Remote Applications in Eclipse ?

 

We are, especially after we learned that JVM's running on Hotspot provides API to discover such applications and allow for easy configuration of your debugger. In this release we've thus added a command available from Debug As... > Remote Java Application... in the context menu on any set of resources.

 

Once you select this command, we use the Hotspot API to discover the remote running applications, allows you to select which you application want to connect to and then we do the tedious work of configuring the ports, names and source code lookups (including maven dependencies if applicable) for your Remote debugging.

 

remote-debugging2.png

No need for manual tweaking anymore.

 

Thanks to Aslak Knutsen for bringing us the idea and initial code to make this happen!

 

Running Server Detection

The server adapters now attempt to detect if a server is already running to avoid port conflicts and UI inconcistencies. If a server is detected running you are shown a dialog allowing you to choose to either have the server adapter assume it is already running or force the launch anyway.

 

server-already-running.png

CDI & Seam Solder

The CDI tooling adds a bunch of quickfixes to have JBoss Tools fix common issues. To aid in searching and navigating your CDI application, Find References (Ctrl+Shift+G) will now show the full list of injection points and EL usage of your beans and Seam Solder and Config annotations and XML now have easy hyperlink navigation to it's declarations.

@ManagedBean's

The JSF tooling now detects @ManagedBean annotations. This avoids false warnings/errors when importing JSF 2 examples. Do consider using @Named instead for better integration into the JavaEE stack.

 

SAR Projects

For a long time we have been asked about providing support for SAR style projects for use on older versions of JBoss AS. This style of project packaging is now supported both in pure WTP style projects and via Maven.

 

GWT Tools are back

Since last time, Google released their GWT eclipse plugin in a version that supports Eclipse 3.7 allowing us to reenable the GWT Tools.

 

And more...

There are additional bugfixes and more features to browse over at What's New & Noteworthy

 

Like the new features ? Leave a comment to let us know!

 

And by all means,

Have fun!


To know more about Java EE 6, I highly recommend The Java EE 6 Tutorial: Basic Concepts (4th Edition) (Java Series) by Eric Jendrock, Ian Evans, Devika Gollapudi and Kim Haase


(Article reblogged from JBoss Tools blog)

Wednesday, August 3, 2011

How to Fix Ant Build Error: "Could not load a dependent class com/jcraft/jsch/Logger. It is not enough to have Ant's optional JARs"

If you get an error message like this while running a problematic Ant build script file :

remote.flush:

BUILD FAILED
/home/ceefour/git/magento-id/build.xml:13: The following error occurred while executing this line:
/home/ceefour/git/magento-id/build.xml:22: Problem: failed to create task or type sshexec
Cause: Could not load a dependent class com/jcraft/jsch/Logger
       It is not enough to have Ant's optional JARs
       you need the JAR files that the optional tasks depend upon.
       Ant's optional task dependencies are listed in the manual.
Action: Determine what extra JAR files are needed, and place them in one of:
        -/home/opt/eclipse_web/plugins/org.apache.ant_1.8.2.v20110505-1300/lib
        -/home/ceefour/.ant/lib
        -a directory added on the command line with the -lib argument

Do not panic, this is a common problem.
The commonest cause is a missing JAR.

This is not a bug; it is a configuration problem


It means your Ant build script file using optional Ant libraries and need to tell Ant where to find them.

In my case, it needs jsch.jar aka libjsch-java package in Debian/Ubuntu Linux.

First you need to install ant-optional package for Ant optional libraries support :
sudo apt-get install ant-optional

Then the libjsch-java Debian/Ubuntu package:
sudo apt-get install libjsch-java

Then put it in correct directories so that Ant can find them :

sudo ln -s /usr/share/java/jsch.jar /usr/share/ant/lib/
mkdir -vp ~/.ant/lib
ln -s /usr/share/java/jsch.jar ~/.ant/lib/

Ubuntu's Ant look for libraries in /usr/share/ant/lib folder, while Eclipse IDE's Ant look for optional Ant libraries in $HOME/.ant/lib folder.

Note that for Eclipse IDE, you may need to refresh Eclipse Ant Plug-in's Runtime Classpath, by going to Window > Preferences > Ant > Runtime, and clicking "Restore Defaults".
Make sure that the required libraries are now listed under "Global Entries".

Ant build system is frequently used in typical Java EE 6 enterprise application development. I highly recommend The Java EE 6 Tutorial: Basic Concepts (4th Edition) for a practical guide to the Java EE 6 technology.

Tuesday, July 12, 2011

JBoss AS 7.0 Final Version Released, Lighting Fast & Configurable Java EE 6 Web Application Server

There have been many highs in my career and many of those have happened since I joined JBoss and took over from Sacha. But today has to be in my top 1 or 2 ever! Today we can officially announce the release of JBossAS 7.0 Final! And it's EE6 Web Profile compliant too, so check out the project pages. It's taken us a while to get here and we've taken some pretty drastic and innovative steps along the way. Sometimes those decisions haven't been ease to make and we've thought long and hard about them. For instance, I recall Jason Greene, Scott Stark and I discussing for ages the various ramifications of continuing with the then current micro container architecture versus radical changes. The decision to change wasn't easy, but even then well over a year ago, we believed it was the right one to make. And now, with the new micro services container, it's proven itself! Some risks are worth taking.

But not every problem on our path has been technical or come from within Red Hat. Without going into details, let's just say that at times it seemed that processes and red tape were being thrown in our way. However, we got past these and the results speak for themselves: the fastest, most configurable and adaptable EE6 implementation (Web Profile) out there. And full EE6 is next on the roadmap, with JBossAS 7.1 due out soon. So if you haven't already tried it I encourage you to download it and give it a try.

I want to take this opportunity to thank everyone who has been involved in the development of JBossAS 7.0. This includes a diverse group of people including the projects, our QE teams, docs, support, product management, program management, marketing and many others. It would be impossible to single out those individuals who have stood out during the last 18 months since everyone has been a rockstar. However, I do want to mention Jason Greene again: any team is influenced both negatively or positively by it's leader and Jason has lead most positively by example throughout. And of course Bruno Georges, the engineering manager, who took over the role just over a year ago and mustered his troops so well! See what I mean? It's really hard to call out one person without immediately thinking of all of the others involved! A great team effort.

I also recommend Enterprise JavaBeans 3.1 by Andrew Lee Rubinger and Bill Burke for a thorough explanation on updated EJB 3.1 technology (including interceptors).  You can find more Java EE 6 Resources here.


(Article copied mostly verbatim from Mark Little's announcement)

Thursday, June 23, 2011

Hot Deploy & F5/Refresh-Driven Web Application Development Are Ancient Compared to Eclipse RAP!

Eclipse-rap-riena-hot-deploy-w

Most web applications developer would be very familiar with F5/Refresh-Driven development. You know, make a little change and press F5 in the web browser and you can view the updated page. This was the good old PHP days.

Java EE web application developers used to not that lucky. While some changes like JSP pages, JSF facelets, etc. take effect immediately (and thus, "refresh-driven"), in some cases they have to "redeploy". This usually means developer changes a Java class backing bean or an "important" file like web.xml. Redeploy means undeploying the web app from the Java EE container or application server, then redeploying the web app or WAR again. IDEs like the excellent Eclipse IDE Indigo (yay!) automate this but a redeploy can take anything between a few seconds to... minutes! I think typical web apps would deploy in about 20-30 seconds so that is painful.

JRebel from ZeroTurnaround (which just won the Most Innovative Java Technology in JAX Innovation Awards 2011, congratulations guys!) really helps here, by allowing most common changes to not cause a full redeploy, but just... hot deploy! It's like JSP/JSF but for the rest of Java app, Spring beans, etc. JRebel is a commercial plug-in but is definitely worth it.

But I'd argue Eclipse RAP should won the Most Innovative Java Technology title... Here's why!

(Eclipse Rich Ajax Platform/RAP is framework to develop AJAX-powered web applications easily based on Eclipse RCP programming model, see Eclipse Rich Client Platform (2nd Edition) for more information.)

I've just noticed something today. I know I should've noticed this long ago, but when you launch an Eclipse RAP rich internet application from Eclipse IDE using Debug (F11 key), ALL your code changes take effect immediately! No exceptions!

No need to even refresh the web browser!

Change the code for a menu item or a view or an action, save the .java file, go to the browser and click it... your new code is there!

"No refresh? But how can it be!"

Part of the magic is due to OSGi Dynamic Module System, that is brilliantly integrated as part of the Eclipse platform itself.

So when you save a Java file, Eclipse IDE will compile your class (and only your class, due to incremental builder feature, so it's very fast!), then update the OSGi bundle or Eclipse plug-in in the Eclipse RAP application. And only your bundle/plug-in is updated/refreshed in the application, so again, even if it's a different process it's also very fast. The whole process typically takes less than a second on a typical developer workstation, even on moderately complex apps! Most of the time the process is already done before you have a chance to hit Alt+Tab. ;-)

The other part of the magic is even though Eclipse RAP application comes with full AJAX features by default (it's not an option, it's actually a requirement), most of the business logic is server-side Java. So even if the most of the render JavaScript/HTML presentation layer in the web browser, when you perform an action for example by clicking a menu item, this will trigger a server request...

Which means your updated code! Yay! :)

Also important feature of Eclipse RAP is that for background/long-running jobs or "server push" operations, Eclipse RAP supports several approaches: Eclipse Jobs API or session-long UICallback.

This is pretty much automatic if you're already an Eclipse RCP programmer utilizing Jobs API. There's no need to do workarounds and hacks like traditional AJAX web development or learn yet another new API (and programming model) just for server push.

To learn more about Eclipse platform programming, I highly recommend Eclipse Rich Client Platform (2nd Edition). It's really good for learning Eclipse RCP/RAP development, most of the things that apply to RCP also applies to RAP. In fact, you can single-source an application to two target platforms (RCP for desktop, RAP for web) simultaneously. :-)

Eclipse Virgo IDE Tooling 1.0.0.M01 Released

Martin Lippert from SpringSource announced:

I am happy to announce that we released the first milestone build of the Virgo IDE tooling. For installation instructions, please take a look at the this wiki page:
http://wiki.eclipse.org/Virgo/Tooling

This is the first milestone build after the code contribution from SpringSource and there aren't that much changes with regards to features or bugs in there compared to the latest dm server tooling releases. But this will change from now on... :-)

Enjoy!

Eclipse Virgo Web Server / Kernel is an Enterprise OSGi web server, capable of serving dynamic OSGi web applications via OSGi Web Bundles (WABs). It works with Eclipse Gemini project to provide Java EE 6 capabilities to server-side OSGi applications.

For more in-depth explanation on using OSGi for enterprise applications, I highly recommend OSGi in Action: Creating Modular Applications in Java.

Tuesday, June 21, 2011

Groovy-Eclipse 2.5.0 Plugin Released

The SpringSource Tools Team is proud to release Groovy-Eclipse plugin 2.5.0.

In this release, we are most proud of our new DSL Descriptors (DSLDs) feature, which provides scriptable support for custom Domain Specific Languages in the Groovy Editor. Additionally, this release includes Groovy 1.8 as an optional add on, better content assist and type inferencing, and a Groovier outline view. 

See all details on the New and Noteworthy page, and please send your comments to the mailing list. Enjoy!

Copied verbatim from release announcement.

Thursday, June 9, 2011

Enterprise OSGi Applications in GlassFish - the definitive guide (well almost)

Enterprise-osgi-glassfish

Thanks to Sahoo, our OSGi applications expert and one of our most active participant on the mailing list, we now have an all-in-one Enterprise OSGi Applications in GlassFish guide document packed with useful content (a first edition of the OSGi & GlassFish definitive guide in a sense ;)

This document focuses on the OSGi Enterprise features of GlassFish, also known as hybrid applications. This includes WAB packaging, JPA bundles, EJB as OSGi bundle or service, type-safe and dynamic injection of OSGi Services using Java EE 6's CDI, exposing HTTP/JTA/JDBC/JMS as OSGi services, tooling and more.

You can find this document and more linked off of the main OSGi page on the GlassFish wiki.

To learn more about OSGi in the Enterprise, I highly recommend the recently published OSGi in Action: Creating Modular Applications in Java.

(Article copied almost verbatim from The Aquarium)

Saturday, April 16, 2011

Using Shiro for Authorization via CDI Interceptors then Easily Test with Arquillian

Did you know Apache Shiro is an easy-to-use security framework for authentication and authorization in Java applications?
Did you know CDI (Java Context and Dependency Injection) Interceptors (and Seam Weld) can make your programming life easier?
Did you know JBoss Arquillian makes testing @Inject-enhanced Java code in a CDI container very easy?
Making It Work Together
Okay, enough with the buzzwords. And sorry for the confusing article title, but really this is about an example of integrating 4 separate cool (and practical!) stuff:
  1. Shiro for security (authentication and authorization)
  2. Use of CDI interceptors so that you don't have to sprinkle your business logic code with orthogonal concerns
  3. Integration testing (actually it is unit testing inside an integration container) your application in Arquillian, demonstrating that it is just as easy as plain JUnit tests. "Look ma, no manual wiring!"(tm)
  4. How Maven project management build tool helps in doing the tasks above easier, no more searching for stuff and configuring classpaths
The Goal
The goal is making this very simple JavaBean class:

public class ContactManager {

String name = "Hendy Irawan";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

}

... "enterprise-ready".

How? By making sure it handles authentication and authorization of secured operations without changing a single character of the above code at all!

"You've got to be kidding me!" No, I'm not. The trick is that I will add the following exactly before that code:

@Secured @NamedResource("contact")

And the bean will get secured. The best part is you can do it with any bean you want, not just the above.

Introducing Shiro The Guardian

The awesome framework that will perform the job as our security guy is Apache Shiro.

Summon Shiro in the Maven project's pom.xml :

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.1.0</version>
</dependency>

Shiro is very configurable, but for this example I'll just use a basic INI style configuration with the following contents:

[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
hendy = hendy, user

[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
guest = view:*
user = view:*, edit:*

I think the above is pretty easy to understand. Create the Shiro SecurityManager that loads the above configuration with:

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
...
final String iniFile = "classpath:shiro.ini"; logger.info("Initializing Shiro INI SecurityManager using " + iniFile); securityManager = new IniSecurityManagerFactory(iniFile).getInstance(); SecurityUtils.setSecurityManager(securityManager);

It's now possible to check the permission by doing:

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
...
Subject subject = SecurityUtils.getSubject();
try {
  subject.checkPermission("edit:contact");
} catch (Exception e) {
  logger.error("Access denied - {}: {}", e.getClass().getName(), e.getMessage());
  throw e;
}

Wiring It All with CDI

I don't want to manually assign objects by doing setSomedependency(object) all over the place. I want to use CDI dependency injection:

@Inject Subject subject;

which is provided by:

@Produces
public Subject getSubject() {
return SecurityUtils.getSubject();
}

You may argue that it's just as concise as:

Subject subject = SecurityUtils.getSubject();

However that code is not flexible, because it is tied directly to Shiro API. The use of dependency injection makes it easier if you want to change the Subject implementation to another (for example, during testing, a mock object).

Grab the JARs

Add the JBoss repository (btw, it's recommended to add this as a profile in your ~/.m2/settings.xml instead of adding directly to the project POM):

<repositories>
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>

Here's the Maven dependencies:

<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.0-SP4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.interceptor</groupId>
<artifactId>jboss-interceptors-api_1.1_spec</artifactId>
<version>1.0.0.Final</version>
<scope>provided</scope>
</dependency>

By the way, if you use M2Eclipse plugin in Eclipse IDE, you don't have to worry about memorizing those because you can just right-click Project > Maven > Add Dependency and merrily search away the Maven repositories.

Using CDI Interceptors to Add Security Layer

Instead of putting the security code in the business logic (or in this case, entity) beans themselves, I'd like to use declarative security. First create an annotation that will serve as interceptor binding:

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.interceptor.InterceptorBinding;

@Inherited
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@InterceptorBinding
public @interface Secured { }

Use it to secure the bean that needs it:

@Named @Secured
public class ContactManager { ...

Now implement the interceptor itself:

import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Secured @Interceptor
public class SecurityInterceptor {

@Inject Subject subject;
@Inject SecurityManager securityManager;
Logger logger = LoggerFactory.getLogger(SecurityInterceptor.class);
@AroundInvoke
public Object interceptGet(InvocationContext ctx) throws Exception {
logger.info("Securing {} {}", new Object[] { ctx.getMethod(), ctx.getParameters() });
logger.debug("Principal is: {}", subject.getPrincipal());

final Class<? extends Object> runtimeClass = ctx.getTarget().getClass();
logger.debug("Runtime extended classes: {}", runtimeClass.getClasses());
logger.debug("Runtime implemented interfaces: {}", runtimeClass.getInterfaces());
logger.debug("Runtime annotations ({}): {}", runtimeClass.getAnnotations().length, runtimeClass.getAnnotations());
final Class<?> declaringClass = ctx.getMethod().getDeclaringClass();
logger.debug("Declaring class: {}", declaringClass);
logger.debug("Declaring extended classes: {}", declaringClass.getClasses());
logger.debug("Declaring annotations ({}): {}", declaringClass.getAnnotations().length, declaringClass.getAnnotations());
String entityName;
try {
NamedResource namedResource = runtimeClass.getAnnotation(NamedResource.class);
entityName = namedResource.value();
logger.debug("Got @NamedResource={}", entityName);
} catch (NullPointerException e) {
entityName = declaringClass.getSimpleName().toLowerCase(); // TODO: should be lowerFirst camelCase
logger.warn("@NamedResource not annotated, inferred from declaring classname: {}", entityName);
}
String action = "admin";
if (ctx.getMethod().getName().matches("get[A-Z].*"))
action = "view";
if (ctx.getMethod().getName().matches("set[A-Z].*"))
action = "edit";
String permission = String.format("%s:%s", action, entityName);
logger.info("Checking permission '{}' for user '{}'", permission, subject.getPrincipal());
try {
subject.checkPermission(permission);
} catch (Exception e) {
logger.error("Access denied - {}: {}", e.getClass().getName(), e.getMessage());
throw e;
}
return ctx.proceed();
}
}

At this point you may think: "OMG! so much code just to check authorization. Can't you shorten the code a little bit?"

And that is exactly why you don't want to litter your business code with security or other concerns. So you can write as complex or long code as you want in the interceptor and not worry about it when you write the business logic.

You may also find bugs in the implementation above or change the requirements (e.g. to use Spring Security instead of Apache Shiro). No sweat, just fix the interceptor (this is just one alternative, read below why), and all the beans that use it will have it right after save the interceptor .java source file (since Eclipse IDE will auto-build your project, right? ;-).

The last step is activating the interceptor itself in the META-INF/beans.xml file:

<?xml version="1.0" encoding="UTF-8"?>
xsi:schemaLocation="
<interceptors>
<class>id.co.bippo.security.SecurityInterceptor</class>
</interceptors>
</beans>

Interceptors will be ignored by CDI container unless it is listed in beans.xml. Now I said that to change the implementation of the interceptor is just one way you can change the behavior of an interceptor binding annotation. Another perfectly valid way is just to activate a different interceptor class that implements the same interceptor binding, for example:

<interceptors>
<class>id.co.bippo.security.SpringSecurityInterceptor</class>
</interceptors>

You may notice I defined another annotation that is @NamedResource :

@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface NamedResource {
String value();
}

My security implementation will check the permission using the value set by @NamedResource annotation, with the lowercase-name of the class used as fallback. The following:

@Named @Secured @NamedResource("contact")
public class ContactManager { ...

Tells the security interceptor to check the permission using "contact" as the resource name, not "contactmanager" inflected from the class name ContactManager.

From Great Power Comes Great Responsibility

Traditionally, running CDI unit tests using JUnit, outside a Java EE container means you either have to:
  1. Instantiate and configure a CDI implementation; or...
  2. Do it the old school POJO way --> someObject.setDependency(toAnother); all over the unit test
Unfortunately option #2 breaks down when you use other features than dependency injection, like interceptors.
And option #1 is just boring for your highly valuable time.

Arquillian Tames The Game

Of course, the movie won't be exciting unless you have a cool protagonist as your buddy: JBoss Arquillian. Let it handle the boring responsibility of dealing with the container and JUnit/TestNG integration, while you keep the power of easy unit testing and full CDI (and more!) features.

Summon the mighty Arquillian inside your pom.xml :

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<arquillian.version>1.0.0.Alpha5</arquillian.version>
<junit.version>4.8.2</junit.version>
</properties>

<dependencies>
<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-junit</artifactId>
<version>${arquillian.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<profiles>
<profile>
    <id>weld-se-embedded-11</id>
    <dependencies>
        <dependency>
            <groupId>org.jboss.arquillian.container</groupId>
            <artifactId>arquillian-weld-se-embedded-1.1</artifactId>
            <version>${arquillian.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.weld</groupId>
            <artifactId>weld-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jboss.weld</groupId>
            <artifactId>weld-api</artifactId>
        </dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>el-impl</artifactId>
<version>2.2</version>
<scope>runtime</scope>
</dependency>
        <dependency> 
            <groupId>ch.qos.logback</groupId> 
            <artifactId>logback-classic</artifactId> 
            <version>0.9.28</version>
            <scope>runtime</scope> 
        </dependency> 
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.weld</groupId>
                <artifactId>weld-core-bom</artifactId>
                <version>1.1.0.Final</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-ext</artifactId>
<version>1.6.1</version>
</dependency>
        </dependencies>
    </dependencyManagement>
</profile>
</profiles>

The above POM snippet will:
  • depend on JUnit 4.8.2
  • depend on Arquillian 1.0.0.Alpha5 (don't be deceived by the "alpha" qualifier. it's excellently usable already!)
  • declare a weld-se-embedded-11 Maven profile that runs tests under Weld SE Embedded 1.1.0.Final CDI container. Note that Arquillian supports a whole host of other container configurations including GlassFish, JBoss, OpenWebBeans, etc.
I also made sure to use SLF4J 1.6.1 and the powerful Logback, but this is optional and you can replace it with slf4j-simple or log4j if you want.

Coding The Test

Fortunately, with a minor change, the test code is just plain JUnit 4 test case conventions you all know and love. (OK, some of you may love TestNG better, thankfully Arquillian also supports it)

import javax.inject.Inject;

import junit.framework.Assert;

import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.subject.Subject;
import org.jboss.arquillian.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;

@RunWith(Arquillian.class)
public class ContactManagerTest {

@Inject ContactManager cm;
@Inject Subject subject;
/**
 * Since Arquillian actually creates JAR files under the covers, the @Deployment
 * is your way of controlling what is included in that Archive. Note, each
 * class utilized in your test case - whether directly or indirectly - must
 * be added to the deployment archive.
 */
@Deployment
public static JavaArchive createTestArchive()
{
return ShrinkWrap.create(JavaArchive.class, "test.jar")
.addPackage("id.co.bippo.security")
//.addClasses(new Class[] {ContactManager.class, SecurityInterceptor.class, SecurityFacade.class})
.addAsManifestResource("META-INF/beans.xml");
}

@Test
public void guestCanView() {
subject.login(new UsernamePasswordToken("guest", "guest"));
Assert.assertEquals("Hendy Irawan", cm.getName());
}
@Test(expected=AuthorizationException.class)
public void guestCannotEdit() {
subject.login(new UsernamePasswordToken("guest", "guest"));
cm.setName("Pak Boss");
Assert.assertEquals("Pak Boss", cm.getName());
}
@Test
public void userCanEdit() {
subject.login(new UsernamePasswordToken("hendy", "hendy"));
cm.setName("Pak Boss");
Assert.assertEquals("Pak Boss", cm.getName());
}
}

There are only two things that make this JUnit test different than vanilla JUnit tests:
  1. Annotate the test class with @RunWith(Arquillian.class)
  2. Implement the public static @Deployment method. Declare all the classes (or packages) and files/resources that you need in the to test what you will deploy. It may take some time to get used to but after that you'll realize that it's so powerful. For example you can test how the beans behave with different beans.xml configuration! (putting the "C"ontext back in CDI!)

Launch The Test Away

Testing the project with Arqullian is as simple as:

mvn test -Pweld-se-embedded-11

Notice the profile argument. It means it's very easy to test your application in different containers at will just by changing the profile! Neatness to the Extreme! I'd say it's the definition of neatness.

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running id.co.bippo.security.ContactManagerTest
16 Apr 11 16:03:14 org.jboss.arquillian.impl.client.container.ContainerRegistryCreator getActivatedConfiguration
INFO: Could not read active container configuration: null
16:03:14 [main] INFO  org.jboss.weld.Version - WELD-000900 1.1.0 (Final)
16:03:14 [main] INFO  org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
16:03:15 [main] WARN  o.j.i.util.InterceptionTypeRegistry - Class 'javax.ejb.PostActivate' not found, interception based on it is not enabled
16:03:15 [main] WARN  o.j.i.util.InterceptionTypeRegistry - Class 'javax.ejb.PrePassivate' not found, interception based on it is not enabled
16:03:15 [main] INFO  id.co.bippo.security.SecurityFacade - Initializing Shiro INI SecurityManager using classpath:shiro.ini
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Securing public java.lang.String id.co.bippo.security.ContactManager.getName() []
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Principal is: null
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime implemented interfaces: interface java.io.Serializable
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime annotations (2): [@id.co.bippo.security.Secured(), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring class: class id.co.bippo.security.ContactManager
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring annotations (3): [@id.co.bippo.security.Secured(), @javax.inject.Named(value=), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Got @NamedResource=contact
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Checking permission 'view:contact' for user 'null'
16:03:15 [main] ERROR i.c.b.security.SecurityInterceptor - Access denied - org.apache.shiro.authz.UnauthenticatedException: This subject is anonymous - it does not have any identifying principals and authorization operations require an identity to check against.  A Subject instance will acquire these identifying principals automatically after a successful login is performed be executing org.apache.shiro.subject.Subject.login(AuthenticationToken) or when 'Remember Me' functionality is enabled by the SecurityManager.  This exception can also occur when a previously logged-in Subject has logged out which makes it anonymous again.  Because an identity is currently not known due to any of these conditions, authorization is denied.
16:03:15 [main] INFO  o.a.s.s.m.AbstractValidatingSessionManager - Enabling session validation scheduler...
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Securing public java.lang.String id.co.bippo.security.ContactManager.getName() []
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Principal is: guest
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime implemented interfaces: interface java.io.Serializable
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime annotations (2): [@id.co.bippo.security.Secured(), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring class: class id.co.bippo.security.ContactManager
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring annotations (3): [@id.co.bippo.security.Secured(), @javax.inject.Named(value=), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Got @NamedResource=contact
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Checking permission 'view:contact' for user 'guest'
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Securing public void id.co.bippo.security.ContactManager.setName(java.lang.String) [Pak Boss]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Principal is: guest
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime implemented interfaces: interface java.io.Serializable
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime annotations (2): [@id.co.bippo.security.Secured(), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring class: class id.co.bippo.security.ContactManager
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring annotations (3): [@id.co.bippo.security.Secured(), @javax.inject.Named(value=), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Got @NamedResource=contact
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Checking permission 'edit:contact' for user 'guest'
16:03:15 [main] ERROR i.c.b.security.SecurityInterceptor - Access denied - org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [edit:contact]
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Securing public java.lang.String id.co.bippo.security.ContactManager.getName() []
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Principal is: hendy
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime implemented interfaces: interface java.io.Serializable
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime annotations (2): [@id.co.bippo.security.Secured(), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring class: class id.co.bippo.security.ContactManager
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring annotations (3): [@id.co.bippo.security.Secured(), @javax.inject.Named(value=), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Got @NamedResource=contact
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Checking permission 'view:contact' for user 'hendy'
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Securing public void id.co.bippo.security.ContactManager.setName(java.lang.String) [Pak Boss]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Principal is: hendy
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime implemented interfaces: interface java.io.Serializable
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime annotations (2): [@id.co.bippo.security.Secured(), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring class: class id.co.bippo.security.ContactManager
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring annotations (3): [@id.co.bippo.security.Secured(), @javax.inject.Named(value=), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Got @NamedResource=contact
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Checking permission 'edit:contact' for user 'hendy'
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Securing public java.lang.String id.co.bippo.security.ContactManager.getName() []
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Principal is: hendy
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime implemented interfaces: interface java.io.Serializable
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Runtime annotations (2): [@id.co.bippo.security.Secured(), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring class: class id.co.bippo.security.ContactManager
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring extended classes: {}
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Declaring annotations (3): [@id.co.bippo.security.Secured(), @javax.inject.Named(value=), @id.co.bippo.security.NamedResource(value=contact)]
16:03:15 [main] DEBUG i.c.b.security.SecurityInterceptor - Got @NamedResource=contact
16:03:15 [main] INFO  i.c.b.security.SecurityInterceptor - Checking permission 'view:contact' for user 'hendy'
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.621 sec

Results :

Tests run: 5, Failures: 0, Errors: 0, Skipped: 0

The Example Project

Now I'd argue that wasn't hard... compared to all the manual work that Java developers had to go through if doing it conventionally.

To make it even easier for everybody to see it in action with their own eyes, this complete example code is freely available, runnable (and forkable!) as arquillian-shiro-example project on GitHub.

Simply:

cd arquillian-shiro-example
mvn test -Pweld-se-embedded-11

And watch the magic unfold.

Conclusion

Java EE 6 and its supporting technologies (like CDI) and tools (like Arquillian and Maven, note they are not specific to Java EE at all) continue to help developers become more productive by reducing unnecessary technical tasks. 


I also recommend Enterprise JavaBeans 3.1 by Andrew Lee Rubinger and Bill Burke for a thorough explanation on updated EJB 3.1 technology (including interceptors).  You can find more Java EE 6 Resources here.

Do you think CDI / Arquillian / Shiro / Maven or this article helpful to you? Let me know what you have in mind. :-)
 
Copyright 2009 Spring vs Java EE Web Dev. Powered by Blogger Blogger Templates create by Deluxe Templates. WP by Masterplan