Tuesday, July 27, 2010

Java Web applications debugging

When debugging Java Web applications I always use remote port debugging. I like my server running out of my IDE, that is all. Separation of concerns is to be applied here *again*.

I try to use port 8787 if it is available and then I setup my IDE to connect to it.

Tomcat Windows

Add a setenv.sh file with the below content. I am adding extra Perm Space memory and that part is irrelevant BTW:

SET JAVA_OPTS=%JAVA_OPTS% -XX:MaxPermSize=256M -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n

Monday, July 26, 2010

Deploying from Maven

Here is a tip that saves a lot of time when developing web applications in Java. I find myself teaching this again and again every so often and so I decided to make it a blog port.

To build and deploy from maven I use the below maven snippet:

...
<properties>
<tomcat.deploy.dir>${env.MVN_TOMCAT_HOME_DEPLOY}</tomcat.deploy.dir>
</properties>
...
<profiles>
<profile>
<id>dev-tomcat-deploy-webapp</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>e1</id>
<phase>process-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo
message="Copying from ${basedir}/src/main/webapp to ${tomcat.deploy.dir}/${pom.build.finalName}" />
<copy todir="${tomcat.deploy.dir}/${pom.build.finalName}">
<fileset includes="**/*.*" dir="${basedir}/src/main/webapp" />
</copy>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>dev-tomcat-deploy-war</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>e1</id>
<phase>install</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Deploying WAR locally</echo>
<copy todir="${tomcat.deploy.dir}" file="target/${pom.build.finalName}.war" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>


I have not tested this in Windows but probably with the help of cygwin or any other other *nix for windows ports you might be able to use it.

First be sure you have the target deployment directory configured as an environment variable.

#vi ~/.profile
export MVN_TOMCAT_HOME_DEPLOY=/Users/nestor/apache-tomcat-6.0.28/webapps


You can use the below command to build and deploy in tomcat from one command:

mvn clean install -Pdev-tomcat-deploy-war antrun:run


You can use the below command just to deploy the webapp content of your web application. This means you just get changes in creatives or JSP files for example. Of course this accelerates your development (No new rebuild, no new redeployment, no session lost) BTW only new files will be copied.

mvn process-resources -Pdev-tomcat-deploy-webapp antrun:run

Bhub: building a Business Hub

I have come across this term after long discussions with some coworkers in the last 5 years. As I study business necessities, create architectures and work together with developers on the implementations I am now so convinced about the power of this solution that I feel the need to share my experience.

A Business Hub (BHub) is an entry point to your business services. It is just the MVC pattern applied rigorously. BHub services are not necessarily SOA and actually in my implementations far away from SOAP. The services in a company are entities that accept input variables and provide output variables similar to what a quadripole* does.

Such a simple concept. What do you do with the output variables? Of course you use them. In Web development most likely you will use them from a Controller that later will use a View to render some kind of markup (site HTML). Of course you will use sometimes JSON or XML from Javascript, CSV from Excel and the list goes on.

In a BHub your Controller acts as a quadripole as well. It is in charge of processing input variables which might come the REST, XML-RPC, SOAP (you name it) way. It is again in charge of generating output variables (In a Java world just request attributes).

In a BHub your View decides how to format the response variables. The same entry point to your business services, the very same logic is applied, the same response variables are generated but the final result depends on the consumer: PC, home appliance, a partner application, mobile devices, spreadsheets, email, printer and more.

Flow or user states of course are reused as well. No matter if you use add-hoc code, Drools, JBPM, or custom Rules Engine your stateless controllers will become stateful at some point but that should never affect the final result.

BHub is MVC with an important statement, the architecture must be View agnostic.

So next time you pick your framework be sure you can configure it to get your BHub up and running with minimum effort. You will have no problems exposing business logic at any possible level.

* Thanks to Hector Gessa, my scientist friend, for the quadripole analogy.

Thursday, July 15, 2010

Liferay refactoring: Moving existing extension to plugin SDK portlets

Yes I know it is frustrating. You want to keep your code separated in different WAR files containing individual portlets (Plugin SDK programming) but at the same time you want to reuse lots of lines of code that Liferay team already took care of.

You realize very fast that most of the amazing amount of code ready to be used is actually buried in the portal code in a way that to reuse it most of the people will be forced to use the extension environment.

Well, the good news is that with some effort the migration from extension environment to plugin SDK is actually just a matter of some tweaking.

The steps below are just theory. For the stuff working just checkout the maven project, deploy it in Liferay and look for "Update Password" portlet from "Add application". You will get a form to change the user password.

The "My Account" portlet comes with a functionality called "Update Password". I will show how to use the same functionality from a plugin SDK portlet.

1. Create a typical plugin SDK Portlet scaffold. You can go the extra mile and get it as a Maven project. It is just a simple Maven JSP Portlet scaffold project in case you are following this instructions to migrate another extension environment portlet, for example would you help me get the Detail portlet (also known as user Profile which is part of the "My Account" portlet as well)? ;-)
2. Identify which JSP liferay is using to provide the functionality you want. For example you want the "Change Password" or better said "Update Password" functionality. The JSP involved in that GUI is update_password.jsp
3. Copy the JSP code from ~/liferay/src/portal-web/docroot/html/portal/update_password.jsp and include it as your view.
4. Resolve dependencies, inclusions (imports). An IDE is a must have for this part.
5. Test the functionality. While it might compile out of the box the functionality might be broken. For the case of the update_password.jsp for example it uses a Struts action that we will reuse. The code sets via the SessionErrors object some attributes in the Servlet session which are not available from the Portlet session. To get them exposed you will need to change your friend portal-ext.properties. In my local machine:

#vi ~/liferay/ext/ext-impl/src/portal-ext.properties
...
session.shared.attributes=org.apache.struts.action.LOCALE,COMPANY_,USER_,LIFERAY_SHARED_,com.liferay.portal.kernel.servlet.SessionErrors
...



I hope this post will promote the migration of many other portlets to the plugin SDK environment.

Monday, July 12, 2010

Spring3 and the departure from CoC

Almost two years have passed since I documented a simple way to get Convention Over Configuration (CoC) while using Spring.

Since then I built a nice Framework where developers could just concentrate on implementing Controller logic, reusable services and DAOs.

A new project has come to my plate and a new team eager to use the latest from Spring (Spring 3). I would love to be wrong but Spring3 is favoring the use of annotations for URL/Controller Mapping and my simple GreetingController will not longer work with ControllerClassNameHandlerMapping

So now my Controller will need to repeat himself === not agile (Note I tested this with the Spring3 Petclinic example):

package org.springframework.samples.petclinic.web;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.stereotype.Controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
public class GreetingController {

@RequestMapping("/greeting/hi")
public ModelAndView hi(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
ModelAndView mav = new ModelAndView("messageView");
mav.addObject("message", "Hi");
return mav;
}

@RequestMapping("/greeting/hello")
public ModelAndView hello(HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView("messageView");
mav.addObject("message", "Hello");
return mav;
}
}

IMHO if it says it is a controller and it has public methods that should be enough so it is missing a default (and very useful) implementation. If it walks like a duck it must be then a duck.

Followers