Friday, April 1, 2011

Selenium Automated Test: Close native window "Security Alert"

Facing this "Security Alert" box in the selenium test when try to access a https site.


No admin right so no way to change the security setting. Seems no way to work around this.

Search the selenium board, found that this is Windows native box, therefore out of Selenium's power.

Looking around find this site using python seems solved this issue.

http://datadebrief.blogspot.com/2010/09/automatically-click-yes-on-internet.html

However, no pure Java solution.

Decided to give it a shot myself. Eventually comes out the following code that successfully closed this "Security Alert" box.

Used library: JNative.jar


public class RunSeleniumNativeHelper {
/**
*
* @param windowTitle
* @return Integer in String represents window handler for the window.
*/
public static String findNativeWindow(String windowTitle) {
String hwnd = "0";
int i=0;

try {
JNative FindWindow = new JNative("User32.dll", "FindWindowA");
while ("0".equals(hwnd) && i++<2) {
FindWindow.setRetVal(Type.INT);
FindWindow.setParameter(0, Type.INT, "0");
FindWindow.setParameter(1, Type.STRING, windowTitle);
FindWindow.invoke();

hwnd = FindWindow.getRetVal();
System.out.println("win:" + i + " " + hwnd);
}
} catch (NativeException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

if ("0".equals(hwnd))
throw new NoSuchElementException("No window found with a title of \"" +
windowTitle + "\"");
else
return hwnd;
}

/**
*
* @param parentWinowHandler
* @param buttonLabel
* @return Integer in String represents window handler for the button.
*/
public static String findButtonInWindow(String parentWinowHandler,
String buttonLabel) {
String hb = "0";
int i=0;

try {
JNative FindButton = new JNative("User32.dll", "FindWindowExA");
while ("0".equals(hb) && i++<2) {
FindButton.setRetVal(Type.INT);
FindButton.setParameter(0, Type.INT, parentWinowHandler);
FindButton.setParameter(1, Type.INT, "0");
FindButton.setParameter(2, Type.STRING, "Button");
FindButton.setParameter(3, Type.STRING, "&" + buttonLabel);
FindButton.invoke();

hb = FindButton.getRetVal();
System.out.println("button:" + i + " " + hb);
}
} catch (NativeException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

if ("0".equals(hb))
throw new NoSuchElementException("No button found with a label of \"" +
buttonLabel + "\" in window with a title of \"" +
parentWinowHandler +"\"");
else
return hb;
}

/**
*
* @param buttonHandler
*/
public static void clickButton(String buttonHandler) {
try {
int i=0;
while (!"0".equals(buttonHandler) && i++<2) {
HWND hbHandler = new HWND(Integer.parseInt(buttonHandler));
UINT unit = new UINT(0x201); //native code for mouse event: left button down
WPARAM p1 = new WPARAM(0);
LPARAM p2 = new LPARAM(0);
User32.SendMessage(hbHandler, unit, p1, p2);

unit = new UINT(0x202); //native code for mouse event: left button up
p1 = new WPARAM(0);
p2 = new LPARAM(0);
User32.SendMessage(hbHandler, unit, p1, p2);

System.out.println("click button:" + i + " " + buttonHandler);
}
} catch (NativeException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

We integrated Selenium with Fitnesse so the above code was called in the fixture. Therefore, not like the python sample to have it running as a demon process, but rather one step in the Fitness Script.

In our practice we have to pause before and after this "Security Alert" box to make sure it does showeup before we run the closing code and give it enough time to accept the "Yes" button click.

Below is the sample to run the above code to close the box.

//wait enough second so the security box shows
String winHandler = RunSeleniumNativeHelper.findNativeWindow("Security Alert");
String yesButton = RunSeleniumNativeHelper.findButtonInWindow(winHandler, "Yes");
RunSeleniumNativeHelper.clickButton(yesButton);
//wait enough time so the security box closes and the process completes.

Thursday, August 12, 2010

Spring EYE on JAVA EE – Cond. Detail Installation Instruction

Workstation in windows, presumably Java 6 is installed.

1. download eclipse from the following link, select eclipse IDE for Java Developers
http://www.eclipse.org/downloads/
extract the file to c:\javawork\tools

2. download spring framework from the following link, select "2.5.6.SEC01" then "spring-framework-2.5.6.SEC01-with-dependencies.zip". The version has bundled the dependencies in separate folder.
http://www.springsource.com/download/community
extract the file to c:\javawork\tools

3. download activemq from the following link, select "ActiveMQ 5.3.0 Release" then "apache-activemq-5.3.0-bin.zip"
http://activemq.apache.org/download.html
extract the file to c:\javawork\tools

4. download tomcat 6 from the following link, select "32-bit Windows zip (pgp, md5)"
http://tomcat.apache.org/download-60.cgi
extract the file to c:\javawork\server

5.download project zip file from https://docs.google.com/uc?id=0BxIFLyh-ItQyMTM0Yjc3OWQtODMxYy00NWFiLTkyOWQtZDdkZjNmY2U3YWFi&export=download&hl=en

6. start eclipse, specify the workspace as the following directory
C:\javawork\workspaces
Yours maybe different depending on where you extract the project springdemo.

7. in eclipse, open perspective of Java, import springdemo by following the procedure:
(a) File -> import
(b) General ->Existing Projects into Workspace, then click "Next"
(c) click "Browse" button, find where springdemo is located, in my case at c:\javawork\workspaces\springdemo. springdemo will be loaded in the existing projects. Select it and finish the import

8. go to the view of "Navigator", compare the file structure with the one listed in the blog:
http://hr1551.blogspot.com/2010/03/eye-on-java-ee-springs-practical_5312.html
Add the missing four folders: activemq-data, doc, report, resource/lib

9. copy the required libraries into the resource/lib folder: Your source file location varies depending on where you saved them
(a) From the spring framework:
C:\javawork\tools\spring-framework-2.5.6.SEC01\dist\spring.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\dist\modules\spring-webmvc.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\dist\modules\spring-test.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\dist\weaving\spring-aspects.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\antlr\antlr-2.7.6.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\cglib\cglib-nodep-2.1_3.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\dom4j\dom4j-1.6.1.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\hibernate\hibernate3.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\hibernate\hibernate-annotations.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\hibernate\hibernate-commons-annotations.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\hibernate\hibernate-entitymanager.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\hsqldb\hsqldb.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\itext\iText-2.1.3.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\j2ee\el-api.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\j2ee\jsp-api.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\j2ee\jstl.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\j2ee\jta.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\j2ee\persistence
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\j2ee\servlet-api.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\jakarta-commons\commons-collections.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\jakarta-commons\commons-dbcp.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\jakarta-commons\commons-lang.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\jakarta-commons\commons-logging.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\jakarta-commons\commons-pool.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\jakarta-taglibs\standard.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\javassist\javassist-3.4.GA.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\jexcelapi\jxl.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\junit\junit-4.4.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\log4j\log4j-1.2.15.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\slf4j\slf4j-api-1.5.0.jar
C:\javawork\tools\spring-framework-2.5.6.SEC01\lib\slf4j\slf4j-log4j12-1.5.0.jar

(b) from ActiveMQ package
C:\javawork\tools\apache-activemq-5.3.0\activemq-all-5.3.0.jar
C:\javawork\tools\apache-activemq-5.3.0\lib\optional\xbean-spring-3.6.jar

10. check the build path configuration by right click the project name springdemo ->Build Path->Configure Build Path. The only missing jar left should be external jars point to a tomcat location.

11. fix the missing tomcat jars by add them as external jars following the steps: Tab Libraries ->Add External JARS, find the tomcat location, in my case: C:\javawork\server\apache-tomcat-6.0.29\lib, yours may vary depending on where saved. Select all jars in the folder plus the two jars: commons-daemon.jar and tomcat-juli.jar located in bin folder. (Or as I did copy these two jars to the lib folder and then be selected along with other library files)

12. Now all the missing jars will have a duplicated records in the list so simply remove all missing jars.

13. Now project should be able to be compiled and no more errors.

14. modify the following files so they all points to the correct locations for Java, Tomcat, and Spring:
build.xml
db/server.bat (server.bat maybe displayed as server.bat.changeitbackpls cause gmail does not allow sending executable file, change it back to server.bat)

15. modify tomcat configure file, server.xml in the C:\javawork\server\apache-tomcat-6.0.29\conf so it can include springdemo by adding the following xml element within the <Host></Host> tag. Make sure the docBase point to the correct location where project is saved.
<Context path="/springdemo" docBase="C:\javawork\workspaces\springdemo\war"
crossContext="false" debug="0" reloadable="true" />

16. now it is time to run it by running the default task, runInEclipse, in the build.xml. It will complete the following elemental tasks
(a)startHSQLDB
(b)createHSQLTables
(c)startAppTier
(d)startWebTier
Checking the "Windows Task Manager" there should be three java processes running, corresponding to the HSQLDB, AppTier, and WebTier.
Go to the URL: http://localhost:8080/springdemo/ to check out the application.

A couple of notes for the demo application:
1. After initialization, there is one order in the system. Can be seen by click: Want to View Existing Orders?
2. There is no report after initialization.
3. Adding multiple order for any one specific product, simply click the Add To Cart at the end of the product line multiple times.
4. Running report, only two reports available, and the date format has to be yyyy-mm-dd. Running report will simple submit the report request. It is the asynchronized process. View Report need to go the other link of: Want to See Past Reports?
5. There are some broken links and some pages are used in multiple places, therefore some language/labels does not make sense.

Potential improvement to demonstrate more development practice but not done here:
1. I18n
2. Integration of Automated UAT test by adopting Selenium.
3. Component Validation Test.
4. Better dependency management by adopting sophisticated framework like Ivy or Maven.

Tuesday, March 30, 2010

Spring EYE on JAVA EE – Cond.
Service Pooling

Spring EYE on JAVA EE – Cond. Service Pooling


Source Code with no library jars. Build works in Eclipse env. Require separate Tomcat Installation.



Service pooling is a common practice to improve the performance. By providing the services, typically database sources, or remote services, etc, in a pool, unnecessary creation/destroy of those objects can be eliminated, and the overall performance can be improved by taking advantage of multi-thread build-in parallel computing.


Adding pool is fairly easy in Spring. Spring provides out-of-the-box support for Jakkarta Commons Pool 1.3. To convert a service, by default a singleton in Spring, to a pooled services is as simple as the following steps:


1st, claim the business service as a prototype by flag the bean’s scope as “prototype”.


2nd, create the pool by wrapping Spring’s CommonsPoolTargetSource to the business service.


3rd, make the pool a proxy by wrapping the above pool bean with Spring’s ProxyFactoryBean.


4th, use it in your code.


To demonstrate this, I hereby modified the sample so the ReportExecution becomes a pooled service. ReportExecution is the class that takes the report request, executes it, and returns the report in excel format as a byte array.


There is no change required for ReportExecution class.


Now let’s follow the above steps:


1st, the old bean for the bean reportExecution has been modified by claim it as prototype.




2nd, the pool. Notice the targetBeanName points to the reportExecution bean.




3rd, the proxy. Target the pool.




4th. Usage:


I actually found this is rather tricky in this example since the bean, ReportMessageWorker, that is going to use the pool is a MDB (message driven bean) that is handled by the ActiveMQ.


Apparently @Autowired annotation fails because there is actually two implementation for the same service defined, which is not surprising: one is the original service bean, the other is the pooled service bean.


I tried to define this MDB in the config xml file but it fails too claiming that the bean class was not found though it is clearly in the classpath.


Eventually I found the following works by introducing the ApplicationContext in the MDB, then gaining the reference of the pool by retrieving it by its ID. Code listed below:




In order to demonstrate the pool, the message listener pool is intentionally set as 4, which is bigger than the pool size, set as 2. Breakpoint is added in ReportExecution class so its execution can be monitored. The following snapshot of the threads in eclipse show that there are multiple message listener thread but only two actually get a hold on the report execution.




In summary, Spring significantly simplifies the pooling process.



Previous: JSF & Ajax    

Tuesday, March 23, 2010

Spring EYE on JAVA EE – Cond.
JSF Integration and Ajax Support

Spring EYE on JAVA EE – Cond. JSF Integration and Ajax Support


JSF provides a different component based MVC framework. Not only it provides event handling concept, but it has build-in support for Ajax as well. The easy integration with Spring gives it a significant lift in terms of the web tier implementation.


First step would be to include necessary jars as well as reconfigure web.xml so certain URL patterns can be parsed properly by jsf FacesServlet. Following code indicate what need to be added in web.xml to properly handle all *.jsf request.


web.xml




The intended new functionalities for the demo will be to update product. In order to demonstrate the rich Ajax support that jsf has, the product id is set to automatically submit Ajax calls to the backend to get the other product info to be displayed on the page. By taking advantage of JSF Ajax support, this means only one additional code to add the Ajax tag to response to the default “valueChange” event.


product.xhtml




The last line of the <h:outputText> is for the validation error message.

Ajax backing bean follows the flat bean mechanism so it can too take the advantage of the uniform DAO access. In addition, UI related methods are added to handle JSF UI event. One important member, uiId, is added to identify if server call to update product info is necessary by comparing it with the product real id. This also serves as the entry point to validate the user input id. For some reason, the Ajax tag does not work very well with the standard validation so here I found alternative.


JSF back bean: ProductBean.java




Method detail is intentionally omit.



In theory, flat bean does not likely completely reflect the domain entity, therefore, should not be used directly to update domain entity.


One example of this would be the FlatOrderBean that has a member field in String represents a concatenation of all the product names. To regenerate the products for the original order from this member field would be not only difficulty, but against the data integrity as well. Therefore, this reverse mapping has to be stopped.


However, for other flat beans that are inherently similar to the domain entity, share the same member fields, it makes sense to modify the domain object by providing just UI flat bean.


Product and ProductBean is a perfect pair.


In order to introduce this new functionality, in I_FlatBean interface new method reCreateBaseObject() is added to reversely convert flat bean to domain object. For the case this reverse mapping is not appropriate, e.g. FlatOrderBean, exception would be thrown claiming there is not enough information to recreate Order object; while for the other situation, it is sufficient to update the domain entity, the Product.


I_FlatBean




FlatOrderBean.java




ProductBean.java @ManageBean indicates that JSF framework will handle the life circle of this bean object.




DAO need to be adjusted as well.


HibernateEntityDAO.java




JSF provides convenience but challenge as well. One challenge is how to integrate JSF UI with Spring managed services. Since JSF back beans are managed by JSF framework (notice the @ManagedBean annotation in ProductBean class? This indicates that JSF framework will handle the life circle of this bean object), spring’s characteristic DI will not take place. Therefore, it is difficult to inject services as references into JSF back beans.


In this sample, we create a central place, which is a singleton factory, that holds references to all the web tier services, and provide direct access to those references by expose them through their name. As a result, JSF back beans can find those services by their name. Since this central factory is a POJO, it can take advantage of the Spring DI.


WebTierServiceFactory.java @Service tells Spring framework this is a service that needs to be loaded. @PostConstruct will register the services to the singleton factory.




To access this services is straightforward:


FlatOrderBean.java See how within Save() the reference to the service object is obtained.




Other approach like using JNDI is possible too but not discussed here.


In summary, this example successfully integrated JSF UI component with the Spring managed services without break any Spring in-house MVC component.



Previous: View & Flat Bean    Next: Service Pooling

Tuesday, March 9, 2010

Spring EYE on JAVA EE – Cond.
View and Backing Bean/Domain Object Conversion

Spring Eye on JAVA EE: Spring’s Practical Example for Enterprise Application

Source Code with no library jars. Build works in Eclipse env. Require separate Tomcat Installation.



Spring MVC is a sophisticated framework that makes UI works truly flexible and powerful. Here I am not going to cover all the aspects of MVC, but focus on the View, and try to address a common problem of the incompatibility of the view object and business object, and the solution.


In theory, all server side POJO business objects, the domain objects, could be used on the UI side without modification. But in reality, since domain object has complicated relationship linking to other objects, it is unlikely they can be used directly. For example, an Order object in the previous sample composed of OrderItems, which further associated with Products. On the server side, when associated with hibernate session, all the relationship can be retrieved when necessary (lazy loading), thus solved the dilemma between retrieve necessary data (needs load full object which is memory costing and low performance) and performance (lazy loading retrieve data only when necessary). But when the same object resides on the web side, only a fully loaded object can work since it is detached from hibernate session, but it will likely suffer the performance problem. Therefore, creating UI side backing bean object is a better approach than using the original business object.


In addition, unlike business objects, that defines relationship in associate, composite, and/or aggregation, with one or more other objects, UI backing beans are for display purpose, therefore, can be strip down to isolated objects.


In the next section, by developing the page to list all the existing orders, a standard way of creating backing bean, converting domain object to backing bean, and backing bean's usage is demonstrated.


The web page of order list is like the following:




First take a look on the Backing Bean: FlatOrderBean.java. From the class definition shows this class is extended from AbstractEntity.java, which is the base of all Entities. Backing Beans are no exception. One final member field of Class type defines what is the underline business class for this to associate with. It also implements I_FlatBean interface, which defines two methods. getBaseEntityClass() returns the underline business object class for this Backing Bean class, while setValue() populate the Backing Bean object by providing a corresponding domain object. This I_FlatBean defines all the necessary behavior for the DAO to CR this bean.




Then let’s revisit the uniform DAO class: HibernateEntityDAO.java. It now has the ability to identify if the request entity is in fact Backing Bean, and populate it and return it. The previous consolidation of DAO makes great sense here. This newly introduced Backing Bean can be retrieved without additional DAOes except a little modification on HibernateEntityDAO.




Write a unit test to make sure all steps works well. Notice in the unit test transaction needs to be handled programmatically.




Adding further methods in the façade interface so the above server side business can be transferred to web site. Finish it up with necessary jsp files and configuration changes.


Now the controller will looks as simple as the following:




In summary, this refactoring provides a simple, clean yet powerful way to convert pure domain objects to UI backing bean objects.



Previous: Uniform DAO    Next: JSF & Ajax

Monday, March 8, 2010

Spring EYE on JAVA EE – Cond.
Uniform DAO Implementation

Spring Eye on JAVA EE: Spring’s Practical Example for Enterprise Application

Source Code with no library jars. Build works in Eclipse env. Require separate Tomcat Installation.



From the previous electronic store example, a skeleton of a distributed web application has been constructed. It has a web tier, which talks with the façade app tier via RMI. The app tier communicates with individual entity DAO to acquire the necessary data, while DAO persist the entity into underline database.


Since all DAOes provide similar CRUD functionalities and it is a common refactoring approach to consolidate similar behavior, thus, it makes sense to implement a uniform DAO.


Close look at the entity reveals there are two major types of entity objects. One represents the data that is changed frequently, means CRUD operation is common for them. The other represents rather stable data, only likely operation toward them is READ.


In addition, the quantity of the entity objects needs to be put into consideration as well. Large quantity usually leads to persistence into database. But for the rather stable data with rather limited amount, it makes sense to cache them so the availability is fast and reliable.


Applying the above consideration, among five entities involved in the demo application, Order, OrderItem, and ReportInstance, are obviously fit for the database persistent, frequent CRUD type. Report, on the other hand, fits for the in memory candidate for its stability. Remember in Use Case, we only define two reports. The rather unique entity, Product, which only has stable eight instances defined in the Use Case, can be categorized into either type. In this demo application, it is implemented as the first type, only been striped out CUD functionalities. Its creation is handled by scripting in by SQL Statement.


AbstractEntity.java is created as the base class for all entity to be extended from.




An interface, I_IDBaseLookup.java is created, has only two methods, getEntity(int id) which acquire the entity by its ID, and getEntities() which returns all entities. In this way, the 2nd type entity can be separated from the 1st type, by identifying them by I_IDBaseLoopup.




HibernateEntityDAO.java is created to satisfy the uniform DAO access. In the implementation, entity class is passed in as argument while the code derived mapping based on this, then further complete CRUD functions. All I_IDBaseLoopup object was singled out so its unique implementation can take place.




Additional changes needed for the concrete entities like Order, OrderItem, etc. Here I only implement Order for the demonstration purpose so the old example of Product still works.





The original HibernateOrderDAOTest.java is modified to demonstrate how to use the above HibernateEntityDAO.java. It is clear that the only change was the replacement of the HibernateOrderDAO with HibernateEntityDAO. Obviously configuration file need to be updated to reflect this dependency change as well.





Report.java implements I_IDBaseLoopup by stores static defined Report objects in a Map. This implementation detail for sure is not the only one. Interested Audience may create his/her own.




In summary, this uniform DAO release the developer from creating its own DAO for each individual entity object. In addition, the implementation of Report.java represents a simple way for creating static in memory entities.



Previous:Enterprise Practice    Next: View & Flat Bean

Spring EYE on JAVA EE - 10

Till this point we have successfully created a distributed enterprise application. Thanks to Spring, we achieved this goal without touching cumbersome EJBs. Though there are indeed still plenty of commonly used enterprise components like Email, WS, JMX, etc. not explored here, this mini-series demonstrated the power of Spring and its general approach target Java EE application. There are still plenty of places can be refactored. For example, uniform DAO access to database persisted object (Order) and static defined object (Report); Standard converter between domain object and UI backing beans. These are clearly not critical to the Spring so I left them to the audiences.



In summary, in this article I demonstrated how easy Spring can be used to develop enterprise application. Technologies addressed here are:


Spring MVC, Spring DI, Spring AOP, Spring JMS, Spring RMI, Hibernate, DAO, ActiveMQ, HSQLDB.



Previous    Next: Uniform DAO

Spring EYE on JAVA EE - 9

With the product ordering functionalities in place, let’s get back to the report functionalities purposely left behind. Report request, differentiates itself from other functionalities, for its characteristic slowness. Message Oriented Midware, MOM, provide asynchronized approach is ideal for this kind of request. In addition, MOM broker provide reliability in case of system failure, which is a huge plus for report. Therefore, I will deploy report services via message exchange through MOM broker.


In this project, the open source ActiveMQ broker will be embedded in the app server. In Spring configuration file broker’s configuration is added. Message driven bean, ReportMessageWorker.java, which sebsequently call the report execution, is created and linked to the certain queue in the configuration.


ReportMessageWorker.java




Add the following configuration inspringDemoContext.xml to embed ActiveMQ




Unit test takes advantage of the JmsTemplate provided by Spring for converting and sending message.


ReportJMSTest.java




Similar approaches used in the controller to submit report request.



Now finish up the report functionalities. One thing worth point out is the display of report in Excel format. Since Spring allows directly access to HttpServletRequest/Response object, this can be achieved by direct writing to the response.


ReportController.java




Previous    Next

Spring EYE on JAVA EE - 8

Till now we have build a small application consists of several layers: web, service, DAO, data source. Let’s revisit this to see if there is anything can be refactored according to standard Java EE approach. One thing comes to mind here is the separation of the web layer and the service layer. In standard Java EE spec, the distributed web and service layer is transparent to the application developer. Spring, on the other hand, provides proxy wrapper so through simple configuration the separation can be easily achieved. In this project that implement remote access though RMI, it means nothing more than expose RMI service on the service side while define remote beans on the client side.


springDemoContext.xml




Unit test for this remote configured Spring RMI service is created. Tricky part for this is to start Spring as a standalone application. Spring ApplicationContext implementation takes care of this.


RemoteOrderFunctionTest.java




remoteContext.xml




Web layer reconfigured to match the above changes.


Modify web.xml to reflect this configuration file changes.




Previous    Next

Spring EYE on JAVA EE - 7

Now with the backend services completed, it is time to build the web component by applying Spring MVC module. Actually this development can be parallel to the backend as long as there is clean interface defined. Spring MVC Controller, can be made of POJO, thanks the magic of annotation, that is ideal for testing; yet is still so flexible, that can access HttpServlet objects if necessary, makes it a powerful tool. The View, mainly made of jsp, while Model, need additional tuning to match the view. In this project, a few model objects, which represent a portion of the entity objects, are created to match the view requirement. In some case, the POJO entity object can be used as model object directly credit to not having platform dependency in those classes.


Since this article is mainly focus on the configuration as well as development practice, UI code is omit here. Main codes are the two controller files: StoreController.java and ReportController.java


Key configuration files need to be mentioned are: web.xml, which is pretty standard to all Spring web application, and the default servlet mapping file, springdemo-servlet.xml, that defines view resolver as well as annotation configuration.


POJO controller can be tested by its own just like the above test of DAO DI.


Let’s put all three components together, deploy Spring container inside Tomcat web server, and run the test from the UI. Exception was thrown complaining “No Hibernate Session” in “non-transactional” process. What is wrong? Remember in DAO we delegate the transaction handle to the caller while in unit tests, I add transaction management either programmatically or declaratively so no complains. In this latest integrated test, from the web module to service layer, explicitly declarative transaction management is required. All methods in I_OrderFunction are decorated with @Transactional solves the problem.


I_OrderFunction.java Now the annotations make sense.



Previous    Next

Spring EYE on JAVA EE - 6

Now continue with the function façade. Spring strongly promote code to interface concept. Interface I_OrderFunction was created along with the implementing class OrderFunctionImp.java. I can presumably certain that the required DAO object will be there thanks for the IoC or DI, the magic of Spring. Unit test is similar to the above one.


I_OrderFunction.java Ignore the annotation for now.




And OrderFunctionImp.java




Need to modify the spring configuration file by adding the following cause now we are dealing with full entity hierarchy. OrderItem is not needed cause it has composition relationship with Order, means can not exists without Order. Therefore no need for its own DAO.




Previous    Next

Spring EYE on JAVA EE - 5

Up to now, I have not touched Spring framework. It is time to first experience the power of IoC or DI. In the next section I will focus on the product order functionalities while leave the report functionalities till later purposely.


We can first experience this by creating an integrated Unit Test to see how Spring DI works. SpringDIProductDAOTest.java is created for this purpose. HibernateProductDAO is annotated as @Autowired, means it will rely on the Spring framework to provide this depended object at run time. Thanks Spring for the provided abstract testing class, my unit test can specify the testing context without the deployment of the full blow Spring framework. @Transactional is another great feather in Spring, the declarative transaction management, thanks for Spring AOP.


spirngDemoContext.xml, the Spring configuration file need to be adjusted to embed hibernate, datasource, and transaction handling.




SpringDIProductDAOTest.java




Previous    Next

Spring EYE on JAVA EE - 4

Once we have the basic entities ready, it is time to think about persist them into database. Among all five entity classes, Report.java is different cause it defines all two Report as static instances. The rest four will need to map to table. In this demonstration, I am going to apply Hibernate as the ORM tool for its popularity and reliability. HSQLDB is used as an in-memory database support. Start HSQLDB in another window/cmd prompt, create necessary table. Create hibernate configuration file to properly match the data source while takes advantage of the latest hibernate annotation.


hibernate.cfg.xml Now all the annotation tags in Product.java start to make sense.



As a common Java EE approach, Data Access Object (DAO) is created to bridge the calls. Notice all DAO calls do not explicitly handle transaction. It is expected that the caller will handle it.


HibernateProductDAO.java





Now it is testing time again. Testing hibernate DAO will be slightly tricky mainly for test class has to instantiate Hibernate SessionFactory programmatically.


HibernateProductDAOTest.java




Previous    Next

Spring EYE on JAVA EE - 3

Notice the similarity of unit test class among most entity classes, it is a good time to refactor this similarity into a more robust test class. EntityTest.java is the result. Retest all unit test.


EntityTest.java




Now the ProductTest.java can be rewritten in such a clean way. Only thing left for individual entity test is to properly set the object to be tested.


ProductTest.java




The above process represents a mini-serious of develop-test-refactor cycle, and it will be followed in the subsequent development.



Previous    Next

Friday, March 5, 2010

Spring EYE on JAVA EE - 2

Simple and Straightforward? Let’s start the fun of real coding.


Before we put in the first line, we need to mention a little about the environment. I set the project structure as following. Most are self-explaining while the web part followings Java EE standard. One thing need to be pointed out is that most of the configuration files are saved under config folder while the folder itself is added in the classpath.




Currently all Java EE platform claims to be full Object Oriented but when put in practice there is always debate of the pure business model vs. platform specific implementation. And comprise has to be made in between. Spring’s approach of POJO returns back to basic, makes it possible to model business in a complete Object Oriented way without concerns of platform limitation.


Five entity class created, exactly follow the class diagram.


Product.java Ignore the annotation for now. Although to make it simple, spec says no need to add/remove product, functions still build in.



Now it is time for testing. I am a strong believer of unit test, though have some doubt against TDD, for TDD in practice some times be put ahead of modeling. Anyway, by taking advantage of Annotation driven JUnit test suit, junit-4.4, testing is straightforward. OrderTest.java indicates a typical unit test class.


ProudctTest.java



Previous    Next

Spring EYE on JAVA EE - 1

EYE on JAVA EE: Spring’s Practical Example for Enterprise Application



Source Code with no library jars. Build works in Eclipse env. Require separate Tomcat Installation.



Spring, as a lightweight Java EE framework, offers a number of unique advantages, provides a one-stop-shop solution for all your programming needs from prototyping to full-scale production. The DI (Dependency Injection) feature significantly reduces the coupling among programming components, and promotes coding to interface concept in practice. POJO avoid all cumbersome platform dependent imports, greatly improves the testability. MVC offers clean separation among different roles, provide customizable binding and validation, while maintain the pluggability of other platform (like Struts). AOP makes declarative transaction management possible. Spring support of RMI, and JMS etc. makes distributed computing straightforward. All in all, Spring offers a complete support for most enterprise application development.


In this article, I will focus on a handful of most commonly used Spring features by developing a small electronic store application. It shows how different Spring components work and how easy to put them all work together.


First let’s go though the store specification. Since it is for demonstration purpose, the specification has been stripped down to the bare minimum.


The store sells exactly nine computer parts include computer, monitor, and SD cards. For each part, there is a threshold number, indicates the price adjustment if the order quantity is above this number. For example, for a computer – desktop PC, the regular price is $349. But when ordering more than five, the sixth one will be priced as $299. Multiple computer parts can be combined into one order.


In addition, the store offers two reports: one is how much total is sold within a certain period of time. The second one is how much total is sold for one particular computer part within a certain period of time.


The class diagram for the Order, OrderItem, Product, Report and Report Instance:




The UI for Add Product in Order Cart:




Make Order:




Request Report:




Browse Completed Reports:




Next