Donnerstag, 29. November 2012

Weblets 1.3 released

Just a short notice, that Weblets 1.3 is released on Maven Central. To include Weblets in your own programs use following Maven directive. If you want to include Weblets in your program simply now use following entries in your dependencies section.

<dependency>
    <groupId>com.github.weblets</groupId>
    <artifactId>weblets-api</artifactId>
    <version>1.3</version>
</dependency>

and for the implementation use following include 

<dependency>
    <groupId>com.github.weblets</groupId>
    <artifactId>weblets-impl</artifactId>
    <version>1.3</version>
</dependency>

For a summary of the new features see either the Weblets documentation or following blogpost.

 

Links

[1] Weblets homepage

[2] Weblets 1.2 and 1.3 features blogpost

[2] Weblets documentation

Dienstag, 27. November 2012

TomEE and Maven

Introduction

TomEE is a lightweight application server which provides a full JEE Web Profile. It provides following technologies within a simple war container:

  • CDI - Apache OpenWebBeans
  • EJB - Apache OpenEJB
  • JPA - Apache OpenJPA
  • JSF - Apache MyFaces
  • JSP - Apache Tomcat
  • JSTL - Apache Tomcat
  • JTA - Apache Geronimo Transaction
  • Servlet - Apache Tomcat
  • Javamail - Apache Geronimo JavaMail
  • Bean Validation - Apache BVal

This means you simply can drop your EJBs into a single war and be done with your applications. The same goes for CDI and Entity Beans, all reachable from a single war.

Now to provide an example of such a configuration I have written a 3 tier helloworld which does the basic things an enterprise application performs.

  • Display a UI
  • Calls a service layer
  • Calls the database
  • Peforms authentication 
  • Uses internationalization

And all from within a simple Maven start.

This blogentry is about this program and a step by step guide through it.

About the program and getting started

To get started with the program download the program from Github via http://www.github.com/werpu/tomeemaven

Once downloaded simply run the program via mvn install tomee:run and then point your browser to

http://localhost:8080/tomeemaven. The rest is very barebones and basic and self explanatory.

You will be brought to a landing page which loads some data over a service layer from the database. Next is a login page which does basic authentication and then brings you into a restricted area.

Now the program itself is as barebones as it gets, the more interesting part is the setup, which this blog will guide you through.

Maven Setup

The barebones maven setup is a simple war file:

<groupId>com.github.werpu</groupId>
<artifactId>tomeemaven</artifactId>
<packaging>war</packaging>

Now to the first interesting part, normally you have in a Maven and Tomcat configuration a huge list of dependencies, which your app uses. Our setup has reduced the dependency list to two entries.

<dependencies>
    <!-- contains the entire jee api we only use a subset of it-->
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>6.0</version>
        <!-- scope provided means the container delivers it -->
        <scope>provided</scope>
    </dependency>
    <!-- hsqldb references, we start hsqldb as server -->
    <dependency>
        <groupId>org.hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <version>2.2.8</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

As you can see both dependencies are <scope>provided</scope> which means that the app server provides those two.

The more interesting part is the jee-api include which basically just provides the JEE APIs for the code. We only use a subset of those, but for the simplicity of things a full JEE api include should be enough to get you started.

The second include is the hsql db which we use because we start hsql directly in server mode. (Note TomEE comes with hsql included, we do not have to do anything here regarding including it)

The next part is the TomEE Maven Plugin

<plugin>
    <groupId>org.apache.openejb.maven</groupId>
    <artifactId>tomee-maven-plugin</artifactId>
    <version>1.0.0</version>
    <configuration>
        <tomeeVersion>1.5.0</tomeeVersion>
        <tomeeClassifier>plus</tomeeClassifier>
        <debugPort>5005</debugPort>
    </configuration>
</plugin>

This basically is our TomEE starter, we de not have to do anything about its configuration. With this entry our mvn clean install tomee:run is possible and our war automatically picked up as application war.

The last part is the compile time instrumentation weaving for OpenJPA which enhances our entities at compile time.

<plugin>
    <groupId>org.apache.openjpa</groupId>
    <artifactId>openjpa-maven-plugin</artifactId>
    <version>2.2.0</version>
    <executions>
        <execution>
            <id>mappingtool</id>
            <phase>process-classes</phase>
            <goals>
                <goal>enhance</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <includes>
            com/github/werpu/tomeedemo/orm/*
        </includes>
    </configuration>
</plugin>

This is basically the entire maven setup.

File structure

The folder hierarchy follows a strict Maven setup with small enhancements for the TomEE Maven plugin.

It is as follows:

Folder Hierarchy

Following Folders are of interest

  • src/main/java The Java sources
  • src/main/resources the resources folger hosting the beans and persistence.xml, this folder later will be compiled into the web-inf/classes folder along with the java sources
  • src/main/webapp the web application folder
  • src/main/tomee hosting the TomEE configuration file overrides (we will come later to this important folder)

The main difference to a standard Maven layout is the src/main/tomee folder.

It currently hosts 2 files:

  • tomcat-users.xml
  • and tomee.xml

tomee.xml hosts a new database resource which connects to a locally running HSQL DB Server. Outside of that it is a blank copy of what is provided from the standard TomEE distribution.

tomcat-users.xml is the standard Tomcat UserDatabase Realm but provides one additional user, who is the login user for our secured part.

We will go later into more details regarding both files. The important part about this files is, that they replace the original files during the build process and bundle them into the running TomEE once you issue mvn install tomee:run on the command line.

That way you can override any of the standard settings of TomEE with your custom settings.

Override Config Files

 

3 Tiers

The UI layer

Here we use plain JSF as provided by TomEE (in our case Apache MyFaces 2.1.9 which as time of writing is almost the most recent distribution of Apache MyFaces)

The main difference is that we basically use CDI  instead of JSF managed beans. Here is an example page controller class implemented as CDI bean.

@Named
@RequestScoped
public class HelloView
{
    @EJB
    HelloEJB helloEjb;

    //---------------------------- getter and setter ---------------------------------
    public String getHelloWorld()
    {
        return helloEjb.getHello();
    }
}

The main difference here to a standard Tomcat setup is, that we can inject an EJB directly into our managed bean. This is thanks to TomEE.

The EJB can be straightly bundled into the WAR file, no need for EAR and complicated classloader hierarchies.

This brings us directly to our second layer.

 

The service/DAO layer

We have implemented the Service layer as stateless Session Bean, since we use JPA we will omit separate DAOs in favor of simplicity.

The Service does not do to much it basically just writes to the database in case no data is present otherwise it will read from the database.

@Stateless
public class HelloEJB
{
    @PersistenceContext(name = "Demo_Unit")
    EntityManager em;

    public String getHello()
    {
        Query query = em.createQuery("select hello from HelloEntity hello");
        if (query.getResultList().size() == 0)
        {
            HelloEntity entity = new HelloEntity();
            em.persist(entity);
            return entity.getHelloWorld();
        }
        HelloEntity entity = (HelloEntity) query.getResultList().get(0);
        return entity.getHelloWorld();
    }
}

This brings us straight to

 

The database layer

 

Centralized database connection

 The database layer is a little bit more complicated because it needs several configuration files.

First we have to deal with the a centralized managed database connection.

TomEE utilizes a resource entry in tomee.xml to enable the centralized database connection. (Which theoretically can be shared over multiple applications)

Here is our entry:

<Resource id="MyDataSource" type="DataSource">
        JdbcDriver org.hsqldb.jdbcDriver
        JdbcUrl    jdbc:hsqldb:hsql://localhost:9001/testdb2
        UserName   sa
        Password
        JtaManaged true
</Resource>

What is strikingly odd here is, that this is not the same syntax as used in a standard context.xml Tomcat configuration but instead TomEE follows its own syntax which is explained more thoroughly here  (I have not yet tested if a context.xml db connection also works, given that there is the web.xml method, I probably never will (see below)).

In our case we connect to a running HSQLDB server which is started with the application automatically (we will come later to that)

The important parts are following

  1. the Datasource id="MyDataSource"
  2. the Type being a DataSource: type="DataSource"
  3. and JtaManaged being true
The rest is standard JDBC.
The main advantage of this method is mostly the centralized connection which can be shared over multiple web applications, and also that it allows for more configuration options compared to the web.xml method. The downside however is, that it is centrally managed which means you have to alter your config entries in the tomee dir. In our case the project does that automatically during deployment of the web application.
 

Web application managed database connections

 
As one of the readers of this blog has pointed out, the method mentioned before is centralized but non standard (not JEE), which means for a real deployment you have to change the configuration of your tomee and to the worse if you go to a different app server you have to setup the connection again for that server, in some cases this is not wanted. Since we use Servlet 3.0 there is a standard way to define database connections on a per webapp base. We can achieve it simply by adding following code to our web.xml.
 
<data-source>
    <name>MyDataSource</name>
    <class-name>org.hsqldb.jdbcDriver</class-name>
    <url>jdbc:hsqldb:hsql://localhost:9001/testdb2</url>
    <user>sa</user>
    <password></password>
</data-source>
 
The advantage of this method is simplicity and you do not tamper with the config directory of Tomee, the downside is, that MyDataSource only can be used within the context of the web application and you will lose some advanced configuration options the centralized method can provide.
 

Persistence.xml

Now to the second part the persistence.xml. As already discussed we use OpenJPA for persistence, because it already is present in the container. Hibernate or EclipseLink also would be possible by adjusting the pom.xml and removing the OpenJPA implementation and adding the other jars. Following page has an example which exactly does that. 

For our persistence.xml we use following entries:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">


    <!-- simply all annotated persistent entities will be part of this unit-->
    <persistence-unit name="Demo_Unit">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <jta-data-source>MyDataSource</jta-data-source>
        <class>com.github.werpu.tomeedemo.orm.HelloEntity</class>

        <properties>
            <property name="openjpa.jdbc.DBDictionary" value="hsql"/>

            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>

            <!-- disable runtime instrumentation -->
            <property name="openjpa.DynamicEnhancementAgent" value="false"/>

            <property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>

            <!-- with those two settings openjpa behaves better for merge and detach -->
            <property name="openjpa.DetachState" value="loaded(DetachedStateField=true)"/>
            <property name="openjpa.Compatibility" value="IgnoreDetachedStateFieldForProxySerialization=true"/>

            <property name="openjpa.jdbc.MappingDefaults"
                      value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict"/>

        </properties>

    </persistence-unit>

</persistence>

 The important parts are following:

  •  <persistence-unit name="Demo_Unit"which provides us with the persistence unit name used by our EJB.
  • <jta-data-source>MyDataSource</jta-data-source> As datasource definition.
  • <class>com.github.werpu.tomeedemo.orm.HelloEntity</class> For our enity class

The rest are internal openjpa settings, like foreign key handling, that we use compile time instrumentation instead of runtime instrumentation (see also the maven config for that one), or a helper which preserves the states in serialized scenarii, to help to speed up subsequent merges. Neither of that is if importance for the blog.

Now last but not least our entity class which is used by our service:

 

@Entity
public class HelloEntity
{
    @Id
    @GeneratedValue
    Integer id;

    @Column(name = "HELLO_WORLD")
    String helloWorld = "helloWorld from entity";

    @Version
    protected Integer optlock;

    public Integer getId()
    {
        return id;
    }

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

    public String getHelloWorld()
    {
        return helloWorld;
    }

    public void setHelloWorld(String helloWorld)
    {
        this.helloWorld = helloWorld;
    }

    public Integer getOptlock()
    {
        return optlock;
    }

    public void setOptlock(Integer optlock)
    {
        this.optlock = optlock;
    }
}

 

Authentication

We use standard server hosted authentication for our application to limit user access to certain pages. Deeper knowledge on the mechanisms of this authentication method is outside of the scope of this blog, but you can find information here.

The application has a secured page which can be accessed from our landing page. For simplicty reasons we use the standard tomcat-users.xml file and the UserDatabase realm defined by tomcat as standard.

All we do is to add another user and a new permission to the realm:

 

<role name="authenticated-user" />
<!-- we use a new user in our standard realm for the authenticated pages -->
<user name="test" password="user" roles="authenticated-user" />

 The web.xml now has to have following entries to secure the page:

 

<!--
authentication , we use browser authentication
and the tomcat-users.xml file as authentication realm
-->
<security-constraint>
    <web-resource-collection>
        <web-resource-name>Authenticated Pages</web-resource-name>
        <url-pattern>/user/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>authenticated-user</role-name>
    </auth-constraint>
</security-constraint>

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>UserDatabase</realm-name>
    <form-login-config>
        <form-login-page>/login/login.jsf</form-login-page>
        <form-error-page>/login/error.jsf</form-error-page>
    </form-login-config>
</login-config>

What we do here is to secure all pages under /user/* only accessible for users with the role authenticated-user which was defined before.

<realm-name>UserDatabase</realm-name> 

was the standard realm which we defined our new user and new role

We also define a login and error page for a standard login. 

The login looks as follows:

<form method="POST" action="j_security_check">
        <input type="text" name="j_username"/>
        <br />
        <input type="password" name="j_password"/>
        <br />
        <input type="submit" value="Submit"></input>
        <input type="reset" value="Reset"></input>
</form>

 This is a standard login form for server based authentication, it has to follow a certain naming syntax, hence, the non JSF syntax.

The Database

We could make it simpler by running our database in embedded mode, which would look like following:

 

<Resource id="MyDataSource" type="DataSource">
    JdbcDriver org.hsqldb.jdbcDriver
    JdbcUrl jdbc:hsqldb:file:data/hsqldb/testdb
    UserName sa
    Password
    JtaManaged true
</Resource>

This however has the downside of not being able to connect to the database with third party tools, while the db is running. While simplicty is the primary objective of the demo project, which this blog is based upon we stray away from this path in case of the DB. Our primary aim is to have a db which runs in server mode. Normally this would be an Oracle, MySQL or PostgresSQL db. However in our case we simply want the db to start once we start our own server.

For this we use a small trick, we use a servlet to start the db. (theoretically a context listener also would suffice)

The servlet has to be started via loadonstartup = 1

@WebServlet(urlPatterns = "/db/*", loadOnStartup = 1)
public class HSQLDBStartupServlet extends HttpServlet
{
    Logger log = Logger.getLogger(HSQLDBStartupServlet.class.getName());
    
    @Override
    public void init() throws ServletException
    {
        super.init();
        try
        {
            log.info("Starting Database");
            HsqlProperties p = new HsqlProperties();
            p.setProperty("server.database.0", "file:data/hsqldb");
            p.setProperty("server.dbname.0", "testdb2");
            p.setProperty("server.port", "9001");
            Server server = new Server();
            server.setProperties(p);
            server.setLogWriter(null);
            server.setErrWriter(null);
            server.start();
        }
        catch (ServerAcl.AclFormatException afex)
        {
            throw new ServletException(afex);
        }
        catch (IOException ioex)
        {
            throw new ServletException(ioex);
        }
    }
}

 

And the entry in the tomee.xml looks like following:

<Resource id="MyDataSource" type="DataSource">
    JdbcDriver org.hsqldb.jdbcDriver
    JdbcUrl    jdbc:hsqldb:hsql://localhost:9001/testdb2
    UserName   sa
    Password
    JtaManaged true
</Resource>

 Almost the same as before however the JDBCURL parameter is different it now uses a TCP/IP connection instead of direct file access.

 

 

 

Summary

This sums up our little walkthrough through the demo application. Have in mind, that the application is a good kickstarter for your own projects, however in a real production environment some adjustments have to be made. For instance authentication needs to be set towards a database, passwords need to be replaced by their hash sums, authentication has to go through https, and also the db should not be generated out of the entities.

But all of this would sacrifice the simplicity of the demo project. Also feel free to comment or fork the project for your own purposes or improvements. Any participation is welcome as always in opensource projects.

 

Links 

  1. TomEE Maven project
  2. Apache TomEE project
  3. OpenJpa project
  4. Mark Strubergs blog (JPA and CDI information)
  5. Oracle server side authentication tutorial
  6. How to start HSQLDB in a webapp 

 

 

 

 

Montag, 26. November 2012

Weblets 1.2 and Weblets 1.3

Introduction

Weblets 1.2 recently has been released on MavenCentral, this article is about the new features of the release and an outlook regarding the upcoming Weblets 1.3 release.

Weblets 1.2

Namespace Changes

Weblets 1.2 is the first release hosted on Github after the failed transfer from java.net to Kenai and the first release under a new namespace on Maven Central.

If you want to include Weblets in your program simply now use following entries in your dependencies section.

<dependency>
    <groupId>com.github.weblets</groupId>
    <artifactId>weblets-api</artifactId>
    <version>1.2</version>
</dependency>

and for the implementation use following include 

<dependency>
    <groupId>com.github.weblets</groupId>
    <artifactId>weblets-impl</artifactId>
    <version>1.2</version>
</dependency>

 As you can see the namespace was changed from java.net to com.github.weblets

This change was necessary due to the move to Github, I am sorry about any inconveniences this has caused, but having to move to Github was caused by a problem with the java.net to Kenai transition on Oracles side.

 

New Features

The main new Feature of the 1.2 release is subbundles. Subbundles is a usefule feature if you have multiple text file includes which you want to switch to one single include on the fly.

So how does this work.

First of all you need to define a subbundle in your weblets-config.xml 

<subbundle>
    <id>newBundleId</id>
    <resources>
    /subbundle/script1.js, /subbundle/script2.js
    </resources>
</subbundle>

This defines a new subbundle /bundles/script.js from following resources script1.js and script2.js

Now what happens if one of the scripts is loaded is following, that script1 and script2 are concatenated and loaded within one request, the second request will get a resource already served answer.

You already get a small optimization that way without changing your code between subbundles and normal resource requests.

However by using a small utils function you can cut down on the additional requests if a bundle already is served.

Simply use following:

 <script type="text/javascript" defer="true"
                src="<%=jspweblet.getURL(request, "weblets.demo","/subbundle/script1.js",true)%>">
</script>

<% if (!jspweblet.isResourceLoaded(request, "weblets.demo", "/subbundle/script2.js")) { %>
        <!--
 double includes can be suppressed by the resource loaded
 method, we can add as many includes here as we want the code
 will not be executed for any resource in the bundle
 -->
        <script type="text/javascript" defer="true"
                src="<%=jspweblet.getURL(request, "weblets.demo","/subbundle/script2.js",true)%>">
        </script>
<%}%>

The utils function isResourceLoaded checks whether a resource already is loaded or not. You have this function enabled not only for jsp, but also for jspx and jsf. See the weblets documentation for further information on the utils functions / methods.

By using the utils function you can switch easily between the bundled and non bundled versions of the include.

(Note currently it is not possible to load a bundle from the given subbundle id, this limitation will be lifted in the future)

Weblets 1.3

The main feature of Weblets 1.3 will be finally the connection between JSF 2.x resources and Weblets. What this means is that Weblets will provide its own Resource Handler which allows JSF to access Weblets resource bundles. Along with this feature comes also a set of utility functions which will allow the easy handling of weblets resources on JSF 2.0 level.

Here are examples on what Weblets 1.3 will try to achieve.

<h:graphicImage id="yyy4" value="#{wbl:jsfURL('weblets.demo','/img/icon_alert.gif')}"/>

<h:graphicImage id="yyy5" value="./#{wbl:jsfResource('weblets.demo','/img/icon_alert.gif')}"/>

<h:graphicImage id="yyy2" value="./javax.faces.resource/img/icon_alert.gif.jsf?ln=weblets.demo"/>

This is a set of different methods to generate valid weblet-JSF requests, which means all of those resources will be served by the JSF resource system.

The generated requests look like following:

<img id="yyy4" src="/weblets-demo/javax.faces.resource/1.0/img/icon_alert.gif.jsf?ln=weblets.demo" />
<img id="yyy5" src="./javax.faces.resource/1.0/img/icon_alert.gif.jsf?ln=weblets.demo" />
<img id="yyy2" src="./javax.faces.resource/img/icon_alert.gif.jsf?ln=weblets.demo" />

As you can see the generated requests are all valid JSF2 resource requests.

Now how about Subbundles?

Subbundles also work with the JSF2 API, following example demonstrates how you can work with subbundles.

<h:outputScript id="loadingBundleScript" library="weblets.demo" name="subbundle/script1.js"  target="body"/>
<h:outputScript id="loadingBundleScript2" library="weblets.demo" name="subbundle/script2.js"
                    rendered="#{wbl:isResourceLoaded('weblets.demo','/subbundle/script2.js')}"  target="body"/>

This is the exactly same example as before utilizing the JSF2 infrastructure of Weblets 1.3.

Links

[1] Weblets Homepage

[2] Weblets Documentation

Dienstag, 20. November 2012

What happened to Weblets?

Hello again, if you head over to java.net you will notice that Weblets does not exist anymore. Given that I am the core maintainer of the project, all I can say is, that Oracle/Sun screwed up here. Weblets old releases are still present in the Maven repository.

However Weblets is alive and kicking, I am working on a 1.2 version with nifty new features while I am writing this. So where is Weblets now?

Weblets is alive and kicking on Github head over to http://www.github.com/werpu/weblets to reach the code and documentation.

I am also working currently on getting Weblets back into the maven central repository so that you can reach it easily again via Maven.

I will keep you updated about the situation. Sorry about the inconvenience.

Situation update: I just finished the release process for Weblets 1.2 it should show up soon under:

<dependency>
    <groupId>com.github.weblets</groupId>
    <artifactId>weblets-api</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>com.github.weblets</groupId>
    <artifactId>weblets-impl</artifactId>
    <version>1.2</version>
</dependency>

In the Maven central repository. Older versions are available under the weblets.java.net namespace including the sources. Please use http://search.maven.org to look them up.

Donnerstag, 8. November 2012

Marrying Scala with Apache MyFaces Part 4 - Apache MyFaces Extension Scripting

Introduction

In Parts 1 2 and 3 we have had a look at various implementation aspects on how to enable Scala and Apache MyFaces.
Part 4 introduces a framework which allows a zero restart configuration for Scala based JSF artifacts, such as components, managed beans, renderers etc...

This project is a relatively new extension to the Apache MyFaces project which already has had spawned several sideprojects such as CODI or Ext-Val.

The projects name is Ext-Scripting.

What is Ext-Scripting? This is an ongoing effort to integrate scripting languages into Apache MyFaces in a way that the user gets zero restart configurations for code writing.

Following video will give more details on what Ext-Scripting can provide:



Ext-Scripting itself is not only a Scala specific project but also supports as of now Groovy, dynamically recompiled Java  and soon JRuby.
One of the major aspects of Ext-Scripting was to provide extensive documentation which you can find here.

In this blog we will trim down all the information provided to give you the bare essentials in the shortest possible time.

Ext-Script in action

Ext-Script allows you now to edit direct JSF artifacts like managed beans and recompiles those artifacts on the fly. Very similar to JSP, however in JSP you were limited to stateless pages,  Ext-Scripting literally allows you to edit most JSF artifacts no matter if they are stateless or stateful.

It uses sophisticated dependency detection mechanisms on bytecode level, to reload exactly the artifacts it needs to keep the system in a stable state.

Following video (With a Java Example) will demonstrate of what happens exactly



So what does this mean for Scala. Once Ext-Scripting is enabled you can start to write managed beans, components, navigation handlers, phase listeners etc... directly in Scala and have Ext-Scripting do the heavy lifting for you.

Your server restart times will be reduced up to 90% by simply using the dynamic recompilation feature. You even can use the JSF annotations in a dynamic manner, by simply moving them deleting them etc...

Getting started -

Maven config

The easiest way to get started with Ext-Scripting is simply to take one of the example projects provided by the distribution and to start hacking or use maven. We will emphasis on the maven configuration in this blog. To add Ext-Scripting all you need is a working war configuration and then add following entries to your dependency section:

<dependency>
 <groupId>org.apache.myfaces.extensions.scripting</groupId>
 <artifactId>extscript-myfaces20-bundle</artifactId>
 <version>1.0.4</version>
</dependency>


And for the Scala support:

<dependency>
    <groupId>org.scala-lang</groupId>
    <artifactId>scala-library</artifactId>
    <version>2.9.1</version>
</dependency>
<dependency>
    <groupId>org.scala-lang</groupId>
    <artifactId>scala-compiler</artifactId>
    <version>2.9.1</version>
</dependency>


This should add all the needed dependencies automatically to your project.

web.xml

General Setup To have Apache MyFaces picking up Ext-Scripting we have to add following context parameter to the web.xml:

<context-param>
     <description>
         Enables our scripting engine support plugins
     </description>
     <param-name>org.apache.myfaces.FACES_INIT_PLUGINS</param-name>
     <param-value>
         org.apache.myfaces.extensions.scripting.servlet.StartupServletContextPluginChainLoader
     </param-value>
</context-param>

Setting up your source directories

Now theoretically you can start to code. Ext-Script will pick up sources hosted under WEB-INF/scala in your deployment directory. However under normal circumstances this is undesired because you want to have Ext-Scripting to pick up the sources from your real source directories for editing.

So we now have a number of context parameters in the web.xml which will allow Ext-Scripting to pick up your various sources from the source destinations itself.

For Scala following config parameters is relevant:

<context-param>
     <description>Additional comma separated loader paths to allow direct editing on the sources directory instead of the deployment dir
     </description>
     <param-name>org.apache.myfaces.extensions.scripting.scala.LOADER_PATHS</param-name>
     <param-value>
   <some project path>/src/main/webapp/WEB-INF/scala
     </param-value>
</context-param>


Now this is all to have Ext-Script to pick up your sources from the Scala path and you can start. Happy Coding.

[1] Link to Apache MyFaces Ext-Scripting
[2] Marrying JSF and Scala Part 1
[3] Marrying JSF and Scala Part 2
[4] Marrying JSF and Scala Part 3

Ext-Script and TomEE

Introduction:

I just wanted to inform everyone that Apache MyFaces Extension-Scripting works out of the box with Apache TomEE.

 

 What is Apache MyFaces Ext-Scripting?


For all people who don't know what Ext-Script is (probably most of you). Apache MyFaces Extension Scripting short Ext-Script is an Apache MyFaces extension which provides scripting language support and dynamic recompilation for Apache MyFaces. This means you can code the JSF parts of your project in Groovy, Scala, Java and soon in JRuby and you get jsp like dynamic recompilation of those parts for free.

It does not work with all app servers due to server limitations (mostly in the classloader section)  but so far it has been tested with

  • Tomcat
  • Jetty
  • Websphere Liberty Profile
  • Glassfish and
  • TomEE

More information about Apache MyFaces Ext-Scripting here.

This blogpost is about TomEE and how to get it up and running with this excellent lightweight server.

 

What is TomEE:


TomEE is a project, which provides a full JEE Web Profile to a Tomcat, it does not touch Tomcat but provides the entire JEE web profile stack (and more) within a standard Tomcat war container.  Thats right no EAR anymore just drop a war and you will get JSF CDI etc... out of the box from the container.
More information on Apache TomEE here. No more bundling of JSF CDI etc... all is provided by a lightweight servlet container with great startup times.

 

Combination of both


So how do we combine both containers? The answer is simple, drop
Ext-Scripting:

  • extscript-myfaces20-bundle-1.0.4.jar

and its dependencies :

  • commons-beanutils.jar version 1.8.3 or above
  • commons-codec.jar version 1.3 or above
  • commons-collections.jar version 3.2 or above
  • commons-io.jar version 1.4 or above
  • groovy-all.jar version 1.7.2 or above
  • scala-compiler.jar version 2.10.0-M2 or above
  • scala-library.jar version 2.10.0-M2 or above

(Note if you use Maven then Maven will do the job for you) into your war WEB-INF/LIB and set following configuration entries:

<context-param>
        <description>
            Initializes the plugins for our groovy handlers
        </description>
        <param-name>org.apache.myfaces.FACES_INIT_PLUGINS</param-name>
        <param-value> 
            org.apache.myfaces.extensions.scripting.jsf.startup.StartupServletContextPluginChainLoader
        </param-value>
</context-param>


This is the most important entry and under normal Servlet containers now we would be set and could start coding, however we have to set additional parameters for TomEE:

 <context-param>
        <description>Additional comma separated loader paths to allow direct editing on the sources directory instead
            of the deployment dir
        </description>
        <param-name>org.apache.myfaces.extensions.scripting.groovy.LOADER_PATHS</param-name>
        <param-value>
            /whatever/myfaces20-extscript-helloworld/src/main/webapp/WEB-INF/groovy
        </param-value>
</context-param>

<context-param>
        <description>Additional comma separated loader paths to allow direct editing on the sources directory instead
            of the deployment dir
        </description>
        <param-name>org.apache.myfaces.extensions.scripting.java.LOADER_PATHS</param-name>
        <param-value>
            /whatever/myfaces20-extscript-helloworld/src/main/webapp/WEB-INF/java
        </param-value>
</context-param>
    
<context-param>
        <description>Additional comma separated loader paths to allow direct editing on the sources directory instead
            of the deployment dir
        </description>
        <param-name>org.apache.myfaces.extensions.scripting.scala.LOADER_PATHS</param-name>
        <param-value>
            /whatever/myfaces20-extscript-helloworld/src/main/webapp/WEB-INF/scala
        </param-value>
</context-param>

<context-param>
        <description>Additional comma separated loader paths to allow direct editing on the source
        directories of the deployment dir.
        </description>
        <param-name>org.apache.myfaces.extensions.scripting.ruby.LOADER_PATHS</param-name>
        <param-value>
            /whatever/extscript-examples/myfaces20-example/src/main/webapp/WEB-INF/ruby
        </param-value>
</context-param>


Those paths point to your source directories hosting the source files. (Note that the Ruby loader paths are only valid with the latest 1.0.5-SNAPSHOTS, 1.0.4 has no Ruby support)

Once done you can start coding in the code hosted at the respective directories.

 More information about setting up Ext-Script can be found here.

Dienstag, 28. Februar 2012

 Marrying JSF and Scala part 3: Custom Components in Scala

Introduction

While JSF2.0 has simlified the component building a lot thanks to the
composite components, there are still usecases when the classical component
building tasks have to be performed.

We showed in part 1 and part 2 how to build the basic JSF artifacts in Scala we now dive deeper into
JSF by showing how to leverage Scala to build your own jsf custom component.

With this article we combine various techniques of Scala for programming custom components.
The case we are going to investigate is a simple hello world component.

A custom component in Scala

First we have a look at the component itself:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import javax.faces.component.{UINamingContainer, FacesComponent}
import java.util.logging.Logger
import javax.faces.event._


/**
 *
 * @author Werner Punz (latest modification by $Author$)
 * @version $Revision$ $Date$
 */

object HelloWorld {
    /*attributes*/
    val ID = "id"
    val SAY_HELLO = "sayHello"

    /*statics*/
    val logger = Logger.getLogger("HelloWorld")
}


/**
 * helper to avoid a problem with the image button being nested in another component
 * takes a calendar as value
 */
@FacesComponent("at.irian.HelloWorld")
@serializable
@ListenersFor(Array(
    new ListenerFor(systemEventClass = classOf[PostRestoreStateEvent]),
    new ListenerFor(systemEventClass = classOf[PostAddToViewEvent])
))
class HelloWorld extends UINamingContainer with StandardComponent {
    /*lets import the attributes due to not having java structs*/

    import HelloWorld._

    def setSayHello2(hello: String) {
        setAttr[String](SAY_HELLO, hello)
    }

    def getSayHello2(): String = getAttr[String](SAY_HELLO, "") + " added text"

    //we now handle the special events
    override def processEvent(event: ComponentSystemEvent) {
        event match {
            case evt: PostAddToViewEvent => logger.info("PostAddToViewEvent called"+getAttr[String](SAY_HELLO,""))
            case evt: PostRestoreStateEvent => logger.info("PostRestoreStateEvent called")
            case _ => {}
        }

        super.processEvent(event)
    }
}
Code a) Custom component

We have a simple component which exposes one additional attribute sayHello2. The component itself is a composite component with an xml template for rendering an performs some listener tasks.

So far so good, however we use several things here which are of interest:

1
2
3
4
5
6
7
8
object HelloWorld {
    /*attributes*/
    val ID = "id"
    val SAY_HELLO = "sayHello"

    /*statics*/
    val logger = Logger.getLogger("HelloWorld")
}
Code b) Singleton
  • A singleton object for static replacements and struct replacements
1
@ListenersFor(Array(...
Code c) Listeners Array
  • A listeners array for combining multiple listeners 
1
with StandardComponent
Code d) trait 
  • a trait instead of a utils class to combine common functionality of components 
1
2
3
4
5
 event match {
            case evt: PostAddToViewEvent => logger.info("PostAddToViewEvent called"+getAttr[String](SAY_HELLO,""))
            case evt: PostRestoreStateEvent => logger.info("PostRestoreStateEvent called")
            case _ => {}
        }
Code e) Type matches
  • matches for types to avoid instanceof cascades
Lets dissect the code parts one by one:


1) Object HelloWorld

Scala does not have neither static variables nor structs, instead of that it provides singletons as language construct.
Static variables simply can be simulated by a singleton and a simple in class import:

1
2
3
4
5
6
7
8
object HelloWorld {
    /*attributes*/
    val ID = "id"
    val SAY_HELLO = "sayHello"

    /*statics*/
    val logger = Logger.getLogger("HelloWorld")
}
Code b) Singleton 

 and then

1
 import HelloWorld._  
 Code f) import

Allows you to import the instance variables and methods as semi native members.

1
logger.info("PostAddToViewEvent called"+getAttr[String](SAY_HELLO,""))
 Code g) import usage

2) Annotation Arrays

1
2
3
4
@ListenersFor(Array(
    new ListenerFor(systemEventClass = classOf[PostRestoreStateEvent]),
    new ListenerFor(systemEventClass = classOf[PostAddToViewEvent])
))
 Code h) annotation array Scala

is simply what would be in Java
1
2
3
4
@ListenersFor({
   @ListenerFor(systemEventClass = classOf[PostRestoreStateEvent]),
   @ListenerFor(systemEventClass = classOf[PostAddToViewEvent])
})
 Code i) annotation array Java

Since this code transition is not quite obvious even within the Scala documentation, it is worth to be noted in this blog.

3) Traits

The most interesting part is the traits part.
First of all, what is a trait. To sum it up, a trait is an abstract class which can be multiply inherited sort of an interface
with code. Now this opens quite a few possibilities.
Common constraints can be isolated and shared among object instances without having to revert to singletons.
Traits can access "this" and can call methods provided by the class as abstract members.

We reuse traits in this case to isolate common component behavior without having to introduce yet another helper class or an
abstract base class. In fact we finally can share this referencing code among components with different base classes without having to introduce our own inheritance hierarchy.

The trait looks like following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
trait StandardComponent {


    def getViewRoot = FacesContext.getCurrentInstance.getViewRoot

    def getLocale: Locale = FacesContext.getCurrentInstance.getViewRoot.getLocale

    def getAttr[T](key: Serializable, default: T): T = {
        val ret = getAttributes().get(key)
        if (ret != null) ret.asInstanceOf[T] else default
    }

    def setAttr[T](key: String, value: T) {
        //note the scala compiler compiles anyref to java.lang.Object
        //in scala itself anyref is one level above Any which is the base
        //of everything scalawise
        getAttributes.put(key, value.asInstanceOf[AnyRef])
    }

    def getAttributes(): java.util.Map[String, AnyRef]

    def reqAttrMap: java.util.Map[String, String] = {
        FacesContext.getCurrentInstance.getExternalContext.getRequestParameterMap
    }


    def getReqAttr(key: String): String = {
        reqAttrMap.get(key)
    }
}
 Code j) Trait

We use only a subset of this functionality namely getAttr and setAttr.




1
2
3
4
   def getAttr[T](key: Serializable, default: T): T = {
       val ret = getAttributes().get(key)
       if (ret != null) ret.asInstanceOf[T] else default
   }
 Code k) getAttr

Here we can see clearly the this reference to the underlying component getAttributes with
 
def getAttributes(): java.util.Map[String, AnyRef]
 
being defined only as interface, which has to be implemented by the component or one of its parents.

4) Match patterns

Now an interesting language part in Scala is the extended matches. Not only you can match in Scala for values, also matches for types and patterns are allowed.
We use the type matches to avoid instanceof if cascades:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
//we now handle the special events
override def processEvent(event: ComponentSystemEvent) {
    event match {
        case evt: PostAddToViewEvent => logger.info("PostAddToViewEvent called"+getAttr[String](SAY_HELLO,""))
        case evt: PostRestoreStateEvent => logger.info("PostRestoreStateEvent called")
        case _ => {}
    }

    super.processEvent(event)
}
 Code l) match patterns

The cases basically replace if instanceof constructs here


 A renderer in Scala

Now what if we want to write the renderer in Scala.
Scala there can support us as well, it has XML support in the language baked in.
Now lets have a look at the renderer (if not done in an xhtml template like it should be)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import javax.faces.render.{Renderer, FacesRenderer}
import javax.faces.context.FacesContext
import javax.faces.component.UIComponent

@FacesRenderer(componentFamily = "javax.faces.Output", rendererType = "at.irian.HelloWorld")
class HelloWorldRenderer extends Renderer {
    override def encodeEnd(context: FacesContext, component: UIComponent) {

        val responseWriter = context.getResponseWriter,
        val text = component.asInstanceOf[HelloWorld].getSayHello2(),
        val id = component.getClientId

        responseWriter.write(
                <div class="helloWorld" layout="block" id={id}>
                    {text}
                </div>.toString
        )
    }
}
 Code m) renderer

Now the interesting part of this renderer is following code:
1
2
3
4
5
     responseWriter.write(
                <div class="helloWorld" layout="block" id={id}>
                    {text}
                </div>.toString
            )
 Code m) render part

As we can see, we simply write the html directly constructs like     id={id} and {text} allow for inline templating.

There are constraints to this approach
  • We cannot write out partial xml. The xml written always must be complete, hence we cannot simply write an open tag first, call a subclass and then close the tag
  • We do not use the startElement, endElement. The plus side is readability. 
  • In the end a composite component and its direct xhtml rendering should always be the first choice. Xhtml simply is the target platform in most cases why not use xhtml also for the component renderer part.

References
  1. Marrying JSF and Scala Part1
  2. Marrying JSF and Scala Part2
  3. Custom Components in JSF (German)
  4. Scala Documentation