Red Hat

In Relation To Seam

In Relation To Seam

Seam 1.1.1 released

Posted by    |       |    Tagged as Seam

Seam 1.1.1 is now available for download.

https://sourceforge.net/project/showfiles.php?group_id=22866&package_id=163777&release_id=479605

This release fixes several minor bugs, introduces a number of improvements to seam-gen, and adds the following new features:

  • Facelets PDF templates (a JSF tag library for iText)
  • definition of navigation rules via pages.xml
  • Seam Text, a built-in text formatting language for use in blogs, forums and wikis
  • transaction success events
  • several improvements to pages.xml

The most exciting feature is the PDF generation (developed by Norman Richards). It's now super easy to generate PDF from Seam, by writing a simple facelets template. Check out the samples in the examples/pdf directory.

For people building collaboration-oriented websites, Seam Text is a wikitext parser built using an ANTLR grammar. It's totally trivial to display wikitext in your Seam application using <s:formattedText/>. The language itself is nice and flexible - much, much better than the awful wikitext language used by the software that runs this blog. I guess its well past time for blog.hibernate.org to be running on Seam.

Seam book excerpt on InfoQ

Posted by    |       |    Tagged as Seam

Michael and Thomas are writing a book about Seam for O'Reilly , which is apparently the hottest selling item on Rough Cuts. InfoQ are running an excerpt from the first chapter.

Meanwhile, Norman and I have been tearing our way through JIRA issues, and so 1.1.1 will be ready to go when I get back from vacation :-)

Seam Roadmap

Posted by    |       |    Tagged as Seam

The 1.1 release involved a lot of hard work in the guts of Seam, refactoring and fixing bugs, and working with tricky code that handles concerns like clustering and concurrency. Sure, there are many new features, but a lot of the real work is less user-visible. Now that this hard stuff is out of the way, it lets us add some interesting new stuff pretty quickly. Here's a quick roadmap for the next few months:

Spring integration package

We're seeing regular requests from people who have existing DAOs and business logic written using the Spring Framework and want a migration path to Seam that lets them re-use this existing code unchanged. The planned Spring integration package will provide:

  • injection of Spring beans into Seam components, using @In
  • access to the Spring beans in the EL
  • injection of Seam components into Spring beans using Spring XML
  • integration of the Spring DAO framework with Seam-managed persistence contexts

So, you'll be able to easily call existing code written in Spring from your Seam component, JSF views, or jBPM process definitions, and have that code be able to take advantage of Seam's conversation-scope persistence contexts. For the first time, you can have Spring code that isn't vulnerable to LazyInitializationException!

We'll probably even go as far as:

  • The ability to treat a Spring bean as a Seam STATELESS JAVA_BEAN component, with a full stack of Seam interceptors

In which case a class can simultaneously be a Seam component and a Spring bean, the same way a class can simultaneously be a JSF managed beans, an EJB3 session bean, and a Seam component today.

Seam/Security

The most-requested feature in the Seam forums is security. Unfortunately, the security-related specifications did not go through the same process of self-examination and improvement in Java EE 5 that some other specifications (EJB) did, and so there is now a yawning hole, exactly where the platform should strongest. (Today the most inadequate specifications in Java are the portlet spec, the atrocious servlet spec, and any JSR relating to security.) Seam 1.1.5 will introduce Seam/Security, an extension to Seam that provides:

  • a usable authentication layer
  • an ACL based permissioning model
  • an optional (customizable) user/role model
  • a totally cool (at least we think so) authorization mechanism based upon EL and Drools

The permissioning model lets you do row level security by writing rules that refer to the actual object instance that we are checking permissions for.

A subsequent release will also provide a console for administration of permissions, users/roles and rules. OK, I'm sure that sounds pretty vague now, but stay tuned.

Seam and iText

Generating PDF is amazingly unsexy, but also incredibly useful. Seam 1.1.5 will provide a library of JSF controls for iText , letting you quickly create JSF templates that are capable of rendering PDF, Text and RTF. This will be as easy to use as:

<f:view [=>xmlns:f=]"=>http://java.sun.com/jsf/core"
        [=>xmlns:it=]"=>http://jboss.com/products/seam/itext">
    <[=>it:paragraph]>Hello World!</=>it:paragraph>
</f:view>

Integration of seam-gen with Hibernate Tools

Rails has made commandline tools popular for web development, and was the inspiration behind seam-gen. But I'm one of those recalcitrant IDE kinda guys, and I expect tooling to be properly integrated with Eclipse. We'll be updating the GUI for Hibernate Tools to take advantage of the new templates in Seam 1.1, which will let you do everything you can do today using seam-gen, totally within Eclipse.

Seam/WS

We've been promising for months that Seam is the killer component model for SOA. Unfortunately, we got so bogged down in Seam 1.1 that we're well behind on our original plan to deliver this in 2006.

Seam 1.2 will integrate Seam with the Java EE 5 Web Services layer and provide support for service conversations in its context model (I've not yet decided whether this calls for a new SERVICE_CONVERSATION context, or whether it is just a different interpretation of the existing CONVERSATION context for a WS invocation. Eventually, Seam/WS will also support service orchestration and conversation recovery via jBPM.

Actually, Seam/WS will just be one piece of a larger initiative to bring Seam to ESB and SOA environments, but at present this idea is mostly speculative.

Look for a beta release of Seam 1.2 in Q1.

Seam 1.1 thankyous

Posted by    |       |    Tagged as Seam

In the announcement I neglected to give credit to all the people who worked on Seam 1.1 , so I'll take care of that now. Many thanks to:

  • James Williams for seam-gen
  • Norman Richards for the namespace support in components.xml, and <s:selectDate/>
  • Michael Yuan for testing Seam on WebLogic and GlassFish and getting the examples running on those platforms (this kind of work is always a frustrating and thankless task)
  • The Ajax4JSF team and Todd Smart for getting Ajax4JSF working with Seam
  • Ted Goddard and the ICEfaces team for getting ICEfaces working with Seam
  • Max Andersen for the improvements to Hibernate Tools needed by seam-gen
  • Stan Silvert for the EL enhancements

And thanks to the Seam community for your trust and patience!

Seam 1.1 finally reaches GA

Posted by    |       |    Tagged as Seam

This morning I uploaded a GA release of Seam 1.1. For those who've been following the development of Seam 1.1, there is not much new in this compared to the two CR releases. The only significant improvements compared to CR2 are that we now have the Hibernate and JPA example applications running out of the box on WebLogic (as well as JBoss, GlassFish and Tomcat), a number of enhancements to seam-gen, and a nice built-in datepicker control.

Download it here .

But for those who've been sleeping on Seam, here's a quick rundown on what's new in 1.1. (If you've never heard of Seam, and are wondering why you care, go here first.)

AJAX

Seam has featured (DWR-like) AJAX component remoting for a while now and this functionality is popular and useful. But realistically most Java developers would prefer to be able to get functionality like partial page refresh, interactive server-side validation, server-side suggest, etc, without needing to futz with JavaScript at all. This is where ICEfaces and Ajax4JSF come in. These are the leading AJAX component libraries for JSF, and they are the easiest way to build a rich client using simple, declarative JSF templates. We've been working with the ICEfaces and Ajax4JSF teams to make sure that both libraries work with Seam.

More importantly, we've created a brand new concurrency management architecture for Seam. AJAX fundamentally changes the interaction model of the web. If you try to take a traditional stateless architecture, designed for use with few, synchronous, coarse-grained requests, and re-use it in an AJAX environment where many, asynchronous (and therefore concurrent), fine-grained requests are the order of the day, you're virtually guaranteed to kill your database! AJAX makes server-side (conversational) state management a requirement, not a nicety. Amazingly, Seam is the only architecture in existence today which offers a strong model for conversation state. But the possibility of concurrent access to server-side conversation state opens up a whole raft of threadsafety issues which are not addressed by the servlet specification. Seam 1.1 solves these problems in a robust way.

http://docs.jboss.com/seam/1.1GA/reference/en/html/concepts.html#d0e2420

Data-oriented applications

It's very important to make clear that Seam is not, primarily, a Rails/Grails/Trails style framework for simplifying the development of basic data-oriented applications. Seam certainly does very much simplify the programming model of typical J2EE or Spring+Hibernate application architectures, but you won't really fully appreciate Seam until you start to come to terms with the stateful component model, conversations, conversation-scoped persistence contexts, pageflow and business process management. However, there is no reason on earth why the existence of this sophisticated functionality can't live comfortably beside facilities for simplifying basic data access. So Seam 1.1 introduces an Application Framework and a command line tool. These are surprisingly simple since they are layered over Seam's existing programming model, and are able to leverage all the power and simplicity of Seam.

The Seam Application Framework will eventually grow a lot bigger than it is now, and might eventually end up being packaged seperately from the Seam core. For now it provides Query and Home objects for both JPA and Hibernate3. These are classes that you can re-use either by extension or configuration. If you like, you can think of them as filling a similar role to DAO in a more traditional Java web application architecture. The biggest difference is that in Seam it is perfectly reasonable to bind Query and Home objects directly to the view (with loose coupling courtesy of the EL) whereas more traditional architectures force you to access the DAO via some kind of Action class. Of course, you can still inject a Query or Home into any Seam component and call it programmatically if that is what you prefer. As always, Seam lets you layer your code, but does not force any particular layering upon you.

http://docs.jboss.com/seam/1.1GA/reference/en/html/framework.html

The commandline tool makes it super-easy to get started with Seam. A few keystrokes, and you'll have a full Eclipse project structure (NetBeans is also supported) that automagically re-deploys itself to a JBoss exploded directory when you edit code. A few more keystrokes, and we've got a page with a simple action. A few more, and we've reverse engineered a whole Seam application (based on the Application Framework) from the database. The reverse engineering tool is, of course, built on top of Hibernate Tools. We intend to integrate the functionality of the commandline tool into a future release of JBoss IDE.

http://docs.jboss.com/seam/1.1GA/reference/en/html/gettingstarted.html

This work also involved improving Seam's extensions to JSF that allow the easy creation of applications with bookmarkable pages.

http://docs.jboss.com/seam/1.1GA/reference/en/html/events.html#d0e3357

J2EE support

Previously, Seam could be deployed on a Java EE 5 environment like JBoss or GlassFish, or on standalone Tomcat with the help of JBoss Microcontainer or JBoss Embeddable EJB3. We have heard loud complaints from a number of potential users who want to use Seam but are stuck on J2EE application servers like WebLogic or WebSphere. Seam 1.1 is compatible with J2EE (you can use either JPA or Hibernate for persistence) and comes with some examples that deploy out of the box on WebLogic (we'll get up to WebSphere next release).

This change meant that we needed to beef up Seam's support for plain JavaBean components, since in a J2EE environment people won't be able to use stateful session beans. A lot of the less visible work in Seam 1.1 involved building an efficient clustering architecture of stateful JavaBean components.

http://docs.jboss.com/seam/1.1GA/reference/en/html/concepts.html#d0e2831

Persistence context management

Seam-managed persistence contexts are one of the coolest things in Seam. In fact, one of the main reasons we decided to create Seam in the first place was our frustration at the all the problems Hibernate users experienced with LazyInitializationExceptions when using Hibernate with stateless session beans or Spring. Seam persistence context management got two major enhancements in this release. First, there is a bunch of extremely complex code (totally invisible to the user) to allow extremely efficient clustering of extended persistence contexts - even more efficient than what the EJB container is allowed to do with container-managed persistence contexts. Second, we introduced support for atomic persistence contexts. An atomic persistence context lets you make changes to managed objects across many requests in the same conversation, but have those changes be made persistent only at the end of the conversation (or some other well-defined point), instead of at the end of each request. This is a feature that JBoss, Sun and Sybase tried unsuccessfully to standardize into the EJB3 specification. If you want to use this feature, you'll need to use Hibernate as the JPA provider.

http://docs.jboss.com/seam/1.1GA/reference/en/html/conversations.html#d0e4275

Asynchronicity

Seam 1.1 layers support for asynchronous method invocation over the EJB3 timer service. This is a lightweight way to achieve asynchronicity in cases where JMS is overkill (don't worry, Seam also makes sending and receiving JMS messages a breeze, but that is not new).

http://docs.jboss.com/seam/1.1GA/reference/en/html/jms.html#d0e5041

JSF tag library

Seam 1.1 introduces some additions to Seam's JSF tag library, the most notable being a control for page fragment caching (similar to OSCache, which does not work with JSF), a control for adding fancy decorations to fields when validation fails, and a nice datepicker.

http://docs.jboss.com/seam/1.1GA/reference/en/html/controls.html http://docs.jboss.com/seam/1.1GA/reference/en/html/validation.html

Sophisticated XML-based component configuration

We've enhanced Seam's XML configuration facility, allowing more flexible packaging of the XML, and the use of namespaced schemas along with other improvements.

http://docs.jboss.com/seam/1.1GA/reference/en/html/xml.html

Seam 1.1 CR2 released

Posted by    |       |    Tagged as Seam

Seam 1.1.0.CR2 fixes a number of minor bugs in the CR1 release, and adds some minor improvements. This release includes a version of the booking example application which deploys on GlassFish, the Java EE 5 reference implementation, along with the hibernate2 and jpa examples which run cross-platform on JBoss 4 (with or without EJB3), GlassFish and Tomcat out of the box, and which may be made to run on any J2EE 1.4 compliant application server. The ICEfaces example has been upgraded to ICEfaces 1.5.1.

Download:

https://sourceforge.net/project/showfiles.php?group_id=22866&package_id=163777&release_id=467898

Changelog:

http://jira.jboss.com/jira/secure/ReleaseNote.jspa?projectId=10071&styleName=Html&version=12311064

Enjoy!

Seam 1.1 on InfoQ

Posted by    |       |    Tagged as Seam

InfoQ interviewed me on the subject of Seam 1.1. Check it out:

http://www.infoq.com/news/2006/11/seam-11-Gavin-King-interview

Seam 1.1 CR1 released

Posted by    |       |    Tagged as Seam

With the release of CR1, we are proud to announce Seam 1.1 to the world. Seam 1.1 brings Ajax, lightweight asynchronicity and the Seam Application Framework to Seam, and brings Seam to the J2EE platform. No matter what application server you use, you can experience the difference made by Seam's unique state and concurrency management architecture. This release is also a huge step forward in maturity, with many bugfixes and minor enhancements.

New features include:

  • New concurrency model for AJAX-based applications
  • Integration with ICEfaces and Ajax4JSF
  • Support for J2EE environments
  • The Seam Application Framework for data-oriented applications
  • seam-gen, a command line tool for generating seam projects, actions, and reverse engineering existing databases
  • Efficient clustering of Seam-managed extended persistence contexts and JavaBean components
  • Support for atomic conversations
  • Asynchronous methods and events
  • Enhanced configuration via components.xml
  • Exception handling via annotations or exceptions.xml
  • Page fragment caching via <s:cache/>
  • Decoration of invalid input via <s:decorate/>
  • Page parameters for RESTful applications
  • Themes
  • Support for the Sun JSF 1.2 reference implementation
  • Many, many bugfixes and other enhancements

Many thanks to everyone who contributed to this release, which was a real team effort.

Download it here:

https://sourceforge.net/project/showfiles.php?group_id=22866&package_id=163777&release_id=465354

Functional testing with Seam, DBUnit, and TestNG

Posted by    |       |    Tagged as Seam

I was looking for a good way to integrate DBUnit with Seam, so that I can prepare a dataset for functional testing without too much hassle. This is what I came up with, a test superclass that integrates with Seam and adds DBUnit operations that run before and after every test method.

The org.jboss.seam.mock.SeamTest class is the base class you'd usually use for functional testing in a Seam application. It allows you to easily script an interaction (for a whole session or a single event) at the presentation layer level. I extended this class to add some DBUnit specific features:

/**
 * Uses a JNDI datasource and JTA for DBUnit operations.
 *
 * @author christian.bauer@jboss.com
 */
public abstract class SeamDBUnitTest extends SeamTest {

    private static Log log = LogFactory.getLog(SeamDBUnitTest.class);

    private Context ctx;

    private ReplacementDataSet dataSet;

    @Configuration(beforeTestClass = true)
    public void prepare() throws Exception {
        log.debug("Preparing DBUnit setup for test class");

        // Prepare JNDI context
        ctx = new InitialContext();

        // Load the base dataset file
        URL input = Thread.currentThread()
                        .getContextClassLoader().getResource(getDataSetLocation());
        if (input == null)
            throw new RuntimeException(
                "Dataset '" + getDataSetLocation() + "' not found in classpath"
            );
        dataSet = new ReplacementDataSet(
                        new FlatXmlDataSet(input.openStream())
                      );
        dataSet.addReplacementObject("[NULL]", null);
    }

    @Configuration(beforeTestMethod = true)
    public void beforeTestMethod() throws Exception {
        executeOperations(getBeforeTestMethodStack());
    }

    @Configuration(afterTestMethod = true)
    public void afterTestMethod() throws Exception {
        executeOperations(getAfterTestMethodStack());
    }

    private void executeOperations(DatabaseOperation[] operations) throws Exception {
        log.debug("Executing database operations in JTA transaction");

        UserTransaction tx = getUserTransaction();
        tx.begin();

        IDatabaseConnection con = new DatabaseConnection( getConnection() );

        // TODO: Remove this once DBUnit works with HSQL DB
        DatabaseConfig config = con.getConfig();
        config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new FixDBUnit());

        for (DatabaseOperation op : operations) {
            op.execute(con, dataSet);
        }
        tx.commit();
    }

    // Subclasses can/have to override the following methods

    /**
     * Return a JDBC <tt>Connection</tt> with disabled foreign key checking.
     */
    protected Connection getConnection() throws Exception {
        log.debug("Getting database connection through JNDI lookup of DataSource");

        // Lookup Datasource in JNDI
        DataSource ds = (DataSource)ctx.lookup(getDataSourceJNDIName());
        Connection con = ds.getConnection();

        // Disable foreign key constraint checking
        // This really depends on the DBMS product... here for HSQL DB
        con.prepareStatement("set referential_integrity FALSE")
            .execute();

        return con;
    }


    /**
     * Add <tt>DatabaseOperation</tt> that run before every test method.
     */
    protected DatabaseOperation[] getBeforeTestMethodStack() {
        return new DatabaseOperation[]{};
    }

    /**
     * Add <tt>DatabaseOperation</tt> that run after every test method.
     */
    protected DatabaseOperation[] getAfterTestMethodStack() {
        return new DatabaseOperation[]{};
    }

    /**
     * The relative location of the data set on the classpath.
     */
    protected abstract String getDataSetLocation();

    /**
     * The JNDI name of the datasource used by DBUnit.
     */
    protected abstract String getDataSourceJNDIName();

}

This is pretty simple stuff: For each test class in the test suite I load a configured DBUnit dataset from the classpath and replace all the NULL markers with real nulls (see DBUnit documentation). Before each test method, which in a Seam functional test has the scope of a session, I run a stack of DBUnit operations, and again after each test method for cleanup. So each session in my functional tests works with a defined dataset. A concrete test subclass has to provide some settings, such as the location of the DBUnit dataset file, and the name of the database connection that is used. A subclass can also override the getConnection() method if a custom routine is needed. (Also note the TODO for a DBUnit/HSQL issue, one day they might actually fix this.)

A DBUnit dataset might look like this:

<?xml version="1.0"?>

<dataset>
    <USERS      USER_ID             ="1"
                OBJ_VERSION         ="0"
                FIRSTNAME           ="Root"
                LASTNAME            ="Toor"
                USERNAME            ="root"
                PASSWORD            ="secret"
                EMAIL               ="root@toor.tld"
                RANK                ="0"
                IS_ADMIN            ="true"
                CREATED             ="2006-06-26 13:45:00"
                HOME_STREET         ="[NULL]"
                HOME_ZIPCODE        ="[NULL]"
                HOME_CITY           ="[NULL]"
                DEFAULT_BILLINGDETAILS_ID ="[NULL]"
            />
</dataset>

Finally, this a concrete functional test class:

public class LoginLogoutFunction extends SeamDBUnitTest {

    protected String getDataSetLocation() {
        return "org/hibernate/ce/modules/user/test/basedata.xml";
    }

    protected String getDataSourceJNDIName() {
        return "[=>java:/caveatemptorDatasource]";
    }

    protected DatabaseOperation[] getBeforeTestMethodStack() {
        return new DatabaseOperation[] {
            DatabaseOperation.CLEAN_INSERT
        };
    }

    @Test
    public void testLoginLogout() throws Exception {

        // Test logged out state
        new Script() {

            // Test a component that requires a logged in user
            @Override
            protected void invokeApplication() {
                assert !isSessionInvalid();
                ChangePassword changePw =
                        (ChangePassword) Component.getInstance("changePassword", true);
                String outcome = changePw.doChange();
                assert "login".equals(outcome);
            }

            // Test if there is no loggedIn flag in the Session context
            @Override
            protected void renderResponse() {
                assert !Manager.instance().isLongRunningConversation();
                assert Contexts.getSessionContext().get("loggedIn") == null;
            }

        }.run();
...

The first three methods implement and override the settings for DBUnit operations, you can create a stack of DBUnit operations that are executed before and after each test method (only one in this example, running before). The test method testLoginLogout() is a single session in which I run several scripts (one for each event) to exercise the login and logout functionality of my application. As you can see, the methods in my script are simulating JSF presentation layer events. To see the full class without the DBUnit additions, browse the Seam tutorials, this is from the Hotel Booking application.

So one test class works with one dataset, I don't think this is too restrictive if you consider TestNG's ability to work with named groups of tests and wildcard matching.

Seam hands-on lab from JBoss World

Posted by    |       |    Tagged as Seam

Norman Richards (super-smart/thoughtful guy doing product management stuff at JBoss) has posted a download of the Seam hands-on lab from JBoss World. This is a nice way to get started with Seam, and much more interesting than listening to me rant on about conversations and state management and unified component models for an hour and a half...

http://docs.jboss.org/seam/jbossworld-seam-lab.zip

(Warning: it's a bit enormous because it bundles the appserver!)

back to top