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.


To know more about Java EE, I highly recommend Java EE 7 Essentials: Enterprise Developer Handbook by Arun Gupta.


(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!

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 (vogella series) by Lars Vogel. 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)

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 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 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. 


To know more about Java EE, I highly recommend Java EE 7 Essentials: Enterprise Developer Handbook by Arun Gupta.


Do you think CDI / Arquillian / Shiro / Maven or this article helpful to you? Let me know what you have in mind. :-)

Wednesday, April 13, 2011

Fixing EJB 3.1 + CDI + JSF 2.0 problem: javax.el.ELException: ...xhtml: The class ...WeldProxy does not have the property ...

Yesterday I got hit by a very frustrating problem in developing a Java EE 6 web application under Oracle GlassFish 3.1 Application Server, using EJB 3.1, CDI, and JSF 2.0 EL expression.

The error message:

SEVERE: Error Rendering View[/pages/refills.xhtml]
javax.el.ELException: /pages/refills.xhtml: The class 'com.abispulsa.bisnis.service.org$jboss$weld$bean-com$abispulsa$bisnis$jsf-SessionBean-RefillManager_$$_WeldProxy' does not have the property 'summary'.
at com.sun.faces.facelets.compiler.TextInstruction.write(TextInstruction.java:88)

It happens with this very simple JSF 2.0 Facelets tag:

<p>Records: #{refillManager.summary}</p>

Where refillManager is a EJB 3.1 bean:

import javax.ejb.Stateless;
import javax.inject.Named;

import com.abispulsa.refill.PendingHandler;

@Named("refillManager")
@Stateless
public class RefillManager implements PendingHandler {

Google Searches exposed many different issues, but nothing useful for my problem.

What I know is that it's caused by @Stateless, when I remove it and simply use CDI with @ApplicationScoped, it works perfectly. Of course at that point I lose declarative JPA transactions.
(note: You can use declarative transactions without EJB using Seam Persistence CDI extensions).

To add to the frustration, I can't seem to reproduce the problem with another EJB + CDI bean. The others work fine!

I found the solution while reading the excellent Java EE 6 Book Enterprise JavaBeans 3.1 from O'Reilly. It is @javax.ejb.LocalBean !

Cause of the problem is @Stateless/@Stateful session bean that implements an interface, but not marked it as @javax.ejb.LocalBean.

@LocalBeans designates that a session bean exposes a no-interface view.

If a bean implements interface(s), it seems EJB only exposes those interfaces, meaning JSF 2.0 EL will not be able to access getter/setters that are not part of the declared interfaces (although they're accessible using the concrete class).

This may also happen to objects from "rich" languages like Groovy or Scala.

Solution:

Annotate the class with @javax.ejb.LocalBean.

Example:

import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.inject.Named;

import com.abispulsa.refill.PendingHandler;

@Named("refillManager")
@Stateless
@LocalBean
public class RefillManager implements PendingHandler {

Alternatives:
  1. Use EJB + JSF ManagedBean in XML, not CDI.
  2. Use CDI + Seam Persistence / Solder, not EJB. (I guess prefer this one)
Also, when all else fails: Undeploy, restart GlassFish, redeploy.

If you want to develop enterprise web applications using the latest Java EE 6 and EJB 3.1 technology be sure to get Enterprise JavaBeans 3.1 book from O'Reilly.