Speaking at JavaOne 2013

I’m going to speak at JavaOne 2013, which is my new achievement unlocked! I’ll be talking about a very interesting topic –  integration of Java and JavaScript.

Here is quick abstract of my [BOF5793] session:

There is a perception in the Java community that JavaScript is a second-rate interpreted language whose main purpose is to make Web pages a little prettier. But JavaScript is actually a powerful, flexible, dynamically typed language. And today the language has been experiencing a revival driven by the interest in HTML5. Nashorn is a modern JavaScript engine available on the JVM, and it’s already included with JDK8 builds. This presentation is about building polyglot applications with Java and JavaScript.

Essentially, during this talk I will demonstrate how to leverage Java API from JavaScript and use both languages side-by-side in the real-world use-cases like servlet programming, RESTful WebServices etc. I’ll demo a couple of interesting samples for the audience.

javascript

You can find details about this session the JavaOne website. Stay tuned by following me on twitter, and I hope to see you in a couple days in San Francisco.

Productive Enterprise Web Development with ExtJS and Clear Data Builder

It’s not likely that you’ll start developing an enterprise HTML5 applications without using one of the JavaScript frameworks. One of the most feature-complete frameworks is ExtJS from Sencha, but its learning curve is a bit steep. Our company, Farata Systems, has developed an open source software Clear Toolkit for ExtJS. Clear Toolkit includes an Eclipse plugin called Clear Data Builder (CDB). This is a productivity tool – a code generator – that can create a CRUD application for you in no time. This application will have HTML/JavaScript/ExtJS client and Java-based server. In this article you will learn how jump start development of such Web applications.

Part One: ExtJS MVC Application Scaffolding

In part one I’ll cover the following topics:

  • What is Clear Toolkit for ExtJS
  • How to create ExtJS MVC application for Java-based project
  • How deploy and run your first ExtJS+Java application on Apache Tomcat server

Clear Toolkit for ExtJS contains of following parts:

  • Clear Data Builder – Eclipse plugin that supports code generation ExtJS MVC artifacts based on Java code. CDB comes with wizards to start new project with plain Java or with popular frameworks like Hibernate, Spring, MyBatis.
  • Clear JS – set of JavaScript components that extends ExtJS standard components. E.g. Clear JS contains ChangeObject – a universal way to trace the state changes between old and new versions of the same item in a store.
  • Clear Runtime – Java components that implements server side part of ChangeObject, DirectOptions and etc.

The phrase “to be more productive” means to write less code and produce the results faster. This is what CDB is for. In this article you’ll see how Clear Data Builder helps you to integrate the client side with the back end using the RPC style and how to implements data pagination for your application.

CDB distribution available as plug-in for Eclipse IDE. The current update site of CDB is located here. The current version is 4.1.4 (don’t be surprised – this is a five-year old code generator, and its previous versions were made for generating the UI for Adobe Flex framework). You can install this plug-in via Install New Software menu in Eclipse IDE. The [FIG-1] shows how you can validate plug-in installation. If you see “Clear Data Builder for Ext JS feature” in the list of Installed Software in your Eclipse IDE, you’re good to go.

Important You have to have “Eclipse for Java EE Developers” installed, which includes the plugins for automation of the Web applications.
image
Figure 1. Verifying CDB installation

Clear Data Builder comes with a set of prepared examples that demonstrate the integration with popular Java frameworks – MyBatis, Hibernate, and Spring. Also, a plain Java project example that doesn’t use any of the frameworks is available as well. Let’s start with the creation of the new project by selecting the menu File → New → Other → Clear, and then press Next.

image
Figure 2. New CDB Project Wizard

First of all let’s call the new project episode_1_intro. CDB supports different ways of linking the ExtJS framework to the application. In my case, I already have installed ExtJS libraries under my Web server (Apache Tomcat). We’re going to use this local ExtJS URL, but you can just specify any folder in your machine and CDB will copy the ExtJS file inside your project. Lastly, you can use ExtJS from the Sencha’s CDN, if you don’t want to store these libraries inside your project. Besides, using a common CDN will allow Web browser to reuse the cached version of ExtJS.

For this project we are not going to use any server-side (like MyBatis or Hibernate). Just click the button Finish. First of all, CDB will print some initial messages on the Eclipse console. When CDB runs for the first time it initializes directory structure in the WebContent folder. Inside the WebContent directory CDB creates directory structure which is recommended by Sencha for MVC applications. Also you’ll get the HTML wrapper – index.html – for this application, which contains the link to the entry point of our application.

CDB generates an empty project with one sample controller and one view – Viewport.js. To run this application, you need to add the newly generated Dynamic Web Project to Tomcat and start the server (right-click on the Tomcat in the Servers view of Eclipse).

image
Figure 3. Adding web project to Tomcat

Let me switch to web browser to open this application on http://localhost:8080/episode_1_intro . Voila! Just in couple minutes we’ve setup new Dynamic Web Project with the ExtJS framework support and one fancy button on UI.

image
Figure 4. Running scaffolded application

The next step is to make something useful out of this basic application.

Part Two: Generating a CRUD application

CRUD stands for Create-Retrieve-Update-Delete. It’s a well known term for describing the applications that support data manipulation. They can retrieve the data from some data source and update them too. The Part Two agenda is covering exactly this:

  • Create a simple CRUD ExtJS+Java application
    • Create a POJO and the corresponding Ext.data.Model
    • Create a Java service and populate Ext.data.Store with data from service
    • Use the auto-generated ExtJS application
    • Extend the auto-generated CRUD methods
    • Use ChangeObject

Now I would like to show how to use Clear Data Builder to create a CRUD application. I’ll show you how you can turn your Java POJO class into the ExtJS model. I’ll explain the following:

  • how you can populate the ExtJS store from a remote service
  • how you can use automatically generated UI for that application
  • how you can extend it
  • what the ChangeObject class is for

I will extend the application from Part 1. For my CRUD application I need a Java POJO. First, I’ve created the class Person.java in the package dto. Then I’ve added the fields firstName, lastName, address, ssn and phone and id. Also I need getters and setters for these fields. It’s good to have a constructor for the that uses these fields, and a DTO class should have a toString() method. [LISTING_1]
Now I need the same corresponding ExtJS model for my Person. Just annotate this class with the CDB annotation called @JSClass to ask CDB to generate the ExtJS model.

Person data transfer object

package dto;

import com.farata.dto2extjs.annotations.JSClass;
import com.farata.dto2extjs.annotations.JSGeneratedId;

@JSClass
public class Person {

  @JSGeneratedId
  private Integer id;
  private String firstName;
  private String lastName;
  private String phone;
  private String ssn;

  public Person(Integer id, String firstName, String lastName, String phone,
      String ssn) {
    super();
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
    this.phone = phone;
    this.ssn = ssn;
  }

  // Getters and Setter are omitted

}

Now I need to annotate the id field with the CDB annotation @JSGeneratedId. With this annotation I’ll instruct CDB to threat this field as auto generated id. Let’s examine the directory of ExtJS MVC application and lets take a look inside the model folder. Inside the model folder (the JavaScript section) we have the folder dto which corresponds to the Java dto package where the class PersonModel.java resides.

image
Figure 5. Generated from Java class ExtJS model

As you can see Clear Data Builder generated two files as recommended by the Generation Gap pattern, which is about keeping the generated and handwritten parts separate by putting them in different classes linked by inheritance. Let’s open the person model. In our case the PersonModel.js is extended from the generated _PersonModel.js. Should we need to customize this class, we’ll do it inside the PersonModel.js, but this underscore-prefixed file will be regenerated each and every time when we change something in our model. CDB follows this pattern for all generated artifacts – Java services, ExtJS models and stores. This model contains all the fields from our Person DTO.

Now we need to create a Java service to populate the ExtJS store with the data. Let’s create an interface PersonService in the package service. This service will to return the list of persons. This interface contains one method –List<Person> getPersons().

I need to ask CDB to expose this service as a remote object, which is done by the annotation called @JSService. Another annotation @JSGenetareStore will instruct CDB to generate the store. In this case CDB will create the destination-aware store. This means that store will know from where to populate its content. All configurations of the store’s proxies will be handled by the code generator. With @JSFillMethod annotation we will identify our main read method (remember the “R” from CRUD).

Also it would be nice to have some sort of UI to test the service – the annotation @JSGenerateSample will help here. CDB will examine the interface PersonService, and based on these annotations will generate all ExtJS MVC artifacts (models, views, controller) with the sample application.

PersonService interface annotated with CDB annotations

@JSService
public interface PersonService {
    @JSGenerateStore
    @JSFillMethod
    @JSGenerateSample
    List getPersons();
}

When the code generation is complete, you’ll get the implementation for the service – PersonServiceImpl. The store folder inside the application folder (WebContent\app) has the store, which is bound to the PersonModel. And my person model was generated previously. In this case, Clear Data Builder generated store that binds to the remote service.

image
Figure 6. Structure of store and model folders

All this intermediate translation from the JavaScript to Java and from Java to JavaScript is done by DirectJNgine, which is a server side implementation of the Ext Direct Protocol. You can read about this protocol in Ext JS documentation.

There is one more thing not to be missed – Clear Data Builder generated a UI for us! Check out the samples directory shown on [FIG-7].

image
Figure 7. Folder with generated samples

You can see the SampleController and SampleGridPanel inside the samples folder. CDB also generates the JavaScript application entry point – sampleApp.js. To test this application just copy the file SampleController.js into the controller folder, SampleGridPanel.js into the view folder, and the sample application in the root of our WebContent folder. We need to change the application entry point with sampleApp in index.html.

This is how the generated UI of the sample application looks like [FIG-7]

image
Figure 8. Scaffolded CRUD application template

Let’s return to the server side code. For services CDB also follows the Generation Gap Pattern and it generated stubs for the service methods. Override these methods when you’re ready to implement the CRUD functionality [LISTING_3].

Implementation of PersonService interface
package service;
import java.util.ArrayList;
import java.util.List;

import clear.data.ChangeObject;
import dto.Person;
import service.generated.*;

public class PersonServiceImpl extends _PersonServiceImpl { // 

  @Override
  public List getPersons() {        // 
    List result = new ArrayList&lt;&gt;();  
    Integer id= 0;
    result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
    result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
    result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
    result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
    return result;    //
  }

  @Override
  public void getPersons_doCreate(ChangeObject changeObject) {  // 
    Person dto = (Person) deserializeObject(
        (Map) changeObject.getNewVersion(),
        Person.class);

    System.out.println(dto.toString());
  }

  @Override
  public void getPersons_doUpdate(ChangeObject changeObject) {  // 
    // TODO Auto-generated method stub
    super.getPersons_doUpdate(changeObject);
  }

  @Override
  public void getPersons_doDelete(ChangeObject changeObject) {  // 
    // TODO Auto-generated method stub
    super.getPersons_doDelete(changeObject);
  }

}
1. We need to extend the generated class and provide the actual implementation.
2. getPerson is our retrieve method (the R in CRUD) .
3. For this sample application we can use java.util.ArrayList class as in-memory server side storage of the Person objects. In real world applications you’d use a database or other persistent storage.
4. fillmethod+doCreate() is our create method (the C in CRUD).
5. fillmethod+doUpdate is our update method (the U in CRUD).
6. fillmethod+doDelete is our delete method (the D in CRUD).

Click on the Load menu and you’ll get 4 persons from our server.

To demonstrate the rest of the CRUD methods we’ll ask the user to insert one new row, modify three existing ones and remove two rows using the generated Web client. The Clear.data.DirectStore object will automatically create a collection of six `ChangeObject`s – one to represent a new row, three to represent the modified ones, and two for the removed rows.

When the user clicks on the Sync menu the changes will be sent to the corresponding do… remote method. When you sync() a standard Ext.data.DirectStore ExtJS is POST-ing new, modified and deleted items to the server. When the request is complete the server’s reply data is applied to the store, expecting that some items can be modified by the server. In case of Clear.data.DirectStore instead of passing around items, we pass the delta, wrapped in the ChangeObject.

Each instance of the ChangeOject contains the following:

  • newVersion – it’s an instance of the newly inserted or modified item. On the Java side it’s available via getNewVersion().
  • prevVersion – it’s an instance of the deleted of old version of modified item. On the Java side it’s available via getPrevVersion().
  • array of changepropertyNames if this ChangeObject represents an update operation.

The rest of ChangeObject details described on wiki on github (see the link in Useful Links section).

The corresponding Java implementation of ChangeObject is available on the server side and Clear Toolkit passes ChangeObject instances to the appropriate do* method of the service class. Take a look at the getPersons_doCreate() method from [LISTING_3]. When the server needs to read the data arrived from the client your Java class has to invoke the method changeObject.getNewVersion(). This method will return the JSON object that you need to deserialize into the object Person. This is done in [LISTING_3] and looks like this.

 Person dto = (Person) deserializeObject(
                (Map) changeObject.getNewVersion(),Person.class);

When the new version of the `Person` object is extracted from the `ChangeObject` you can do with it whatever has to be done to persist it in the appropriate storage. In our example we just print the new person information on the server-side Java console. This is why we said earlier, that it may be a good idea to provide a pretty printing feature on the class `Person` by overriding method `toString()`. Similarly, when you need to do a delete, the `changeObject.getPrevVersion()` would give you a person to be deleted.

Part Three: Data Pagination

The pagination feature is needed in almost every enterprise web application. Often you don’t want to bring all the data to the client at once – a page by page feeds is a lot more responsive. The user can navigate back and forth between the pages using pagination UI components. To do that, we need to split our data on the server side into chunks so we can display it only once specific page is required. Implementing pagination is the agenda for the Part Three of this article. Here’s the plan:

  • Add the data pagination to our sample CRUD ExtJS+Java application:
    • Add the Ext.toolbar.Paging component
    • Bind both grid and pagingtoolbar to the same store
    • Use DirectOptions class to read the pagination parameters

We are going to extend our CRUD application by adding the paging toolbar component bound to the same store as the grid. The class DirectOptions will handle pagination parameters on the server side.

In Part 1 and 2 you’ve learned how to generate the UI from the Java back end service and how to generate the ExtJS store and ExtJS model. In this part you’ll how to add the pagination functionality to our CRUD application by asking the server to send only portions of data. I’ll need to refactor the service code from previous example to generate a little bit more data than only five records. [LISTING_4]

Refactored implementation of PersonService Interface


public class PersonServiceImpl extends _PersonServiceImpl {
  @Override
    public List<Person> getPersons() {
        List<Person> result = new ArrayList<>();
        for (int i=0; i<1000; i++){
            result.add(new Person(i, "Joe", "Doe", "555-55-55", "1111-11-1111"));
        }
        return result;
    }   
}

The Google Chrome Console shows that PersonStore was populated with one thousand records. Let’s add the pagination component using the Ext toolbarpaging component. Let’s add it to the file sampleApp.js [LISTING_5].

Sample Application Entry
Ext.Loader.setConfig({
  disableCaching : false,
  enabled : true,
  paths : {
    episode_3_pagination : 'app',
    Clear : 'clear'
  }
});

Ext.syncRequire('episode_3_pagination.init.InitDirect');
// Define GridPanel
var myStore = Ext.create('episode_3_pagination.store.dto.PersonStore',{});    //
Ext.define('episode_3_pagination.view.SampleGridPanel', {
  extend : 'Ext.grid.Panel',
  store : myStore,
  alias : 'widget.samplegridpanel',
  autoscroll : true,
  plugins : [{
    ptype : 'cellediting'
  }],
  dockedItems: [
    {
      xtype: 'pagingtoolbar',    //
      displayInfo: true,
      dock: 'top',
      store: myStore      //
    }
  ],
  columns : [
    {header : 'firstName', dataIndex : 'firstName', editor : {xtype : 'textfield'}, flex : 1 },
    {header : 'id', dataIndex : 'id', flex : 1 },
    {header : 'lastName', dataIndex : 'lastName', editor : {xtype : 'textfield'}, flex : 1 },
    {header : 'phone', dataIndex : 'phone', editor : {xtype : 'textfield'}, flex : 1 },
    {header : 'ssn', dataIndex : 'ssn', editor : {xtype : 'textfield'}, flex : 1 }],
  tbar : [
    {text : 'Load', action : 'load'},
    {text : 'Add', action : 'add'},
    {text : 'Remove', action : 'remove'},
    {text : 'Sync', action : 'sync'}
    ]
  });
// Launch the application
Ext.application({
  name : 'episode_3_pagination',
  requires : ['Clear.override.ExtJSOverrider'],
  controllers : ['SampleController'],
  launch : function() {
    Ext.create('Ext.container.Viewport', {
      items : [{
        xtype : 'samplegridpanel'
      }]
    });
  }
});
1. Let’s manually instantiate this store – create a separate variable myStore for this store and with empty config object.
2. Adding the xtype pagingtoolbar to this component docked items property – I’d like to display the information and dock this element at the top.
3. Now the paging toolbar is also connected to same store.

Now we need to fix automatically generated controller to control loading of data on
click of Load button [LISTING_6].

Controller for sample application

Ext.define('episode_3_pagination.controller.SampleController', {
  extend: 'Ext.app.Controller',
  stores: ['episode_3_pagination.store.dto.PersonStore'],
  refs: [{                //
    ref: 'ThePanel',
    selector: 'samplegridpanel'
  }],

  init: function() {
    this.control({
      'samplegridpanel button[action=load]': {
        click: this.onLoad
      }
    });
  },

  onLoad: function() {
    // returns instance of PersonStore
    var store = this.getThePanel().getStore();    //
    store.load();
  }
});

1. We can bind the store instance to our grid panel. In controller’s refs property I’m referencing our simplegrid panel with ThePanel alias.
2. In this case I don’t need to explicitly retrieve the store instance by name. Instead, we can use getters getPanel() and getStore() automatically generated by the ExtJS framework.

When the user clicks the button next or previous the method loadPage of the underlying store is called. Let’s examine the directprovider URL – server side router of remoting calls – and see how the direct request looks like. Open Google Chrome Developer Tools from the menu View → Developer, refresh the Web page and go to the Network tab. You’ll that each time the user clicks on the next or previous buttons on the pagination toolbar the component sends directOptions as a part of the request.

image
Figure 9. Request payload details

Default Ext Direct request doesn’t carry any information about page size. Clear JS, the client side extension of the ExtJS framework, adds some extra functionality to Ext.data.DirectStore component to pass the page start and limit values to the server side. At this point, the directOptions request property shown in [FIG-9] can be extracted on the server side to get the information about the page’s boundaries. Let’s return to the code of PersonServiceImpl and add some extra code there. Right now the pagination doesn’t work. The server sends the entire thousand records, because the server is not aware that the data has to be paginated. We’ll fix it in [LISTING_7].

Implementation of PersonService with pagination

package service;
import java.util.ArrayList;
import java.util.List;

import clear.djn.DirectOptions;      //

import dto.Person;
import service.generated.*;

public class PersonServiceImpl extends _PersonServiceImpl {
  @Override
  public List getPersons() {
    List result = new ArrayList&lt;&gt;();
    for (int i=0; i
    int start = ((Double)DirectOptions.getOption("start")).intValue();
    int limit = ((Double)DirectOptions.getOption("limit")).intValue();

    limit = Math.min(start+limit, result.size() );    //
    DirectOptions.setOption("total", result.size());  //
    result = result.subList(start, limit);      //

    return result;
  }
}

1. On the server side there is a special object called DirectOptions, which comes with Clear Toolkit.
2. We’re interested in start and in limit options (see [FIG-9]).
3. Calculate the actual limit. Assign the size of the data collection to the limit variable if it’s less than the page size (start+limit).
4. Notify the component about the total number of elements on the server side by using DirectOptions.setOption() method with total option.
5. Before returning the result, create a subset, an actual page of data. In this case I need to use method of java.util.List.sublist() which produces the view of the portion of this list between indexes specified by the start and the limit parameters.

As you can see from the Network tab in [FIG-8], we limited the data load to 25 elements per page. Clicking on next or previous buttons will get you only a page worth of data. The Google Chrome Developers Tools Network tab shows that that we are sending start and limit every time and our response contains object with 25 elements.

If you’d like to repeat all of the above steps on you own, watch the screencasts where I perform all the actions described in this article.

Conclusion

The development of enterprise web application involves many steps that need to be done by developer. But with the right set of tools the repetitive steps can be automated. Remember the DRY principle – don’t repeat yourself. Try to do more with less efforts. I hope this article will help your to get started start with Clear Data Builder, which should make any ExtJS enterprise software developer more productive.

Subscribe to our youtube channel to get access to the latest videos, screencasts and learning materials. You are invited to read our upcoming book “Enterprise Web Development” (work in progress) that includes coverage of ExtJS.

Viktor Gamov

E-Commerce with Hybris

People are accustomed to buying goods online. If a company sells products to individuals, we call it B2C for Business To Consumers. If a business sells to other businesses – it’s B2B. Having an online store allows to sell around the clock regardless of the consumer’s location (at least within the country) as long as he or she is connected to the Internet. People spend some substantial time online and sellers are trying to reach their clients via all possible channels and devices being that a regular HTML Web page, a social network, a mobile application on any device with embedded browser. Still, some people aren’t Internet savvy and business will continue using more traditional channels like printed mail order catalogs. This is what the multi-channel marketing is about. Ideally, a business should be able to combine marketing the products with selling them right there. If you’ve seen the product commercial on Facebook or your mobile phone the storefront should be there too.

Ingredients of an online store

If I’d ask you to give me an example of an e-commerce site, most likely you’d answer Amazon or eBay. Agree. But what’s needed for building an e-commerce system? Let’s come up with a list of building blocks and solutions that Joe Smith, a CIO of the Best Stuff, Inc. would need to create an e-commerce portal:

– A shopping cart
– A catalog
– Integration with several payment systems
– Order management system
– Full text search
– High-load solutions
– Selling through social networks
– Ability to create UI supporting variety of desktop and handheld devices
– Integration with warehousing software
– Data feeds from external systems
– Consumers reviews, locator services, Web analytics
– Live video chats with customer supports

This list is not complete. Starting developing such a complex system from scratch would be insane unless you have unlimited budget and no deadlines to meet. On the other hand, trying to find a Swiss army knife solution usually translates into purchasing super expensive software with 80% of the functionality that you’ll never use. The truth is somewhere in the middle, especially in the age of Software-As-A-Service (SaaS) where you can subscribe to only what you need.

Hybris ingredients

Our company, Farata Systems has an e-commerce team that works with the Hybris software suite. For detailed comparison reviews of the e-commerce solutions refer to Gartner or Forrester. I can just offer you a Hybris review based on our real-world experience.

When we were offered to work on our first Hybris project we had to google this name up. Still, we were hired because of our solid expertise in enterprise development using Java and Spring framework, which are pre-requisites for developing software with Hybris Multi-Channel Suite.

Hybris is a well designed modularized software built on top of Apache and SpringSource components, containers and servers. We’ve been given login credentials to be able to access product Wiki and rolled up our sleeves. The software comes with an installer that includes modified Apache Tomcat servlet container, Spring modules and a home-made ORM framework for data persistence.

Finding goods

Finding goods in your online store has to be easier than in a brick and mortar one. Say you want to buy an engagement ring, but not sure if it has to be made of a white gold with diamonds or something more modest. Writing strict SQL queries is not overly flexible, but the full text search (FTS) technique allows examine all words in each document in your database rather then specifying the column names in the database table. The FTS feature give lots of flexibility in creating stores which allow to quickly find the products that closely match your customer’s needs (e.g. diamonds of certain shape, size, price range etc.) Hybris ships with the FTS module based on the fast search engine Apache SOLR (a Lucene extension). The system periodically (say, every minute) runs the data indexing process. You write queries not in SQL, but in a special query language.

Customization

This tightly integrated software allows you to create and release in production a simple online store in less than a month. But a typical store or an auction requires implementation of lots of custom solutions. For example, let’s take order fulfillment. Hybris offers off the box the basic solutions supporting order management and consignment. But in our projects we had to implement fulfillment algorithm that would take into account the distance between the warehouse and the consumer and minimize the number of shipments. For example, the customer wants to purchase twenty large screen TVs. The system has found six TV’s in one of your stores and four in the other. Since we need another ten TV’s our custom algorithm sends a request to a warehouse to order these additional TV sets. As a result – the customer will get a shipment of all twenty items shipped in a least expensive way.

Such customized business logic is implemented in Java as beans of Spring framework, which is literally a fabric of the entire Hybris software. Your code always has access to Spring context object. By adding custom extensions you create the child context object with your Spring bean containing custom logic to place a distributed order of 20 TVs.

From the software architect perspective, the ease of extending existing Hybris entities is very appealing. For example, if you need to add customer reviews features, just add a couple of fields to the Product entity, create a new entity for ProductReview and link them together. Then add a row of those yellow stars to the storefront UI and you’re set.

User Interface

With Hybris you have a complete freedom of selecting the UI platform for your online store. So far we’ve been using HTML, JavaScript and JQuery framework. But we could have used Java, Flex, or Silverlight for the UI if this would meet our needs. Hybris uses Spring MVC that can present the data as JSP pages or send the raw data as XML or JSON to the UI tier – just parse the data and display them any way you like. If you prefer an easily customizable solution, Hybris includes a CMS module, which allows you to specify the Web page layout and change it dynamically during the run-time.

Product Maintenance

Yet another interesting Hybris module is called Cockpit, which becomes quite handy in environments where the information changes quickly and the customers need to see the latest product information. We even customized Cockpit for building our own administration tool for the online auction project.

Launching Server

The launch of your Hybris server can be configured to load only those modules that are needed for your store. Our fully loaded server starts within 2 minutes, which is not bad at all. The initial install of the Hybris server comes with the in-memory HSQLDB, which is fast, but not suitable for the real-world applications. We started with MySql Server and then switched to Oracle with very minimal manual tuning.

Payment processing

Integration with the payment gateway is probably the most critical component of any online store or auction. Hybris has its own payment module, but we’ve been asked to integration with another payment processing engine – Litle.com using XML as the data exchange format. Little accepts all kinds of credit cards, PayPal, eCheck, mobile payments, and bill-me-later option. Introducing another provider in your payment workflow can make a lot of business sense, but be prepare to find yourself in the middle of the finger pointing game until you finish the payment integration. Add some more cushion there if you are making project estimates.

Scalability

Hybris comes with a clustering solution from the box. Each node of your cluster can be configured to include only those Hybris extensions that it needs. For example, you can configure a cluster with one more for the administration module, three nodes for the store UI, and one node for the data indexing.

In March of 2012 Adobe has announced its partnership with Hybris. Adobe’s CQ5 will help in creating multi-channel digital marketing campaigns and building strong brands for online stores created by Hybris.

Room for improvements

Although our overall impression after using Hybris on a couple of projects is very positive, this software has room for improvements. I’m sure, Hybris management has their reasons for keeping its community closed, but it may hurt the adoption of the software. The product documentation is not too detailed and up to date. Hybris technical experts have to pay more attention to the developer’s forum. In many cases we’ve been using the source code de-compilers to find the answers to our questions. Since Hybris is built on top of Java EE, I’d like the future versions to include a JPA-based solution that would allow using the data persistence solution of our choice rather than a proprietary ORM.

Conclusion

While finding solutions in developing software with Hybris was difficult at time, we never hit the wall, which can be credited to the engineering team. Overall, it’s a solid platform for creating modern online stores and auctions.

When we started our first e-commerce projects with Hybris, we couldn’t find any publicly available online materials about this software written by people in the trenches. I really hope that this article will help anyone who’s still in the process of selecting the right e-commerce software package for their next generation online store.

Yakov Fain

WebSockets: The Current State of the Most Valuable HTML5 API

Last Tuesday I’ve delivered presentation at Princeton JUG «WebSockets: The Current State of the Most Valuable HTML5 API».
HTML5 specification includes WebSockets, a new communication protocol for the Web. It’s becoming the best choice for building real-time Web applications. I did an overview of the servers (including upcoming JavaEE 7 RI – Glassfish 4) and frameworks that support WebSockets and showed some use cases where WebSockets shine. At the end we had short conversation  about various approaches for the server- and client-side implementations of WebSockets that can be used in the Web applications today.

Viktor Gamov

ClearDataBuilder for Ext JS 4.1

ClearDataBuilder for Ext JS 4.1 has arrived! The URL for Eclipse plugin update is http://www.cleartoolkit.com/downloads/plugins/extjs/cleardatabuilder/4.1/site.xml.

What Has Changed
In addition to Ext JS 4.1 support, we introduce much simplified project wizard. Prior versions of CDB required you to create a generic Dynamic Web Project with CDB-specific facets. Now you explicitly create ClearDataBuilder ExtJS Project:

From here you have a clear choice: create a brand new project or piggy-back on one of the pre-built example ones:

The wizard will present you just one dialog. That dialog will contain all settings your project needs.
Let’s look at each of the project types one by one.

Java Example Project

This is the simplest project to setup and the dialog contains only two settings, which are required by all project types: Ext JS Location and Target Runtime.

The first one lets you choose between embedding Ext JS inside your app or point to an external Ext JS URL. To embed Ext JS you select “Browse…” and navigate to Ext JS location on your hard drive. Alternatively you may point to a local URL on your own server or to a Sencha CDN. In the latter case you will be constrained to use production version of the Ext JS.

With the second setting you are indicating a deployment server. Keep in mind, though, that we do not do any testing beyond Tomcat:

The rest – deployment of the example sources is done automatically.

MyBatis and Hibernate Example Projects

If you select MyBatis or Hibernate Example project, you will have to provide one additional setting: location of the folder where wizard deploys the HSQLDB database cleardb that is used by the example application. Keep in mind that you will have to explicitly start the database:

Non Example Project

For regular projects you will have to select the persistence type: MyBatis, Hibernate or None.
You will be able to optionally include Spring support, unless you use MyBatis persistance: we plug MyBatis via Spring so here you do not have a choice. Finally, you will need to select a connection:

That’s it for now. I will be presenting the Ext JS 4.1 and CDB for ExtJS on the Fifth Annual Farata’s Symposium, so join us there.

Victor

Using WebJars for Assets Management in JavaScript Projects

Using automatic build tools for dependency management is best practice in Java world and usage of tools such as Maven has been proven by the years.

But can we utilize existing Maven knowledge of Java dependencies management for JavaScript projects. Luckily, some Java and JVM frameworks (like Grails or Play2) provided their own way of dealing with static resources.

But in most common situations, you don’t have lots of options for deploying your application:

  • keep framework artifacts inside war (minified or not). Not very convenient option if you have lot of small assets in like in Ext JS.
  • use library from CDN (common purposes, like Google or Yandex, or vendor-provided, like Sencha’s Ext JS CDN). Also not very convenient b/s you need to have persistent internet connection during development process.
  • use webJars

Wait, but what is webJars? A couple weeks ago James Ward announced a webJars project to help manage JavaScript dependencies into Java projects. He created maven repository and included few popular libraries (jQuery, Backbone.js, Twitter Bootstrap).

Also he created sample spring mvc application to demonstrate how to use this webjars in real project.

If you can’t find library what you using in repository you can submit new webjar request via Github Issue Tracker.

Today I submitted request for adding Ext JS webjar. Also I provided use case and POC based on James’s spring app demo. You can find that Ext JS webJar usage with spring web app in extjs branch of repository.

The idea behind the scenes if pretty obvious – Spring MVC maps the requests from a given URL to files in the classpath (inside jar). Simple, isn’t it?

Besides, some IDE’s (like Intellij IDEA) can recognize js libraries even inside jar file. But again, for development purposes you can still have copy of framework inside of your project workspace. At this point, you must exclude from ready for deployment artifacts somehow, e.g. using build script. Also, one of benefits of webJars approach – you can maintain different sets of artifacts – debug, release, minified and etc – using maven dependency scope.

Please go to the mentioned github projects, fork it, play around, and share your thought in comments below, and let me know what you think about it!.

If you’re looking for a JavaScript and Ext JS training, please visit our Web site for up-to-date information about the scheduled classes. By the way, two days Ext JS workshop is coming up

Viktor Gamov

Bringing Together Java Ext.Direct and Ext JS Models with DTO2ExtJS

We are close to the beta release of the DTO2ExtJS code generator that automatically converts a Java DTO into Ext JS model. This will be of great help to fellow enterprise developers who use Ext.Direct to remote from Ext JS applications to Java classes in the servlet container. We use DirectJNgine. When Sencha releases an Ext JS implementation of AMF, models generated by our DTO2ExtJS will be used to remote to BlazeDS.

Let’s say you’ve created a Java DTO that looks like this:

package clear.dto;
import com.farata.dto2extjs.annotations.*;
@JSClass
public class UserDTO {
   public String id;
   @JSIgnore      
   public Double salary;
   private Date dob;
   public Date getDob() {
      return dob;
   }
   public void setDob(Date value) {
      dob = value;
   }
   @JSOneToMany(
      foreignKey="userId",
      storeConfig="{"+          
         "paramOrder:['0'],"+   
         "api: {"+
            "create  : Clear.action.TicketAction.getTickets_insertItems,"+
            "read    : Clear.action.TicketAction.getTickets,"+
            "update  : Clear.action.TicketAction.getTickets_updateItems,"+
            "destroy : Clear.action.TicketAction.getTickets_deleteItems"+
         "}"+
      "}")
   public List<TicketDTO> tickets;
}

DTO2ExtJS will generate the corresponding Ext JS code:


// Generated by DTO2EXTJS from AM.model.clear.dto.UserDTO.java on 2012-02-16T20:45:29-05:00
Ext.define('AM.model.clear.dto.generated._UserDTO', {
   extend: 'Ext.data.Model',
   requires: [
      'Ext.data.Types',
      'AM.model.clear.Ticket'
   ],
   fields: [
      { name: 'id', type: Ext.data.Types.STRING, useNull: true },
      { name: 'dob', type: Ext.data.Types.DATE, useNull: true }
   ],
   hasMany: [
      {
         model: 'AM.model.clear.Ticket',
         name: 'getTickets', 
         primaryKey:'id',
         foreignKey:'userId',
         autoLoad: 'true',
         storeType:'AM.store.clear.TicketStore',
         storeConfig:'{
            paramOrder:['0'],
            api: {
               create  : Clear.action.TicketAction.getTickets_insertItems,
               read    : Clear.action.TicketAction.getTickets,
               update  : Clear.action.TicketAction.getTickets_updateItems,
               destroy : Clear.action.TicketAction.getTickets_deleteItems
            }
         }'
     }
   ]
}

and one more class, extending the previous one:


Ext.define('AM.model.clear.dto.UserDTO, {
        extend: 'AM.model.clear.dto.generated._UserDTO'
}); 

As you can see, we keep using the generation gap pattern (the parent class gets regenerates, but the subclass doesn’t) to safely modify the extension and let us keep regenerating the bottom file of the pair, which we do every time the Java file is modified. If your Java class inherits from another one – make sure you annotate the parent as @JSClass and DTO2ExtJs generates models for both, or tell DTO2ExtJs to ignore the parent class entirely, and it’ll obey.

You will be able to fully control the output location and naming of the generated models via APT parameters.

DTO2ExtJS is an annotation processor for Java Annotation Processor Tool and you can use it from the command line and as Eclipse plugin. In the latter case you place com.farata.dto2extjs.asap_4.6.0.jar in
eclipse/plugins folder and com.farata.dto2extjs.annotations.jar in the WebContent/lib of your Eclipse Dynamic Web Project. You can find the current version of the jars at http://www.cleartoolkit.com/downloads/plugins/extjs/dto2extjs

The work-in-progress JavaDoc is available at
http://help.faratasystems.com/en_US/cleartoolkit/reference/java/extjs/

We’ll demo the automatic Ext JS code generation at the end of our 2 day Ext JS workshop in June in New York CIty. Enter Victor as a promo code to get $100 off the price.

Victor

ClearDS for Android

Clear DataServices (ClearDS) is a free productivity tool that compliments Adobe AIR Native Extensions(ANE) for Android devices. It allows to embed BlazeDS into the AIR-based Android application.

Why ClearDS?

ClearDS has been designed for two purposes. Similar to ANE, it allows to code part of your application in Java with full access to Android SDK. In addition, we can turn an Android device into a server, broadening possibilities for application architectures.

Prior to ANE, simple features like Android Toast and Status Bar notifications as well as advanced ones like Text-to-Speech or Speech Recognition were out of reach for ActionScript coders. ClearDS allows you to embed the Android code into a Java class hosted by a servlet container with  BlazeDS and remote to that class with standard and familiar <s:RemoteObject>. There is no dependency on AIR version and you can natively debug the Java portion of your application using Android Eclipse plugin.

By the same token embedding of BlazeDS into  APK turns your application into a server. Now any computer on the same LAN or VPN can remote to your mobile device. Imagine a scenario where your mobile phone is used as a signature pad where you sign to complete an insurance application or  a financial transaction. Here are some other use cases for your mobile phone:

– bar code reader
– better camera for your notebook,
– voice data/entry gadget that renders alphanumeric keyboard useless, eliminating costly clerical mistakes.

How Does It Work?

We fine tuned BlazeDS to be compatible with a set of core Java classes used by Android. To enable HTTP traffic between the SWF and Java portions of your APK we employed Winstone Servlet Container. Since Android APK generated by the Flash Builder generates a single-activity application, we extended this (activity) class. This allowed us to start the ClearDSService when the activity gets created. The service, in turn, starts the Winstone Servlet container. This allows your SWF-based ActionScript code to remote to your Java code within the boundaries of the same APK.

To make the developers’ life easy, we created the ClearDS Eclipse plugin.When you create a new ClearDS project you effectively create two projects: a Flash Mobile project and Android Java mobile project. These projects are related: the additional builder script of the Flash project contributes the SWF as an asset to the Android project. Then you just deploy your Android project the same was as the users of Android Eclipse plugin do. You develop MXML/ActionScript code in Eclipse’s Flash project,  and accordingly,  the Java code in the Android project.

Is ClearDS a Right Approach for You?

Adobe’s AIR Native Extension is a door opener to the world of native APIs of mobile devices. If you find an ANE with the functionality you need – just use it. Unfortunately, there is no way to debug mobile ANE. On the other hand, if you choose the ClearDS route, you will be able to debug the Java code using standard Android ADT Eclipse plugin.

So, as long as you feel comfortable writing Flex and Java code, download the ClearDS plugin and use it right away.

You can also watch this 10-minute screencast of ClearDS plugin in action here.

We also started added the ClearDS-related content to the wiki page of Clear Toolkit located at this URL. You may also subscribe for our new video channel at Youtube.

Victor

Thank you, Java annotation!

This was an interesting bug… I was working on a Web application, where Adobe Flex client was sending an instance of an ActionScript WrapperObject to the Java server, which was supposed to invoke some JBDC code to run an SQL Insert statement saving the data from the Java version of WrapperObject in the database. I wrote all the pieces of Flex, Java, and SQL and started Tomcat in Eclipse IDE.

The Web browser displayed my window, I filled out the form populating the ActionScript WrapperObject and pressed the button Save. Nothing happened. No errors and no data inserted in the database.


Well, need to start debugging…Let’s see what could have gotten wrong:
1. I didn’t properly populate the ActionScript WrapperObject
2. I didn’t properly configure the Java class/method so the front end didn’t even call it.
3. I didn’t code the database portion properly.

But why there is no errors? Starting the Flex part in the debug mode quickly revealed that the WrapperObject was properly populated and the asynchronous request to the Java server has been sent.

Great. The next question is, “Have I called the proper endpoint (the destination) on the Java side and if the correct method has been really invoked?” Started an HTTP/AMF sniffer, which confirmed that I was calling a method on the endpoint mapped to the class Customer shown below. On the Java side, the class hierarchy looked as follows:

class _Customer {
…
   public boolean saveData( WrapperObject wrapper){
       // an empty method   
   }
}

class Customer extends _Customer{

   public boolean saveData (WrapperObject wrapper) {
        // the code saving data in DBMS was here
   }
}


Without leaving Eclipse IDE, restarted Tomcat in the debug mode and put a breakpoint in the caller of Java’s saveData. Interesting… The debugger brought me inside the empty method of _Customer.saveData. Do you see any spelling errors in the method signatures? Me neither. This was about time to use a Java annotation @Override, which I was always underestimating. Changed the class Customer to look like this:
class Customer extends _Customer{

   @Override
    public boolean saveData (WrapperObject wrapper) {
        // the code saving data in DBMS was here
   }
}

Sure enough, the Java compiler immediately told me that the method saveData has to override the one from the superclass. But I did override it, didn’t I?

The problem was that my project has two different versions of the class WrapperObject located in different packages! The superclass was using the WrapperObject from one package, but the subclass from another! This little annotation caught what my eyes didn’t see. Fixed the import statement in the subclass to properly override the method saveData, re-ran the program and got… an SQL error stating that I have an extra comma somewhere in my Insert statement. But this one is a piece of cake! I was so happy.

Thank you Java @Override – you made my day!From now on I’ll be using this example in all my Java classes.

Yakov Fain

Forrester, Java ain’t dead – it’s still #1!

Just finished going through the slide deck from the teleconference dated January 24, 2011. It was titled “Is Java A Dead End For Enterprise Application Development?” This document has been authored by Mike Gualtiery, Senior Analyst from Forrester. If the slide deck’s title has a question mark at the end, the author’s blog simply states that Java’s a dead end.

Bashing Java is popular these days, but is it justified? I don’t believe so. Unfortunately, people who state that Java’s dead are not the people who use the latest Java technologies day in and day out. Sure enough, people are overwhelmed by the amount of news generated by iOS and Adnroid, while Java (the most popular programming language) gives a perception of a stagnating platform.

But in this presentation the author made a number of statements that show that his perception of Java platform is based on the status of the platform several years ago. The main issue is that he’s not aware of how things are done in Java EE 6, which has been released more than a year ago. All accusations that Java developers have to use a “frameworks galore” slowly but surely becomes a history. I had a chance to learn it first hand while working on my Java book published earlier this month.

While the author states that “Java innovation failed to reduce complexity” referring to JSP, JSR, and Struts (?!), in my opinion Java EE 6 is a light-weight and elegant platform. No more heavily configured EJBs. Here’s all you need to create a session EJB. Check this POJO – it’s a stateless session EJB:


@Stateless
public class HelloWorldBean {

    public String sayHello(){
        return "Hello World!";
    }
}

No need to write any XML. Just call the method sayHello() from any other Java class. Below is a Java servlet that can be used as a client for our session bean (don’t look for missing JNDI lookup – the @EJB injects the bean into a servlet):

@WebServlet("/HelloWorldServlet")
public class HelloWorldServlet extends HttpServlet {
    
  @EJB HelloWorldBean myBean;

  protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {

       PrintWriter out = response.getWriter();
       out.println(myBean.sayHello());       
  }
}

JPA 2.0 replaced entity beans. Why do you need Hibernate if in Java EE 6 here’s all it takes to define the Employee entity mapped to a database table:

@Entity
public class Employee{
 
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
 
  @NotNull  
  @Size(max=10)   
  public String firstName;

  @NotNull
  @Size(min=2, max=20)  
  public String lastName;
 
  @Column(name=”boss_name”)
  public String managerName;
 
  @OneToMany (mappedBy = “employee”)
  public List<Address> adresses = new ArrayList<Address>();   

}

I’m not going to bore you with Java code, but it’s really easy now. The statement of the Forrester’s analyst that “Java was not designed to increase productivity of business application” doesn’t bear much weight after you look at the code samples above. Java EE 6 doesn’t stand on the way of application developers. Just put your business logic in the sayHello() method with no or minimum boilerplate code to add.

The author correctly blames Java Swing for being overly complex and JavaFX for failing to present a competitive product. Today this is true. But this is just a small part of a solid platform that enterprises rely upon during the last decade.

Mr. Gualtiery suggests using “better alternatives” as he put it. Namely, Business Process Management (BPM) tools, BI, Business rules management systems. He forgot to mention though, that you’d need to rob a bank first to acquire them. And after this part is done, you’ll still need to do some scripting plus a lot of voodoo dancing around these generic packages to make sure that they perform well with YOUR business application.

He claims that “Newer programming languages are designed to make certain apps easier”. Guess what’s the name of this new language? Ruby on Rails. First, this is not a language, but a 7-year old Web-application framework. Second, during all these years it was not able to become a noticeable tool in the enterprise development field.

The author also mentions some other programming languages forgetting to mention that they run on Java Virtual Machine (JVM), which has been greatly improved over the past years.

The last couple of slides contain recommendations. The author claims, “If you are using Java successfully, there is no reason to abandon the ship right away”. Thank you very much! And then, “If you are using Java unsuccessfully, then look first at your software development life cycle… The platform you use is only as good as people and process…” I can’t agree more. If your organization is full of mediocre software developers, switching Java to any other tool or programming language won’t make a difference. Here’s yet another vague recommendation “Don’t think how you can develop Java applications faster. Instead, think how you can develop applications faster. This opens your mind to look outside Java to these alternatives.” I wonder, how much Forrester charges for this report?

Disclaimer. The next verse has been written neither by me nor by the Senior Analyst from Forrester.

Dm F G My mind is clearer now at last all to well
F G Dm I can see where we all soon will be
Dm F G If you strip away the myth from the man
F G Dm You will see where we all soon will be

Dm Em Jesus!

Yakov Fain