Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Sunday, March 16, 2014

Rapid application development with Jboss Forge


Why the Forge!?

Starting a new project can be time consuming task with having to decide the project structure and getting all the configuration files in the correct locations with the correct entries.

JBoss Forge is a decent solution this that helps you jump-start a project very quickly. It helps with the initial 'setting-up' of the different layers of the application, creating required artifacts, testing and deployment. It's a shell based RAD tool that is extensible through plugins and has excellent eclipse integration. Changes on the Forge console immediately reflect on the rest of Eclipse and vice versa. 

It's comparable to using maven architypes. However with architypes, you would have to choose the 'most suitable' architype, run it once and it's done, leaving you to get rid of all the stuff you don't need. Whereas with Forge you can build and shape your project according to your technical direction in an incremental way, with only the pieces that you do need.

Preconditions

In order to use Forge on Eclipse you need to install the Forge plugin on eclipse. Search for JBoss Tools on Eclipse marketplace and install (only) Forge Tools.


After this you should be able to see the forge console (Window>Show View>Forge Console).



You will also need a JBoss runtime in your eclipse that you can deploy to, and make sure you have the maven plugin for eclipse installed (m2e)


Forging your way ahead

Now to demonstrate how we can build a basic web application and RESTful web service from scratch using Forge on Eclipse - in record time.

First, lets create a new project assuming it's going to be a car sales application.
[no project] EclipseWS $ new-project --named CarSales --topLevelPackage com.joerajeev.carsales --type war --projectFolder CarSales
Notice on the Forge console that this created the basic project structure including a pom.xml file. Apparently, JBoss developer studio would have imported the project into the IDE automatically, however since we are using eclipse we have to import the project manually. It would be best to import it as a maven project.

Now lets set up the configurations for the persistence layer. These commands may prompt you with various options. Most often the default option will suffice.
CarSales $ persistence setup --provider HIBERNATE --container JBOSS_AS7
Notice this creates the persistance.xml, updates the pom.xml and also pulls in the required dependencies.

Before creating our entities lets set up bean some validation. Hibernate validation allows us to define constraints in one single place in the code, and have that applied to all the layers of a JavaEE application.
CarSales $ validation setup --provider HIBERNATE_VALIDATOR
As before this updates and pulls in the required dependencies in addition to creating the validation.xml

Lets create an entity for a Car.
CarSales $ entity --named Car
This creates a basic Car entity class and loads it for further manipulation to it such as updating it with fields and validations. If you really want to do this using Forge, it can be done as follows;
Car.java $ field string --named make
Car.java $ constraint NotNull --onProperty make
Car.java $ field string --named model
Car.java $ constraint NotNull --onProperty model
Car.java $ field int --named year
Car.java $ constraint NotNull --onProperty year
Car.java $ field number -type java.math.BigDecimal --named price

We can get back to the 'project level' with
Car.java $ cd ~~

If the class needs to be further updated later you can always manually load the file as follows:
CarSales $ pick-up src\main\java\com\joerajeev\carsales\model\Car.java

Since this is going to be a web app, Forge can help setup the some front end scaffolding for the entities, so that we can do some CRUD operations.
CarSales $ scaffold setup
CarSales $ scaffold from-entity com.joerajeev.carsales.model.*
Note this created the web.xml, a directory structure for a web app and the view (xhtml) pages to do basic CRUD operations.

Lets build and deploy the project
CarSales $ build --notest
Builds us the war file

We can deploy the application to JBoss AS by installing and using the jboss-as-7 plugin
CarSales $ forge install-plugin jboss-as-7
CarSales $ as7 setup
CarSales $ as7 deploy
Note that you will have to provide the path to your JBoss AS installation directory during the as7 setup.

Now we have a application with some basic CRUD functionality deployed at http://localhost:8080/CarSales.


The UI here from the scaffolding we did before. We can take it from here and customize our application for according to the requirements.

Lets go ahead and create some RESTful endpoints for our entity as well
CarSales $ rest setup --activatorType APP_CLASS
CarSales $ rest endpoint-from-entity --contentType application/json ~.model.*
This generates a REST endpoint with CRUD operations for our Car entity.

Now if we redeploy, enter a few cars from the web app (http://localhost:8080/CarSales) and then try the RESTful service endpoint (http://localhost:8080/CarSales/rest/cars) we will get a list of cars in JSON format.


Caveats

  • Forge is still not mature enough to have support across a wide range of technologies. Hopefully once it catches on it will be extended through plugins to support a wider tech stack.
  • It could be more stable. For a tool that's supposed to make your life easier, it did give me some pain with some stuff (especially with setting up and testing with Arquillian), which required an advanced understanding of Maven to resolve.
  • As with any new technology, new commands need to be remembered. However, it does have tab completion which makes things fairly easier.




Saturday, January 25, 2014

Introduction to Nashorn

Nashorn (pronounced naz-horn) is the Javacript engine for the JVM that will be shipped with JDK8. It's a written using 100% Java, is highly optimized and is InvokeDynamic based. Javascript code is converted into bytecode by Nashorn so that it will run on the JVM.

What does that mean?

It means that Nashorn provides complete interoperablity between JavaScript and Java worlds. i.e JavaScript code can directly call Java code, and vice versa. Nashorn also lets you create and manipulate Java objects, extend Java classes and implement Java interfaces. This interoperability also gives access to many additional tools and libraries and gives you the best of both worlds.

Why Javascript?

Javascript as been really taking off along with the popularity of HTML5. Loads of libraries are being introduced every day and there are many Javascript developers out there as well. In fact, stats in 2013 show that there are almost as many Javascript developers as there are Java developers. Turns out Javascript it no longer 'just a' scripting language that is only used for front end development on browsers. :)

How do you start using Nashorn?

You have two options

  • Command Line with jjs
  Set your environment variables to point to your JDK8 installation. (you can get an early access release from here.
  Open up your cmd line and enter jjs
~>jjs
 jjs> print("Hello World");
 
  •  Embed in Java code and use javax.script api
 ScriptEngineManager m = new ScriptEngineManager();
 ScriptEngine e = m.getEngineByName("nashorn");
   
 try {
     e.eval("print('Hello World')");
 } catch (ScriptException e1) {
     e1.printStackTrace();
 }



Examples

Calling Java methods 
As you can see you may treat Java objects just like javascript objects. (Which is achived through InvokeDynamic - which I will come to later)

Java arrays can be created as follows

Collections are interpreted as arrays

Here we are subclassing the abstract TimerTask class.

And since this is really javascript, we can directly pass in the function as a Lambda.

Similarly, functionality can be directly passed into a new thread (again as a Lambda)


Nashorn also integrates well with JavaFX. See this for a pretty cool demo. Just run it with jjs -fx -scripting fireworks.js


InvokeDynamic and Dynalink

This is what enables languages on the JVM to talk to each other. When you make a call, the Dynalink library (using the invokeDynamic instruction) determines at run time if it's a call to a JavaScript function,  Java function or a function of any other JVM language.


Tuesday, December 24, 2013

Introduction to Java 8 lambda expressions

Value parameterization is useful - but only to certain extent. When we try to handle additional use cases, we find the need to handle many special cases. Some developers, try to deal with these special cases using special values (-1, Integer.MAX_VALUE, null) However this is error prone and adds unnecessary complexity to the code. 

Lets start by looking at an example. Say we are developing a car sales application.
The entity class may look something like this.


 public class Car {

   private String make;
   private String model;
   private String type;
   private Integer year;
   private Integer kilometers;
   private String colour;
   private Transmission transmision;
   private BigDecimal price;

   //getters and setters
 }


A functionality required for the app might be the ability to display between a year range. The following method would cater this;


 void showCarsFilterByYearRange(Integer min, Integer max){
   for (Car c : getAllCars()) {
    if(c.getYear() > min && c.getYear() < max){
     display(c);
    }
   }
 }



We can call this with a range like


 showCarsFilterByYearRange(2000, 2005);


This works fine for the range, but we are forced to provide a max year even if we don’t want to. Maybe we can modify the method to support null value params and treat it as a special value ( in this case, when max is null we can safely substitute Integer.MAX_VALUE in it’s place as we are dealing with years here )

 void showCarsFilterByYearRange(Integer min, Integer max){
   for (Car c : getAllCars()) {
    if(c.getYear() > ((min != null)? min : 0)
      && c.getYear() < ((max != null)? max : Integer.MAX_VALUE)){
     display(c);
    }
   }
  }


Now we can only display cars after a particular YOM by passing in null for max


 showCarsFilterByYearRange(2000, null);


Sure this works, but what about additional search requirements? We are bound to need to search vehicles by other parameters such as price, kilometers, transmission. And surely, you should also be able to apply multiple filters? Our approach is obviously quite brittle and code complexity could increase exponentially with each new requirement.

The solution? Parameterization of behaviour (as opposed to values and types)  
The expected behavior should be able to be passed as a function...

In our usecase we need to pass the car filtering logic as such a function. Unfortunately, (at least before Java 8) you cannot just pass a method as a parameter - you can only pass instances of objects. Therefore, this will need to be implemented using functional interfaces (also known as Single Abstract Method (SAM) interfaces).

A functional interface is an interface with only one method. In our case, this method needs to apply a filter to a Car and return a boolean flag.
 public interface CarPredicate {
   boolean test(Car p);
 }


We can have a single filter method that will expect an instance that implements this interface, and uses test method to check the cars.
 public void showFilteredCars(CarPredicate pred){
   for(Car c: getAllCars()){
    if(pred.test(c)){
     display(c);
    }
   }
 }


On the caller end, we can wrap an anonymous inner class declaration and instantiation along with an implementation for the test method and pass it to our showFilteredCars().  In the example below we are displaying the cars made after 2008.
 showFilteredCars(new CarPredicate(){
   public boolean test(Car c){
    return c.getYear() > 2008;
   }
 });

Note we’ve now parameterized the behaviour! The filtering logic is pushed out to the caller, which means we can do any type of filtering without having to touch showFilteredCars(). For example if we need to filter and display cars made after 2008 with manual transmission, the caller just needs to add that logic in;
 showFilteredCars(new CarPredicate(){
   public boolean test(Car c){
    return c.getYear() > 2008 
     && c.getTransmision().equals(Transmission.MANUAL);
   }
 });


It’s instantly obvious that this is a much better implementation. However, there is just too much boilerplate code here which deters programmers from following this approach. That’s where Java8 Lambda expressions come in - we can define the same logic as above with the minimum effort, only using the ‘important bits’.
Revisiting the previous example below, I have highlighted what we can consider the ‘important bits’. I.e (1) the parameter the predicate takes, and (2) the logic of what it returns.
 showFilteredCars(new CarPredicate(){
    public boolean test(Car c){
     return c.getYear() > 2008;
    }
 });

With Java 8 lambda expressions (also called closures) we only need to specify these two things using the following syntax.
 showFilteredCars(c -> c.getYear() > 2008);


It’s important to note that internally still gets converted to an instance of a functional interface. The compiler figures out what type c has to be through type inference.

Note that we did not need to update our showFilteredCars() implementation. However, it turns out that a functional interface that takes an object and returns a Boolean is such a common case that Java8 also provides and generalized predicate so that we don’t have to write our own.
 Interface Predicate {
   Boolean test(T t);
 }

So for completeness, we may update our showFilteredCars() to use this instead.
 public void showFilteredCars(Predicate pred){
   for(Car c: getAllCars()){
    if(pred.test(c)){
     display(c);
    }
   }
 }



The sample code for the above examples are available here

Eclipse IDE with support for Lambda expressions can be found here