Imifos at DEVOXX Paris 2013

C’est fini! The second edition of the DEVOXX France conference is bygone and what remains are souvenirs of a great time in Paris.

Meeting old friends and making new acquaintances, discover new and fascinating stuff in crowded conference rooms and passionate discussions during evening lunches, that was the conference for me. According to Nicolas, DEVOXX France 2013 was also “1478 badges, 180 speakers, a team of 18 volunteers, 9 audio-video technicians and globally 99% of satisfied attendees“.

Let me present a retrospective of the conference – in pictures, of course, telling more than thousands words…

Just a small regret that I have…. the fact that I missed DEVOXX UK this year. As member of the Paper Committee I was of course invited, but I opted for the full DEVOXX France version this time. Next year, I’ll very definitively prefer a 50/50 :-)

Enjoy!

The opening keynote… Paper Committee in the background, the DEVOXX France team and Antonio Gonclaves in pink!
Stephan Janssen, Dad of the DEVOXX family, at the opening keynote.
Martin Odersky, the dad of SCALA and Java Generics, at the opening keynote on “Objects and functions, conflict without a cause?”
As well at the opening keynote: Clarisse Herrenschmidt about “L’histoire des écritures”… starting with the historical origins of signs far in the past, she concluded with Alan Turing – that’s where “our” digital history begins… She received a standing-ovation!
“Winter is coming” by Aurélien Pelletier and Didier Girard. A IMHO rather flat rant on the Java Enterprise world. Could have been a great talk with a bit more finesse.
“Real-time Hadoop: Do it right now with Hadoop and Storm” by Ted Dunning. Machine learning principles explained for Dummies (like me :)
Caffeine bombs…
“Creating Games with WebGL and Three.js” by James Williams.
“Animez vos pages HTML5: un tour d’horizon complet des techniques d’animation en HTML5″ by Martin Gorner. One of the most stunning talks. Check the presentation out at this place – all HTML5 yeah!
I just took a picture through the open door, don’t know what this talk was about :)
“Domotique Low Cost, façon DIY” by Laurent Huet.
“Normal ou décaféiné?” by Alexis Moussine-pouchkine at the 2nd day keynote.
The Devoxx crowd at the 2nd day keynote.
Nicolas Martignole aka Le Touilleur Express, Devoxx France core team member, and Stephan “Dad” Janssen. A good example of “Synergy” – the interaction of multiple elements to produce an effect greater than their sum :)
Devoxx4Kids France BOF by the two organisers Audrey Neveu and Claude Falguière, having a life conference call with the Devoxx4Kids team in Belgium, here Daniel De Luca.
The French Java Duchesses in Action!
Thierry Wasylczenko and Jim Weaver, Oracle JavaFX evangelist, in an interview about, well, JavaFX.
Thierry Wasylczenko on JavaFX…
Stephan Janssen and Yolande Poirier, Oracle Community Outreach Manager, warming up for an interview session :)
Oracles interview session, a more artistic essay :)
“Java EE 7 en Détail” by David Delabassee, the last french speaking Oracle evangelist :) And Arun Gupta just sitting beside me *thumbs up*.
“JavaScript pour les développeurs Java: quels sont les pièges à éviter?” by Florian Boulay. Unfortunately only a quickie. A great session and a must see for all Java web developers around!
Mumpf…
The NAO robot controlled by a LEAP device prototype! Fun :-)
Devoxxians over and over…
Even more Devoxxians…
Most important: 0xCOFFEE!
*thumbs up*
SonarSouce on Sonar…
“Developing Modern Web Apps With Backbone.js” by Sylvain Zimmer, (co-)founder of Jamendo, Joshfire, TEDxParis and the dotJS conference. A real JavaScript genious!
“AngularJS, ou le futur du développement Web” by Thierry Chatel, the founder of the famous Frangular blog.
Thierry Chatel presenting the earliest AngularJS homepage from 2009, at this time in a nerdy geocities look :)
Jean-Laurent De Morlhon and Pierre Gayvallet interviewed by the Programatoo crew just before their session “Le fantome, le zombie et testacular, panorama des outils de tests pour application web moderne.”
And last but not least, the life Cast Codeurs session concluding Devoxx France edition 2013 with a lot of beer and fun!
After the conference is before the conference! See you next year!

More pictures (in hi-res):

Posted in Conferences and Events | Tagged , | Leave a comment

Custom JAAS Realm for Glassfish 3

Building a custom JAAS realm for Glassfish 3 is actually quite straight forward, as long as you know how to do it :) The documentation available around is not very clear and it takes some time to collect the required info on the web and to get it working. So here is a short sum-up of the process.

The first thing to do is to build a realm specific JAR file that is deployed in the Glassfish’s domain directory. This JAR file contains a Realm handler, describing the realm and handling the realm groups, and the ‘LoginModule’ responsible to perform the authentication.

In case of Glassfish 3, we don’t need to develop an entire JAAS solution. We can easily base our solution on some helper classes, as shown hereafter.

Let’s go for the JAR file…

First, the Maven POM (which is generally a sub-module of a project POM, as in this example):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

   <modelVersion>4.0.0</modelVersion>

   <parent>
      <artifactId>myrealm-project</artifactId>
      <groupId>eu.lucubratory.myrealm</groupId>
      <version>1.0-SNAPSHOT</version>
   </parent>

   <artifactId>myrealm-jaas</artifactId>
   <packaging>jar</packaging>

   <name>MyRealm JAAS Module</name>

   <dependencies>

      <!-- 'org.glassfish.security' has a dependency to 'javax.persistence'. However, it is
      currently broken in the java.net and JBoss repositories. To avoid the compilation to
      stop, we get the dependency directly from Eclipse. Later, this explicit dependency might
      be removed. -->
      <dependency>
         <groupId>org.eclipse.persistence</groupId>
         <artifactId>javax.persistence</artifactId>
         <version>2.0.3</version>
         <scope>compile</scope>
      </dependency>

      <dependency>
         <groupId>org.glassfish.security</groupId>
         <artifactId>security</artifactId>
         <version>3.1.1</version>
         <scope>provided</scope>
      </dependency>

   </dependencies>

   <repositories>

       <!-- See above -->
       <repository>
           <id>EclipseLink</id>
           <url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
       </repository>

       <repository>
           <id>glassfish-repository</id>
           <name>Java.net Repository for Glassfish</name>
           <url>http://download.java.net/maven/glassfish</url>
       </repository>

       <!-- Alternative to the java.net repository -->
       <!--repository>
           <id>glassfish</id>
           <name>Glassfish</name>
           <url>https://repository.jboss.org/nexus/content/repositories/glassfish</url>
       </repository-->

   </repositories>

   <build>
       <plugins>
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-compiler-plugin</artifactId>
               <version>2.3.2</version>
               <configuration>
                  <source>1.7</source>
                  <target>1.7</target>
               </configuration>
           </plugin>
       </plugins>
   </build>

</project>

Now the Realm handler class:

package eu.lucubratory.myrealm;

import com.sun.appserv.security.AppservRealm;
import com.sun.enterprise.security.auth.realm.BadRealmException;
import com.sun.enterprise.security.auth.realm.InvalidOperationException;
import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
import com.sun.enterprise.security.auth.realm.NoSuchUserException;

import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;

/**
 * Extends the default implementation provided by "AppservRealm" as requested by
 * com.sun.enterprise.security.auth.realm.Realm in order to make the realm
 * declaration complete.
 */
public class MyRealm extends AppservRealm {

   private static final String JAAS_CONTEXT="jaas-context";

   public MyRealm() {
   }

   /**
    * Initialize a realm with some properties. This can be used
    * when instantiating realms from their descriptions. This
    * method may only be called a single time.
    *
    * @param properties - Key-value pairs defined in the Console's Realm declaration.
    *
    * @exception BadRealmException if the configuration parameters identify a corrupt realm
    * @exception NoSuchRealmException if the configuration parameters specify a realm which doesn't exist
    */
   @Override
   public void init(Properties properties) throws BadRealmException, NoSuchRealmException {

       System.out.println("Init MyRealm");

       // Pass the properties declared in the console to the system
       String propJaasContext=properties.getProperty(JAAS_CONTEXT);
       if (propJaasContext!=null) {
          setProperty(JAAS_CONTEXT, propJaasContext);
       }
   }

   /**
    * Returns a short (preferably less than fifteen characters) description
    * of the kind of authentication which is supported by this realm.
    */
   @Override
   public String getAuthType() {
      return "CustomHardcoded";
   }

   /**
    * Returns the name of all the groups that this user belongs to.
    *
    * @param username name of the user in this realm whose group listing is needed.
    *
    * @return enumeration of group names (strings).
    *
    * @exception InvalidOperationException thrown if the realm does not
    * support this operation - e.g. Certificate realm does not support this
    * operation
    */
   @Override
   public Enumeration getGroupNames(String user) throws InvalidOperationException, NoSuchUserException {

      System.out.println("getGroupNames("+user+")");

      Vector<String> vector = new Vector<>();

      // Get the groups from your DB
      vector.add("group");

      return vector.elements();
   }
}

Having a look in the source code of the Realm class reveals much more things we could do. Most of the tasks are taken charge of by Glassfish’s AppservRealm helper class.

Next task, the ‘LoginModule‘:

package eu.lucubratory.myrealm;

import com.sun.appserv.security.AppservPasswordLoginModule;

import com.sun.enterprise.security.auth.realm.InvalidOperationException;
import com.sun.enterprise.security.auth.realm.NoSuchUserException;

import javax.security.auth.login.LoginException;

import java.util.Enumeration;
import java.util.List;
import java.util.ArrayList;

/**
 * Completes the abstract AppservPasswordLoginModule base class for password-based login modules.
 *
 * Most login modules receive a username and password from the client (possibly through HTTP
 * BASIC auth, or FORM, or other mechanism) and then make (or delegate) an authentication
 * decision based on this data. The AppservPasswordLoginModule class provides common methods
 * for such password-based login modules.
 *
 * This subclasses need to implement the authenticateUser() method and later call
 * commitUserAuthentication().
 */
public class LoginModule extends AppservPasswordLoginModule {

   public LoginModule() {
      System.out.println("MyRealm LoginModule - Construction");
   }

   /**
    * Overrides the authenticateUser() method in AppservPasswordLoginModule
    * Performs authentication of user
    * @throws javax.security.auth.login.LoginException
    */
   @Override
   protected void authenticateUser() throws LoginException {

      System.out.println("MyRealm LoginModule authenticateUser(), _username:"+
             _username+", _password:"+_password+", _currentrealm:"+_currentRealm);

      if (!(_currentRealm instanceof MyRealm)) {
          throw new LoginException("Realm not MyRealm. Check 'login.conf'.");
      }
      MyRealm myRealm=(MyRealm)_currentRealm;

      // Authenticate User
      if (!doAuthentication(_username,_password)) {
          //Login failed
          throw new LoginException("MyRealm LoginModule: Login Failed for user "+_username);
      }

      // Login succeeded
      System.out.println("MyRealm LoginModule: Login Succeded for user "+_username);

      // Get group names for the authenticated user from the Realm class
      Enumeration enumeration=null;
      try {
          enumeration=myRealm.getGroupNames(_username);
      }
      catch(InvalidOperationException e) {
          throw new LoginException("InvalidOperationException was thrown for getGroupNames() on MyRealm");
      }
      catch(NoSuchUserException e) {
          throw new LoginException("NoSuchUserException was thrown for getGroupNames() on MyRealm");
      }

      // Convert the Enumeration to String[]
      List<String> g=new ArrayList<>();
      while(enumeration!=null && enumeration.hasMoreElements())
          g.add((String)enumeration.nextElement());

      String[] authenticatedGroups=g.toArray(new String[g.size()]);

      // Call commitUserAuthentication with the group names the user belongs to.
      // Note that this method is called after the authentication has succeeded.
      // If authentication failed do not call this method. Global instance field
      // succeeded is set to true by this method.
      commitUserAuthentication(authenticatedGroups);
   }

   /**
    * Performs the authentication.
    */
   private boolean doAuthentication(String user, String password) {
      // Implement this.
      return false; // or true :)
   }
}

The result (in this case) is a JAR file named ‘myrealm-jaas-1.0-SNAPSHOT.jar’. This file has to be copied into the domain’s ‘lib‘ directory: ‘…glassfish-3.1.2.2\glassfish\domains\[my domain]\lib‘.

The next step is to register the new realm in Glassfish (for our domain) and to associated the ‘LoginModule’ to invoke for authentication within this realm. For this, we need to edit the file ‘..glassfish-3.1.2.2\glassfish\domains\[my domain]\config\login.conf‘ and add the following lines at the end:

myRealm {
   eu.lucubratory.myrealm.LoginModule required;
};

Now the server is ready to be started and we can install the new realm in the Console: ‘Configurations, server-config, Security, Realms‘ – ‘New Realm‘.

Note that all parameters are important. Set ‘Name’ to ‘my-realm’ and ‘Class name’ to  ‘eu.lucubratory.myrealm.MyRealm’. The name is actually what is referenced in ‘web.xml’ and the class name is the completely qualified identification of the realm description class.

Unfortunately, custom realms are not added by Glassfish to the drop-down list, so we need to use the edit box to specify the complete class name.

Next, we add the (additional) property ‘jaas-context’ with the value ‘myRealm’ as specified in ‘login.conf’. As soon as this gets confirmed by hitting the Save button, you get either an error message (hopefully not) or the console output that shows something like:

INFO: Admin Console: Initializing Session Attributes...
INFO: Init MyRealm (-> that's our out.println)
INFO: SEC1115: Realm [myreal-realm] of classtype [eu.lucubratory.myrealm.MyRealm] successfully created.

If the ‘jaas-context’ variable is wrong, Glassfish will throw the following exception when you try to login later: “com.sun.enterprise.security.auth.login.common.LoginException: Login failed: No LoginModules configured for [Value of jaas-context property]“. This indicates that the server cannot make the link between what is defined in the console and what is in the ‘login.conf’ file.

The last step is to configure our web application to use the new realm. To do so, we add the following in the ‘web.xml’ file.

<login-config>
   <auth-method>BASIC</auth-method>
   <realm-name>my-realm</realm-name>   (name as defined in the console!)
</login-config>

And then, somewhere in a login action (depending on the employed front-end technology)…

:
void login(HttpServletRequest request) {
   :
   request.login(username,password);
   :
}
:

The dependency chain to understand is:

  1. HttpServletRequest.login
  2. web.xml <login-config> <realm-name> pointing to
  3. domain setting (domains\[my domain]\config|domain.xml) realm name pointing to
  4. class describing the realm AND property ‘jaas-context’ parameter pointing TO ‘login.conf’
  5. ‘login.conf’ pointing to the ‘LoginModule’ class to use for authentication

Voila, that’s all… easy, isn’t it :)

Posted in Java | Tagged , , , | Leave a comment

Future<Devoxx UK>

Last year at the Devoxx 2012 in Antwerp, Belgium, we premiered a brand new track for Devoxx: Future<DEVOXX>. Driven by our passion for not only the traditional Java world of laptops, desktops and servers, but also for all the emerging technologies that shape our present and will shape our future. We gathered expert speakers to showcase things sometimes lying far outside of the so far discovered Java continent.

Of course in the rapidly growing world of embedded devices Java, although a relative newcomer, is becoming a true shooting star. But we did not limit ourselves just to the Java ecosystem and served up a flavorful cocktail of topics from a variety of different domains including robotics, embedded devices, drones and even a few amusing things. For a flavour of the content check out “Robots That Care” on Parleys.

We were, and especially me, amazed by the incredible reception of the track. Full house, so to speak, for all Future<Devoxx> sessions, fascinated faces, glowing eyes! That was my personal reward for all the work done by the team.

Afterward we decided that this track has to be part of Devoxx UK! However we ran into an unexpected problem! We received so many awesome conference proposals that we had a very hard time to select the best and most interesting topics and speakers for you. Many great talks had to be rejected including some from the Future<Devoxx> track. Nevertheless, expect enticing embedded devices, Java in the box, and some cute and fascinating robots!

Devoxx UK is about amazing talks, great speakers, smart Devoxxians and galactic networking and… absolutely cool devices! :-)

“At the bottom, robotics is about us. It is the discipline of emulating our lives, of wondering how we work.” Prof. Rod Grupen, Discover Magazine, June 2008

Imifos, Future<Devoxx> track lead

Martijn's Tweet - I'm honored!
Martijn’s Tweet – I’m honored ;-)

See also “NAO visiting Devoxx 2012“.

Posted in Conferences and Events, Java | Tagged , , | Leave a comment

Guava/Logback and Weblogic12c

Using Google’s Guava libraries with Oracle’s Weblogic 12c is not a no-brainer. This is the result of Weblogic using a very old version of the Google Collections library, which is the predecessor of Guava, provides the same classes and more, but also uses the same package name – “…/weblogic12/modules/com.google.common_1.0.0.0_0-6.jar”.

Of course there is a very simple “solution” that you can find on many places on the web (e.g. here and here): replace the Weblogic file with a renamed updated version of the library.

This solution is obviously suicide for any stable production environment, despite of the fact that this seem to work at first sight. It’s like installing a Nitro injection in your car with the risk that the motor explodes one moment or another.

However, there is a clean solution to the problem. In the “weblogic.xml” file, you can tell Weblogic to prefer the libraries provided in your classpath to the ones provided in  Weblogic’s classpath. This applies to your application only. The same works well, by the way, if you want to use SLF4J and Logback instead of Weblogic’s Log4J.

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns .../.. .web-app/1.3/weblogic-web-app.xsd">
      :
      <container-descriptor>
          :
          :
          <prefer-application-packages</a>>
               <!-- Priority is given to SLF4J / Logback JARs embedded with the WAR instead of Weblogic's log4j -->
               <package-name>org.slf4j</package-name>
               <package-name>com.google.collections</package-name>
          </prefer-application-packages>
          :
          <prefer-application-resources>
              <resource-name>
                   org/slf4j/impl/StaticLoggerBinder.class
              </resource-name>
          </prefer-application-resources>
          :
      </container-descriptor>
      :
   </weblogic-web-app>

The same should be possible using the <prefer-web-inf-classes> tag instead, but I never tried this possibility.

Posted in Java | Tagged , , , , | Leave a comment

AngularJS, Jersey, JSP and Java EE 6

The “topro” project (short for “topic proposer”, sorry I wasn’t very inspired on this) is a test that I made to play around with AngularJS. In the opposite to a lot of AngularJS examples on the net, the project implements the entire chain: AngualarJS on the browser side, REST to communicate with the application server, JAX-RS/Jersey as server-side REST implementation, JSP as templating system of the server-side front-end, Java EE 6 for server-side back-end. The project demonstrates many different things, some of them enumerated hereunder.

The choice of using JSP technology for templating may seem strange at first sight. First of all raises the question if we still need server-side templating while having client-side templating with AngularJS. Realistically, the answer is yes when it comes to more complex applications. A lot of things are easier (and smarter) be done on the server before actually delivering the pages: translations, transforming data, security role handling et al.

Concerning JSP, one has to admit that, despite of its age, it’s a great and proven technology. Pre-compiled into servlets, it’s fast compared to other Servlet-based technologies and the JSTL library provides most of what a happy programmer needs to perform efficient templating. Custom Tags come to rescue if this should not be enough. Obviously, Java code in the JSP pages has to be banished. If this discipline is not there, better use PHP then :)

For simplification, the project doesn’t use a database. Data is stored in a flat file de/serialised using the XStream library. You can pull the project and just run it (on Glassfish), without any installation.

The complete source code can be found here: https://github.com/imifos/sample-project-library/tree/master/topro-1

Some things discussed in this project:

*) How to use Jersey not only to implement REST based data resources, but also deliver (JSP) pages. This mechanism is not part of the Java EE 6 JAX-RS standard, but a Jersey specific implementation.

See web.xml and eu.lucubratory.topro1.front.res.page.MainPageResource

@Path("/res/pages")
@Produces(MediaType.TEXT_HTML)
@ManagedBean
public class MainPageResource {
   @GET
   @Path("main")
   public Viewable index(@Context HttpServletRequest request) {
      :
      return new Viewable("/main.jsp", null);
   }

*) How to configure Jersey in the web.xml file to differentiate REST from classic web server file accesses and how to define in which directory the JSP files are located. Since the WEB-INF directory is the only directory that cannot be accessed from the outside, this is the best place to store JSP files.

See web.xml

<filter>
   <filter-name>
      jersey
   </filter-name>
   <filter-class>
      com.sun.jersey.spi.container.servlet.ServletContainer
   </filter-class>
   <init-param>
      <!--  "Viewable" JSP root is placed in the /WEB-INF/jsp directory.
      This means that it's not accessible outside of the web app.
      There's no way to construct a URL that can retrieve these files. -->
      <param-name>
          com.sun.jersey.config.property.JSPTemplatesBasePath
      </param-name>
      <param-value>
          /WEB-INF/jsp
      </param-value>
   </init-param>
   <init-param>
      <!-- Declare what file type should be accessible thru Jersey without being interpreted as REST call.
      Escape img, js, css folders and *.jsp, *.html, *.xhtml from the Jersey filter -->
      <param-name>
          com.sun.jersey.config.property.WebPageContentRegex
      </param-name>
      <param-value>
          (/(img|js|css)/?.*)|(/.*\.jsp)|(/WEB-INF/.*\.jsp)|(/WEB-INF/.*\.jspf)|(/.*\.html)|
                                                                       (/favicon\.ico)|(/robots\.txt)
      </param-value>
   </init-param>
   <init-param>
      <param-name>
         com.sun.jersey.api.json.POJOMappingFeature
      </param-name>
      <param-value>true</param-value>
   </init-param>
   <init-param>
      <!-- Allow JAX-RS resources to use @RolesAllowed, @PermitAll and @DenyAll annotations (like EJBs) -->
      <param-name>
          com.sun.jersey.spi.container.ResourceFilters
      </param-name>
      <param-value>
          com.sun.jersey.api.container.filter.RolesAllowedResourceFilterFactory
      </param-value>
   </init-param>
</filter>

*) How to inject the org.codehaus.jackson library’s ObjectMapper and how to customise the serialiser. The ObjectMapper is documented as idempotent and thread safe – the perfect singletone.

See package eu.lucubratory.topro1.front.common.json

@Qualifier
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD,ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonMapper {
}

public class JsonMapperFactory implements Serializable {

    private static ObjectMapper customisedJsonMapper=null;

    public @Produces @JsonMapper ObjectMapper getJsonMapper(InjectionPoint ip) {

        if (customisedJsonMapper==null) {
           synchronized(JsonMapperFactory.class) {
              if (customisedJsonMapper==null) {
                  SimpleModule myModule = new SimpleModule("TOPRO1",new Version(1,0,0,null));
                  myModule.addSerializer(new ProposalTypeSerializer());
                  customisedJsonMapper=new ObjectMapper();
                  customisedJsonMapper.registerModule(myModule);
              }
           }
        }
        return customisedJsonMapper;
    }
:
}

public class ProposalTypeSerializer extends SerializerBase<ProposalTypes> {

     public ProposalTypeSerializer() {
        super(ProposalTypes.class, true);
     }

     @Override
     public void serialize(ProposalTypes value, JsonGenerator jgen, SerializerProvider provider)
                                                   throws IOException, JsonGenerationException {
         jgen.writeString(Translator.translate(value));
     }
}

*) How to define data REST resources in JAX-RS (Jersey)

See eu.lucubratory.topro1.front.res.topic.TopicsResource

@Path("/res/")
@ManagedBean
public class TopicsResource {

   @POST
   @Consumes(MediaType.APPLICATION_JSON)
   @Path("/topics")
   public void newTopic(@Context HttpServletRequest request, ProposalEntity proposal) {
      try {
         ...
      }
      catch (ValidationException ex) {
         ...
      }
      catch (SystemException ex) {
         throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
      }
   }
:
}

*) How to use the ‘ServiceFacade’ and the ‘Service’ EJB patterns.

See package eu.lucubratory.topro1.domain.topic

@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class TopicFacade {

    @Inject TopicService topicService;

     public void newTopic(ProposalEntity topic) throws ValidationException, DatastoreFailureException {
         topicService.newTopic(topic);
     }
}

@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public class TopicService {

    public void newTopic(ProposalEntity topic) throws ValidationException, DatastoreFailureException {
       :
    }
}

Facades are thin transaction boundary beans and that always start a transaction which is then propagated to one or more services. The real power of this architecture becomes clear with more complex business operations distributed over multiple services.

Services are business logic EJBs that are executed inside of a transactions open by a Facade. Services handle business logic that is too broad to be placed directly in the concerned Entities. Services are never called by the front-end (this would trigger a transaction error), but always via a ServiceFacade.

On the client-side, we have…

*) How to use an application level controller (cf. ‘AppController’) to store global configurations. This avoids “polluting” the ‘$rootScope’ and allows to handle failed sub-controller pre-instantiation Promises. This top-level scope is inherited by all nested controller scopes, just like the ‘$rootScope’ is.

See main.jsp and controllers.js

<body ng-app="topro" ng-controller="AppController">
---
app.controller("AppController",function AppController($scope) {
    $scope.proposalTypes=initProposalTypes();
});

*) How to prepare data via JSP templating that is then passed into AngualrJS controllers.

See MainPageResource, main.jsp and controllers.js

public class MainPageResource {

   @Inject @RawJsonMapper ObjectMapper rawJsonMapper;

   @GET
   @Path("main")
   public Viewable index(@Context HttpServletRequest request) {

       List<ProposalType> proposalTypes=ProposalType.init();
       String jsonProposalTypes=null;

       try {
           jsonProposalTypes=rawJsonMapper.writeValueAsString(proposalTypes);
       }
       catch (IOException  ex) {
           throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR);
       }

       request.setAttribute("proposalTypes",jsonProposalTypes);

       return new Viewable("/main.jsp", null);
   }

---

main.jsp:
<body ng-app="topro" ng-controller="AppController">
   :
   <%-- EAGER DATA INITIALISATION --%>
   :
   <script type="text/javascript">
      function initProposalTypes() {
         return <c:out value="${proposalTypes}" escapeXml="false"/>
      }
   </script>
   :

---

app.controller("AppController",function AppController($scope) {
    $scope.proposalTypes=initProposalTypes();
});

*) How to define a Service/Factory, in this case to perform REST operations using the ngResources module of AngularJS. ‘ngResource’ is declared as a module dependency and injected by AngularJS.

See services.js

angular.module('topicsServices', ['ngResource']).
    factory('Topics',function($resource,AppContext){

       // Returns the topics rest resource, replacing POST by PUT on the update operation.
       // All other methods stay on the default behavior.
       // http://docs.angularjs.org/api/ngResource.$resource
       return $resource(AppContext+'/res/topics/:id', {}, { update: {method:'POST'} });
});

In this case, we declare the factory in an different module (i.e. ‘topicsServices’) than the main.jsp page module (i.e.’topro’) – this is optional. The factory() method of the module object registers a value factory, i.e. a Provider, under the name ‘topicsProvider’. Each time we inject the ‘Topics’ service, AngularJS looks for a ‘topicsProvider’ in its registry ($injector).

There is actually a difference between a Service and a Factory. A Factory represents an object that has a single method: get(). The result of this getter is injected. A Service on the other hand is an injectable constructor. It injects an entire singletone (!) object which can be used to share stuff, data, methods, behavior, event buses between scopes. Under the surface, Services use the Factory mechanism, which uses  the ‘$provide’ AngularJS service.

About dependency injection (DI), the question arises how to implement DI in a weakly-typed environment. Since one cannot rely on types to find what has to be injected (like in Java), AngularJS uses variable names instead. Injecting for example ‘$scope’ or ‘Topics’ in a controller makes AngularJS looking for a ‘$scopeProvider’ or ‘topicsProvider’ respectively ($injector). The $ sign is just part of the variable name and a naming convention to indicate that the information is coming from the AngulaJS framework. It’s the AngularJS namespace.

*) How to use a filter for data transformation (like translation):

See main.jsp and filters.js

   :
   <h2>Proposed Topics</h2>
   <div ng-repeat="topic in topics">
      <p style="font-size: 18px; font-style: oblique; font-weight:bold;">{{topic.title}}<p/>
      <p>{{topic.summary}}<p/>
      <p>{{topic.proposalDate | date:'yyyy-MM-dd'}}<p/>
      <p style="font-size: 9px; font-style: oblique; ">{{topic.comment}}</p>
      <p style="font-weight:bold;">{{topic.type | pronounce:proposalTypes}}</p>
   </div>
   :
---
app.filter('pronounce', function() {
    return function(id,idLabelArray) {
       for (var i in idLabelArray) {
         if (idLabelArray[i].id===id)
            return idLabelArray[i].label;
       }
       return 'no_label_for_'+id;
    }
});

It’s not possible (afaik) to inject the surrounding scope into a filter. By this, it’s not possible to take the translation reference data from the application scope, for example. This is rather a good design since filters should be kept independent of scopes. On the other hand, the ‘$rootScope’, which is the scope associated with the “ng-app” level element, can be injected.

For more complex operations that require scopes, it’s better to use services or scope methods directly.

Posted in Java, JavaScript | Tagged , , , , , , | Leave a comment

FOSDEM 2013

Brussels was, like every year in the first days of February, the center of the European and even galaxy-wide free and open-source world. Around 5000 geeks met this weekend at the FOSDEM conference to meet and greet, to key sign, to tinker, to hack, to exchange and to listen to the 486 lectures happening in the 25 huge, big and small auditoriums.

Part of the FOSDEM 2013 Schedule (Source fordem.org) Click to see more...
Part of the FOSDEM 2013 Schedule (Source fordem.org) Click to see more…

A look at the schedule gives an idea of what huge diversity of domains and what giant amount of knowledge was concentrated in Brussels during these days. F/OSS Technology pure!

Just to tease you, here the list of dev rooms, each running conferences during two days: Keynotes, Lightning talks, Certification, Operating systems, Open source challenges, Security, Beyond operating systems, Web development, Miscellaneous, Robotics, Ada, BSD, Cross desktop, Free Java, Cross distro, Embedded and mobile, Legal issues, Mozilla, Apache OpenOffice, Community Development and Marketing, FOSS for Scientists, Graph Processing, Jabber, Microkernels and Component-based OS, PHP and Friends, Testing and Automation, Wine Project, Virtualisation, X.Org, Cloud, Configuration Systems Management, LibreOffice, MySQL and Friends, NoSQL, Open Source Game Development, PostgreSQL, Python, Smalltalk, Telephony and Perl.

This year was, in opposition to last year where Brussels was quite snowy, rather cold and served us a mix of dry and rainy weather – but again, this was no reason for the geek crowd to not pass the entire weekend on the campus of the Université Libre de Bruxelles (ULB), like every year friendly host of the world biggest FOSS conference.

To me personally, the conference felt less crowded, in my opinion due to a better distribution of stands and attracting-to-niche talks ratio. Some new auditoriums have been added as well.

Another surprise was the amount of women at the conference. I would estimate a quota of 10% to 15% of female participation. For European conditions an amazingly good ratio! Well done ladies!

The Free Java dev room at FOSDEM is since many years the biggest OpenJDK meet-up around.You can not only see, but really high-five celebrities like – this year – Mark Reinhold, Chief Architect of the Java Platform Group at Oracle, Sean Coffey, Oracle JDK engineer and maintainer of OpenJDK 7u, Steve Poole, developer and evangelist working since ever  for IBM on the JVM, Simon Phipps, Andrew Haley, Charles Nutter, JRuby lead developer speaking about InvikeDynamic, Paul Sandoz, Ben Evans and Martijn Verburg, LJC and Adopt-A-OpenJDK/JSR evangelists, Heather Van Cura from the JCP program office, Dalibor Topic, Java strategy team at Oracle and OpenJDK manager, Doug Lea per video conference, Mike Milinkovich, executive director of the Eclipse Foundation, and many more…

The ignition of the Free Java marathon was made by Mark Reinhold, speaking about the state of the OpenJDK, which is actually the Java 7 reference implementation and providing 99% of the code for the “official” Oracle JDK.

Mark Reinhold giving the State of the OpenJDK
Mark Reinhold giving the State of the OpenJDK

The day continued with a lot of interesting talks and the sessions were closed by an OpenJDK Governing Board Q & A, with Dr Doug Lea as guest hooked in per video confcall. The first day was concluded at the Free Java speakers et al LibreDinner, sponsored by Oracle, iText and JFree! Thank you!

OpenJDK Governing Board Q & A Session
OpenJDK Governing Board Q & A Session (Mike Milinkovich, Georges Saab, Mark Reinhold, Andrew Haley)

With subjects like InvokeDynamic, Lambdas, Adopt an OpenJDK and the JCP, the second day was as interesting as the first and passed again very quickly.

A huge thank you to the team of the Free Java room – Mario Torre, Martijn Verburg, Tom Marble and the rest of the squad!

The Free Java dev room LibreDinner
The Free Java dev room LibreDinner

The Free Java room, was of course, just a very small part of the conference and I’m sure there will be hundreds of blogs and photo pages published about all the other activities very soon. To conclude my write-up, just check the impressions that I post hereunder.

Hope to see you at FOSDEM 2014!

The Lightning Talk Rooms was always crowed...
The Lightning Talk Rooms was always crowded…
FOSDEM is not only about software. A lot of hardware hacking is going on as well...
FOSDEM is not only about software. A lot of hardware hacking is going on as well…
The O'Reilly's - main sponsor - book corner...
The O’Reilly’s – main sponsor – book corner…
The Eclipse Foundation is not only the EDI and Java projects. Hardware interfacing technologies are also part of their agenda. Here the M2M (Machine to Machine) protocol project (m2m.eclipse.org).
The Eclipse Foundation is not only the IDE and various Java projects. Hardware interfacing technologies are also part of their agenda. Here the M2M (Machine to Machine) protocol project (m2m.eclipse.org).
One of the bigger Auditoriums...
One of the bigger Auditoriums…
One of the small hacker rooms...
One of the small hacker rooms…
Crowded corridors... usual at FOSDEM :)
Full house in all corridors… usual at FOSDEM :)
Classic meet-up place... the Belgian embassy :)
Classic meet-up place… the Belgian embassy :)
NAO was visiting FOSDEM as well!
NAO was visiting FOSDEM as well!
Posted in Conferences and Events, Java, Python | Tagged , , , , , | Leave a comment

Devoxx 2012 – The Fascinating World of NAO – Slides

With the friendly permission of Aldebaran Robotics, I published the slides of my talk at DEVOXX 2012 about the fascinating world of the NAO robot on Slideshare. Of course, there were a lot of demos and live hacking going on, but you might enjoy the slides anyway :)

Next stop will be the Mix-IT conference in Lyon (April 2013), where Blandine and I will give a 2 hour talk about NAO, with even more demos and more coding! I’m looking forward!

Posted in Conferences and Events, Robotics | Tagged , , | Leave a comment

NAO Technology User Group Belgium

Thursday, January 10th 2013 met the NAO Technology User Group Paris for the first time in the nice offices of Sfeir. Endorsed by Aldebaran Robotics, about 20 people met to get acquainted and to watch NAO demos and technical presentations. The group is organised by Blandine Bourgois. She is as well a passionate NAO developer and as you can see below, the evening was a nice success.

A very interesting talk about how to make better animations with NAO is available online (in french).

Speaking of NAO Technology User Groups, I proudly present the Belgian NAO Technology User Group opening its doors in January as well. Our aim is to reunite users and developers, coders, curious people, researcher and artists, in short everybody that wishes to work with Aldebaran Robotic’s NAO robot.

The main focus however will be the development using Choregraphe, C++, Python and Java. We have NAOs at our disposal and access to Aldebaran Robotic’s NAO Developer Program.

Join us on http://ntug.be and follow us on Twitter: https://twitter.com/ntug_belgium.

Posted in Conferences and Events, Robotics | Tagged , , | Leave a comment

Essay: The future of Java web application development is RESTful

The Web is RESTful

[] In 2000, Roy Fielding, one of the primary authors of the HTTP specifications, wrote a doctoral dissertation titled “Architectural Styles and the Design of Network-based Software Architectures” ([REF1, REF2, REF3]). In this text, he coined the term “Representational State Transfer” to describe the networking principles that characterise the World Wide Web.

In the broadest terms, REST outlines how to define and address sources of specific information, commonly known as resources. Resources are referred to individually with a universal resource identifier, such as the URL used for Web addresses. The term REST often describes any simple interface used to transmit domain-specific data over HTTP without the need for additional messaging layers or session tracking.

REST is an architectural style, not a standard, a protocol or implementation specification. The largest REST application is the Web itself, characterised by the use of HTTP for transport and URLs as addressing mechanisms. REST can support any type of media. [REF4]

REST is a resource-oriented architecture and identifies the key architectural principles of why the World Wide Web is so prevalent and scalable.

The Evolution of Web Application Architectures (from the Java perspective)

Around the year 1995, web pages were mostly static HTML pages served by a classic web server that could have been considered as nothing more than network file servers.

Yet the need of including dynamic content raised and standards like CGI (Common Gateway Interface) or Servlets on the Java side made their entrance.

Web Browsers were merely considered as simple HTML viewer. JavaScript was introduced in 1996 by Netscape, but not supported by all browsers and mostly used to produce fancy effects on web pages.

In 1999, Sun Microsystems released the first version of its J2EE Java 2 Enterprise Edition 1.2 standard, introducing Java Server Pages 1.1. The architecture of J2EE was heavily influenced by distributed computing architectures like CORBA and DCE, and the web presentation technology JSP, based on the servlet technology, was inspired by PHP and ASP. Content was managed by the server and “dynamic” HTML pages where generated on the server before being delivered to the client browser for mostly static display.

Today, in 2012, the topology of the web has changed. Web applications are rich applications doing more than just showing data. They provide rich look-and-feel, are responsive and highly dynamic. Browsers have become powerful run-time environments for executing software. HTML, together with CSS, evolved (and is still evolving) from a simple display description language into a Rich Internet Application (RIA) user interface description standard, taking into account modern SEO, semantic web requirements, the advent of mobile clients, micro formats, the separation of semantic (HTML5) and layout (CSS3), and much more.

HTML5 and CSS3 are designed for the web, both now and in the future. These are the specifications that we will be working with for the next decade at least, so the process of its development is relatively slow and considered. For further reading, see [REF5].

In terms of, the Java ecosystem is fragmented. Many technologies exist, variously advanced and modern. Examples are Struts, Spring MVC, Tapestry, Wickets, JSP, Java ServerFaces (JSF), Grails, GWT, Play!, Stripes, Vaadin, to name a few.

A lot of the modern Java presentation technologies like JSF 2 and Vaadin remove the “burden” of knowing and understanding the principles of the modern web from the Java developer. By keeping a representation and a state of each front-end component (button, list) on the server-side, Java developers interact with the web page using server-side executed Java code, at the price of adding a (sometimes) huge overhead in managing these states and obviously breaking with the nature of the modern web.

Considering technologies outside of the classic Java Enterprise world, for instance Ruby on Rails, Grails, Play! or the Node.js eco system, we can see a more evolved way of developing modern web applications: a clear separation of concerns in terms of user interface and domain logic, a clear separation of tasks in terms of display and user interaction and business data management.

The client, in our case the web browser, should handle what it is supposed to handle – the user interaction, and the server should do what it does best, data manipulation, business logic execution and centralisation of domain knowledge – in a presentation agnostic way.

At client side, HTML 5, CSS 3 and JavaScript, supported by MVC and data binding frameworks like AngularJS or Backbone.JS, are used to implement a rich and responsive client interface, whereas the server still is a Java Enterprise application. Both side are communicating using REST either performing classic round-trips (Client-Server-Client cycles) or implementing a single-page AJAX paradigm. Dynamic communication between client and server generally uses JSON, a standard lightweight data format, or less frequently XML, to exchange information.

This topology is however not alien to the Java Enterprise world as the existence of a powerful REST support by the Java EE 6 standard (JSR 311, JAX-RS) shows.

Risk Assessment – The Developer

Java developers in general are not known for their flexibility in terms of programming languages variations. They mostly like to stay in the Java world and technologies like JSF 2, Primefaces, GWT or Vaadin allow writing complex web applications without getting too much involved with HTML, CSS and JavaScript. Often, front-end programming is considered 2nd class and executing an Explain Plan on a SQL query is considered a DBA’s task.

With the architecture discussed in this essay however, we require developers to be “polyglot”.

The concept of polyglot programming exists since quite some time in the IT world [REF6], but with the advent of the modern web, more languages and technologies have been added to the portfolio of the modern Java developer, which has to embrace these new challenges.

Don’t be weary, embrace it!

References

[REF1] Architectural Styles and the Design of Network-based Software Architectures
UNIVERSITY OF CALIFORNIA, IRVINE
DISSERTATION, DOCTOR OF PHILOSOPHY in Information and Computer Science by Roy Thomas Fielding, 2000
http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
(Accessed 11.2012)

[REF2] Principled Design of the Modern Web Architecture
Roy T. Fielding (Day Software) and Richard N. Taylor
University of California, Irvine, May 2002
http://www.ics.uci.edu/~taylor/documents/2002-REST-TOIT.pdf
(Accessed 11/2012)

[REF3] Principled Design of the ModernWeb Architecture
Roy T. Fielding and Richard N. Taylor
Information and Computer Science, University of California, Irvine, 2000
http://www.ics.uci.edu/~fielding/pubs/webarch_icse2000.pdf
(Accessed 11.2012)

[REF4] QuickStudy: Representational State Transfer (REST)
It describes the principles that keep things moving smoothly on the Web.
Russell Kay, August 6, 2007
http://www.computerworld.com/s/article/297424/Representational_State_Transfer_REST_
(Accessed 11/2012)

[REF5] Why HTML5 Rocks
http://www.html5rocks.com/en/why
(Accessed 02.2012)

[REF6] MEME AGORA, Polyglot Programming
Neal Ford, Dec 05, 2006
http://memeagora.blogspot.be/2006/12/polyglot-programming.html
(Accessed 11/2012)

Posted in Java, JavaScript | Tagged , , , , , , , , , , , , | 1 Comment

RHoK Belgium – Event #3 – Conclusion

RHoK #3:

We started the 3rd Random Hacks of Kindness Belgium on Saturday with a headcount of 16 people. Both coders and non-coders started brainstorming about two problems presented by the “Movement Without a Name” (Bond Zonder Naam). BZN is a Belgo-Flemish NGO helping disadvantaged people in need, giving them food, shelter, hope, social contacts, … and rising awareness!

BZN will launch a new campaign on the 12th of December. Website, TV spots, ads in newspapers and also a online Loneliness Test. This was one of the two applications we worked on – and we finished the task!

We also did a few non-coding tasks. Marina Cooreman was so kind to translate Bring The Food, created at RHoK Trento, to Dutch! And thanks to Chad Badiyan, we were able to submit a data set with all food banks in Brussels to be injected into the Sheltr database.

We’ve been cooperating with other RHoKs as well. We connected with RHoK Trento to talk about extra features in the Bring The Food application and skyped with RHoK South Hampton to see what they were up to.

We were located at the headquarters of De Persgroep, the biggest media company of Belgium, so journalism couldn’t be missing at our event. Rina Tsubaki from the European Journalism Center was here to follow-up on the complete RHoK event (internationally) and to see how it feels to join such an event. We might work together in the future to create some data mining tools making it easier for smaller media agencies to create quality articles about emergency situation through the usage of ICT and networking. A very nice idea that ignited at the RHoK #3.

Chad Badiyan, from Second Muse acting as steward of the international RHoK movement, gave some insights into how the organisation works at top level. Interesting – and important – to know: Google, NASA, The World Bank and the other main players behind the movement are still there, providing council and taking decisions. And Second Muse, that’s my personal opinion, does a great job stewarding the events!

Concluding:

This event was simple great in terms of organisation done by Maarten Cautreels, in terms of hackers and non-hackers working hand-in-hand to actually conclude projects that have impact, concerning national and international support from Second Muse, the other RHoKs, the European Journalism Center and BZN, and in respect to the amazing venue provided by De Persgroep and the barrels of food sponsored by Contribute4J! Saying that we made the world a bit of a better place is not a presumption!

Links:

Impressions: (use the back button to close the picture)

Posted in Conferences and Events | Tagged , , , , | Leave a comment

Ignite a Java EE 6 project for Eclipse Juno with Maven 3

Supposed that Maven and Eclipse are correctly installed, we can execute in the workspaces directory…

E:\dev\workspaces>mvn archetype:generate

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<<
[INFO]
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: remote -> br.gov.frameworkdemoiselle.archetypes:demoiselle-jsf-jpa (Archetype for web applications (JSF + JPA) using Demoiselle Framework)
2: remote -> br.gov.frameworkdemoiselle.archetypes:demoiselle-minimal (Basic archetype for generic applications using Demoiselle Framework)
3: remote -> co.ntier:spring-mvc-archetype (An extremely simple Spring MVC archetype, configured with NO XML.)
:
:
:
413: remote -> org.codehaus.mojo.archetypes:webapp-j2ee13 (-)
414: remote -> org.codehaus.mojo.archetypes:webapp-j2ee14 (-)
415: remote -> org.codehaus.mojo.archetypes:webapp-javaee6 (-)
416: remote -> org.codehaus.mojo.archetypes:webapp-jee5 (-)
417: remote -> org.codehaus.mojo.groovy:groovy-maven-archetype (An archetype for creating Maven modules/projects using the Groovy language.)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 231:

Find the “webapp-javaee6” archetype ID – in this case 415. This number is changing all the time, btw. Enter 415 at the Maven prompt.

You get asked for the archetype plugin version to use. Let’s chose the latest.

Choose org.codehaus.mojo.archetypes:webapp-javaee6 version:
1: 1.0
2: 1.0.1
3: 1.0.2
4: 1.1
5: 1.2
6: 1.3
7: 1.4
8: 1.5
Choose a number: 8:

Downloading: http://repo.maven.apache.org/maven2/org/codehaus/mojo/archetypes/webapp-javaee6/1.5/webapp-javaee6-1.5.jar
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/mojo/archetypes/webapp-javaee6/1.5/webapp-javaee6-1.5.jar (2 KB at 12.1 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/mojo/archetypes/webapp-javaee6/1.5/webapp-javaee6-1.5.pom
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/mojo/archetypes/webapp-javaee6/1.5/webapp-javaee6-1.5.pom (918 B at 12.0 KB/sec)

Define value for property 'groupId': : eu.lucubratory
Define value for property 'artifactId': : cck
Define value for property 'version':  1.0-SNAPSHOT: :
Define value for property 'package':  eu.lucubratory: :
Confirm properties configuration:
groupId: eu.lucubratory
artifactId: cck
version: 1.0-SNAPSHOT
package: eu.lucubratory
Y: :
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: webapp-javaee6:1.5
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: eu.lucubratory
[INFO] Parameter: artifactId, Value: cck
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: eu.lucubratory
[INFO] Parameter: packageInPathFormat, Value: eu/lucubratory
[INFO] Parameter: package, Value: eu.lucubratory
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: eu.lucubratory
[INFO] Parameter: artifactId, Value: cck
[INFO] project created from Archetype in dir: E:\dev\workspaces\eclipse\cck
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3:31.560s
[INFO] Finished at: Thu Dec 06 21:51:48 CET 2012
[INFO] Final Memory: 12M/245M
[INFO] ------------------------------------------------------------------------
E:\dev\workspaces>

Done! Now, we can enter the directory and build the (empty) project (for fun and download some stuff :).

E:\dev\workspaces\eclipse>cd cck

E:\dev\workspaces\eclipse\cck>mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building cck 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: http://repo.maven.apache.org/maven2/javax/javaee-web-api/6.0/javaee-web-api-6.0.pom
Downloaded: http://repo.maven.apache.org/maven2/javax/javaee-web-api/6.0/javaee-web-api-6.0.pom (4 KB at 16.1 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/javax/javaee-web-api/6.0/javaee-web-api-6.0.jar
Downloaded: http://repo.maven.apache.org/maven2/javax/javaee-web-api/6.0/javaee-web-api-6.0.jar (909 KB at 670.6 KB/sec)
[INFO]
[INFO] --- maven-dependency-plugin:2.1:copy (default) @ cck ---
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/1.5.1/plexus-utils-1.5.1.pom
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/1.5.1/plexus-utils-1.5.1.pom (3 KB at 23.6 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/doxia/doxia-sink-api/1.0-alpha-10/doxia-sink-api-1.0-alpha-10.pom
:
:
[INFO]
[INFO] --- maven-war-plugin:2.1.1:war (default-war) @ cck ---
[INFO] Packaging webapp
[INFO] Assembling webapp [cck] in [E:\dev\workspaces\eclipse\cck\target\cck-1.0-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [E:\dev\workspaces\eclipse\cck\src\main\webapp]
[INFO] Webapp assembled in [24 msecs]
[INFO] Building war: E:\dev\workspaces\eclipse\cck\target\cck-1.0-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18.800s
[INFO] Finished at: Thu Dec 06 21:55:08 CET 2012
[INFO] Final Memory: 12M/243M
[INFO] ------------------------------------------------------------------------
E:\dev\workspaces\eclipse\cck>

The fresh Maven file should look similar to this one:

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

    <groupId>eu.lucubratory</groupId>
    <artifactId>cck</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>cck</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>6.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

Let’s update to Java 1.7, add some useful dependencies (for later :) and attach the Eclipse plugin as well:

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

    <groupId>eu.lucubratory</groupId>
    <artifactId>cck</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>cck</name>
    <url>http://lucubratory.eu</url>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jersey.version>1.11</jersey.version>
        <jackson.version>1.9.2</jackson.version>
    </properties>

    <!-- Order of dependencies is of importance! -->
    <dependencies>

        <!-- Test dependencies -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>

        <!-- The javaee JARs contains an "empty" implementetion, thats why they HAVE to be
        put at the end of the classpath. So potentially added "real" implementations get
        loaded first. -->
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <!-- Full EE profile: <artifactId>javaee-api</artifactId> -->
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

 <build>
   <plugins>
     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
            <source>1.7</source>
            <target>1.7</target>
            <compilerArguments>
                <endorseddirs>${endorsed.dir}</endorseddirs>
            </compilerArguments>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1.1</version>
        <configuration>
           <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>

      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-dependency-plugin</artifactId>
         <version>2.1</version>
         <executions>
           <execution>
              <phase>validate</phase>
              <goals>
                <goal>copy</goal>
              </goals>
              <configuration>
                <outputDirectory>${endorsed.dir}</outputDirectory>
                <silent>true</silent>
                <artifactItems>
                  <artifactItem>
                    <groupId>javax</groupId>
                      <artifactId>javaee-endorsed-api</artifactId>
                      <version>6.0</version>
                      <type>jar</type>
                  </artifactItem>
                </artifactItems>
              </configuration>
           </execution>
         </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <version>2.9</version>
        <configuration>
            <wtpversion>2.0</wtpversion>
            <downloadSources>true</downloadSources>
            <downloadJavadocs>true</downloadJavadocs>

            <additionalProjectFacets>
               <!-- For front-end/web modules -->
               <jst.jaxrs>1.1</jst.jaxrs>
               <jst.jstl>1.2</jst.jstl>
               <jst.web>3.0</jst.web>
               <!-- For back-end modules, replace the above by
               <jst.ejb>3.1</jst.ejb> -->
            </additionalProjectFacets>

            <!-- Set Eclipse project to UTF-8 -->
            <additionalConfig>
              <file>
                 <name>.settings/org.eclipse.core.resources.prefs</name>
                 <content>
                   <![CDATA[eclipse.preferences.version=1${line.separator}encoding/<project>=${project.build.sourceEncoding}${line.separator}]]>
                 </content>
              </file>
            </additionalConfig>

        </configuration>
     </plugin>

   </plugins>
 </build>

</project>

The Eclipse plugin allows generating Eclipse project metafiles by using the command: mvn eclipse:clean eclipse:eclipse (remember: mvn plugin:command). The ‘clean’ parameter is only required when regenerating the Eclipse project files after updates made outside of Eclipse, like adding dependencies in the pom.xml.

Eclipse needs to know the path to the local Maven repository. Therefore the classpath variable M2_REPO has to be set in Eclipse. This can be done via maven: mvn -Declipse.workspace= eclipse:add-maven-repo or manually in Eclipse via the “Window > Preferences, Java > Build Path > Classpath Variables” page, where M2_REPO has to be added.

More info can be found here: http://maven.apache.org/plugins/maven-eclipse-plugin/.

After executing the eclipse plugin, we can open Eclipse and “File, Import…” the project.

Glassfish 3.1.2 and Eclipse Juno

Normally, you would install the Oracle Glassfish plugin for Eclipse via the Eclipse Market, but if you are using Eclipse Juno and Glassfish 3.1.2, the plugin will not be able to handle your Glassfish installation. Juno will not recognize the Glassfish server path. (I don’t understand why the official plugin is always 100 years behind the current Glassfish release?!).

Instead, you have to install another plugin via “Help, Install new Software”. Use this URL to find the operational one:
http://dlc.sun.com.edgesuite.net/glassfish/eclipse/juno/. (There is also http://dlc.sun.com.edgesuite.net/glassfish/eclipse/indigo if you stay with Indigo).

After restarting Eclipse, you will find “GlassFish 3.1.2.2″ in the server view and you can create an instance by selecting the “xxx/glassfish3/glassfish” directory.

Et zou!

Posted in Java | Tagged , , , , , | 1 Comment