Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

05/10/2011

Builder Pattern Usage: Rule of Thumb

Builder Pattern is a creational design pattern. It is good in:

  1. Creating complex immutable objects
  2. Preventing objects being created to be used before initialization is complete.

Complex Immutable Objects

It's important that object being created should be Complex enough and Immutable. Overwise it may be an overkill to use a Builder for simple cases.

  • If object is not complex enough — you may use more simple ways of creating new object, e.g. use static factory method.
  • If object is not immutable — use setter methods

What kind of object are complex? Much depends on context, of course. But if object has less than than 2-3 constructor parameters is unlikely to be complex enough to use the Builder. I.e, if object can be created with factory method with up to 3 parameters, than object is simple and using Builder pattern is overkill.

One more pattern should be recalled here is Value Object or Data Transfer Object (DTO). Value objects or DTOs may be passed as a constructor parameters to simplify object creation.

Preventing early object access

Builder may be used to create an object which should not be used unless fully initialized. Initializing object using setter methods does not prevent client from calling other object business methods. To handle this incomplete state correctly you normally should perform object state check in the beginning of every business method and throw IllegalStateException... or just prevent object to be created in inconsistent state. One of the way to to this it is to use Builder. But anyway, you should check if all the parameters are initialized inside builder.build() method or inside object constructor:

import org.apache.commons.lang3.Validate;
public class PingResponseBuilder {
    private String serverName;
    private long timestamp;

    public void setServerName(String name) {
        this.serverName = name;
    }

    public void setTimestamp(long millis) {
        this.timestamp = millis;
    }

    private void validate() {
        Validate.notBlank(serverName, "The serverName must not be blank");
        Validate.isTrue(timestamp>0, "The timestamp must be greater than zero: %s", timestamp);
    }

    public PingResponse build() {
        validate();
        return new PingResponse(serverName, timestamp);        
    }
} 

Please keep in mind, that although memory is cheap and processors are fast, creating the new Builder instance for every created object instance is not very efficient. You may re-use single builder object (in a thread-safe manner!!!) for creating multiple object instances by setting differing properties, e.g.:

PingResponseBuilder builder = new PingResponseBuilder();
builder.setServerName("A Test Server");
...
PingResponse firstResponse = builder.setTimestamp(System.currentTimeMillis()).build();
...
PingResponse nextResponse = builder.setTimestamp(System.currentTimeMillis()).build();

22/07/2010

GWT is about to add Native JSON function support in version 2.1

GWT 2.1 has reached Milestone 2.

One of the new features in version 2.1 is support for browser's native JSON function in JSONParser class. More...

30/06/2010

Upgrading to Spring 3: "Unable to locate Spring NamespaceHandler" in JAR file built by Maven

After upgrading to Spring 3 your may discover that your application packaged in JAR archive does not start any more throwing an exception like this:

"Unable to locate Spring NamespaceHandler for XML schema namespace[http://www.springframework.org/schema/tx]"

This happens when you include multiple Spring module dependencies in your pom.xml file and use Maven Shade or Assembly plugin to build a single JAR.
Since Spring can does not contain a single distribution jar (org.springframework:spring:jar), Spring namespace handlers, schema mappings and tooling information files are now present in multiple files with names:

  • META-INF/spring.handlers
  • META-INF/spring.schemas
  • META-INF/spring.tooling

In order to make it work in a single shaded JAR you need to merge contents of these files from different jars and place merged files into new JAR. More...

30/01/2009

How to Lookup JBoss MBean Server from Spring (JMX)

If you having problems accessing "mbeanServer" Spring-managed bean under JBoss Application server Read more...

29/01/2009

How to Use Spring from EJB3

This is a short instruction how to inject a spring-managed bean into EJB3 component.

  1. Read SpringFratamework's reference here: http://static.springframework.org/spring/docs/2.5.x/reference/ejb.html#ejb-implementation-ejb3

  2. Place to ejb module's classpath a file beanRefContext.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>

    <bean id="myBeanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
    <constructor-arg value="myApplicationContext.xml"/>
    </bean>

    </beans>

  3. Create application context file named myApplicationContext.xml and define You beans there. Place this file to the ejb module's classpath.

  4. Annotate your Stateless Session Bean:
    @Stateless
    @Interceptors(org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor.class)
    public class MyFacadeBean implements MyFacade {

    @Autowired
    private MySpringComponent component;
    ...
    public void foo() {
    component.foo();//invocation
    }
    }

  5. Deploy and test Your application.

27/01/2009

How To Export Spring Managed Bean To JNDI

Sometimes, it is necessary to export a spring managed bean to JNDI context. Here I want to show how do it.

In spring, there is a bean that provides a similar functionality for exporting to MBean server: MBeanExporter. Unfortunately, there is no standard JNDI bean exporter implementation in spring (current version is 2.5.6) - (Why?).
But it's easy to write it youself:
package com.example.spring.jndi.export;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jndi.JndiTemplate;

public class JndiExporter implements InitializingBean, DisposableBean {

private String jndiName;

private Object bean;

private final JndiTemplate jndiTemplate = new JndiTemplate();

public String getJndiName() {
return jndiName;
}

public void setJndiName(String jndiName) {

this.jndiName = jndiName;
}

public Object getBean() {
return bean;
}

public void setBean(Object bean) {
this.bean = bean;
}


public void afterPropertiesSet() throws Exception {
jndiTemplate.bind(jndiName, bean);
}

public void destroy() throws Exception {
if (bean != null && jndiName != null && bean == jndiTemplate.lookup(jndiName)) {
jndiTemplate.unbind(jndiName);
}
}
}

Add following fragment to spring configuration file:
<bean id="myBean" class="com.example.MyBean"/>

<bean class="com.example.spring.jndi.export.JndiExporter">
<property name="bean" ref="myBean" />
<property name="jndiName" value="MyJNDIName"/>
</bean>
Don't forget to make your bean serializable by implementing java.io.Serializable interface.
Now we can lookup exported bean by adding to the spring config fil:
<jee:jndi-lookup id="myJndiBean" jndi-name="MyJNDIName" proxy-interface="com.example.IMyBean" lookup-on-startup="false"/>

That's all, folks!

02/01/2009

Use BigDecimals for Financial Calculations: One More Example

Recently I was asked about the preferred data type in java application dealing with financial data. I suggest using of BigDecimal and here is the example why. Let's perform following arithmetic operations over double values, double values with strictfp mode enabled and over BigDecimals.

Expression is: "0.999/9 - 0.112"
Expected result is: "-0.001"

Java code:
import java.math.BigDecimal;

public class FloationPointTest {

public strictfp static void testStrictfp() {
System.out.println("strictfp: 0.999/9-0.112 = " + (0.999/9-0.112));
}

public static void main(String ... args) {
System.out.println("double: 0.999/9-0.112 = " + (0.999/9-0.112));
testStrictfp();
System.out.println("BigDecimal: 0.999/9-0.112 = " + (new BigDecimal("0.999").divide(new BigDecimal("9")).subtract(new BigDecimal("0.112"))));
}
}

Program output:
double: 0.999/9-0.112 = -0.0010000000000000009
strictfp: 0.999/9-0.112 = -0.0010000000000000009
BigDecimal: 0.999/9-0.112 = -0.001

We see that only operations with BigDecimal does not lead to the lost of precision. Performing operation over values of type double even in strictfp mode may loose accuracy. It is not acceptable for financial calculations in the days of Global financial crisis.

02/12/2008

Proxy Method Resolving Order

I noticed interesting behavior of method resolving order, which reflects interface order in java.lang.reflect.Proxy.newProxyInstance(...) call. It fact, it is described in Sun's java guide: Dynamic Proxy Classes: Methods Duplicated in Multiple Proxy Interfaces

Supose, there are two interfaces (A and B) with same signature and we have created a proxy that implements this interface in order {A,B}.

When we cast a proxy to class A and invoke it's method, the InvocationHandler says that we invoke a method from interface A (as expected).

But when we cast a proxy to class B and invoke it's method, the InvocationHandler says that we invoke a method from interface A again! Here I'd expect the InvocationHandler will say that we invoking a method of interface B and it's strange for me.

Order of appearing interfaces in proxy instance factory method does matter. Following program demonstrates it:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class ProxyMethod {

interface A {
void doSomething();
}

interface B {
void doSomething();
}

static class EchoHandler implements InvocationHandler {

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method = " + method);
return null;
}
}

public static void main(String[] args) {
Object proxy1 = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class[]{B.class, A.class},// The difference
new EchoHandler());

Object proxy2 = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class[]{A.class, B.class},// The difference
new EchoHandler());

System.out.println("\nproxy1 intfs = " + Arrays.asList(proxy1.getClass().getInterfaces()));
((A) proxy1).doSomething();
((B) proxy1).doSomething();

System.out.println("\nproxy2 intfs = " + Arrays.asList(proxy2.getClass().getInterfaces()));
((A) proxy2).doSomething();
((B) proxy2).doSomething();
}
}

Returns following result:

proxy1 intfs = [interface ProxyMethod$B, interface ProxyMethod$A]
method = public abstract void ProxyMethod$B.doSomething()
method = public abstract void ProxyMethod$B.doSomething()

proxy2 intfs = [interface ProxyMethod$A, interface ProxyMethod$B]
method = public abstract void ProxyMethod$A.doSomething()
method = public abstract void ProxyMethod$A.doSomething()

This behavior allows to build object wrapper as dynamic proxies easily. Interface of the object being wrapped should be passed first to the proxy factory method. So, if methods of the wrapped object's interface is passed to the invocation handler - just invoke them on a wrapped objects. Other methods should be handled differently by invocation handler.

26/03/2008

WebService Authentication under JBoss

In my business project there is a need to check declarative security within EJB3 Session beans exposed as WebServices. The project is deployed under JBoss AS 4.0.5.GA with JBossWS 1.2.0.SP1. After brief investigation, a quick solution was found.

HTTP BASIC Auhtentication with EJB3 Endpoints



Axis client provides HTTP BASIC authentication when invoking web services (see previous article). So, it should be some way to enable it on server side.

For EJB web service endpoints, JBossWS generates and deploys web application, so Session Beans are mapped to Servlets.

Let's look at the example of SLSB exposed as WebService (class HelloIntf, containing missing here @WebService annotations, is generated from WSDL and not listed here):
@javax.ejb.Local(HelloIntf.class)
@javax.ejb.Stateless(name = "HelloPort")
@javax.jws.WebService(endpointInterface = "HelloIntf")
@TransactionManagement
@DeclareRoles({"foo","bar"})
// jboss specific
@org.jboss.ws.annotation.WebContext(
    contextRoot = "/services",
    urlPattern = "/hello",
    authMethod = "BASIC")
public class HelloBean implements HelloIntf {

    @javax.annotation.Resource
    private SessionContext ctx;

    @javax.annotation.security.RolesAllowed({"foo","bar"})
    public String sayHello() {
        return "Hello, " + ctx.getCallerPrincipal();
    }

}


Defined bean will be deployed as http://localhost:8080/services/hello.
Actually, JBossWS generates web.xml by processing annotations. In web.xml following code will be added:
<security-constraint>
<web-resource-collection>
<web-resource-name>HelloPort</web-resource-name>
<url-pattern>/hello</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>EJBServiceEndpointServlet Realm</realm-name>
</login-config>

Unfortunately, the realn name is predefined (hardcoded in JBossWS code) and can not be changed (in JBossWS 1.2.0.SP1), so, we may configure default application-policy called "other" in login-config.xml to meet our needs or to add new application-policy element with name="EJBServiceEndpointServlet Realm" (but the second solution does not works by unknown reason).

09/10/2007

Development Process Guidelines

"You're pirates. Hang the code, and hang the rules.
They're more like guidelines anyway."


I'll try to figure out some configuration and development process guidelines. Don't take it too seriously, it's just a guidelines :-)

Required infrastructure

Following tools and environments must be available:
  1. Issue Tracking system - JIRA or BugZilla
  2. Version Control System [VCS] - Subversion, CVS, etc.
  3. Continuous Integration Tool [CI tool] - Hudson, Continuum etc.
  4. System Test environment exists (dev-box) - for system test by development team (QA team - by request). Available for developers to deploy.
  5. Integration Test environment exists (tst-box) - for QA team. Not available for developers
  6. Pre-Production (user-acceptance) environment exists (uat-box) - visible to end-uses, used by another projects within organization (clients). Maintained by Integrators
  7. Production environment (prod-box) - maintained by Integrators.

Project requirements

Project structure requires following:
  • Each system component should be buildable (build script exists)
  • Each system component should be buildable on the remote machine using CI tool without human intervention (no manual source modifying) by schedule or forced build.

Roles

  • Developer - works with code
  • Builder - prepares the distribution
  • Tester - tests the application
  • Integrator - manages UAT and PROD environments
Single person may share multiple roles

The Process


  1. Builder gets the binaries from the CI Tool and deploys to dev-box environment.
  2. When internal system test passed:
    1. Packages components, deployed to dev-box, into distribution package with build number assigned.
    2. Builder submits the Package to SCM or special folder.
    3. Builder assembles the change list (or marks issues in issue tracking system).
    4. Builder writes deployment instructions (if required)
    5. Builder sends changelist, deployment instructions and reference to the distribution package to the Tester.
  3. Tester gets the package from the Builder and deploys it to Dev-box.
  4. Tester tests changes described in CHANGELIST or from Bug Tracking system as well as the regression tests
  5. If QA test passed:
    1. Tester marks Distribution package as Release Candidate
    2. Developers implement features and fix bugs. All changes are submitted to the VCS[Version Control System]
    3. Tester writes Release Notes for RC.
    4. Tester sends deploys tested package together with release notes to the Integrator
    5. Integrator installs RC version to uat-box. (Integrator learns how to install the new release over existing running system.)
  6. If UAT phase passed
    1. RC version is marked as release version
    2. Integrator installs RC version to the customer's server.
I must have left something important in process.
Comments are welcome ;-)

03/09/2007

Coding java persistence: JPA vs. Hibernate

In my current projects, I deal with database persistence layer. I use Hibernate implementation of the JPA 1.0 API. But restrictions of JPA API limits my ability to use some cool features of Hibernate, including


  1. Full control over cascade behavior;

  2. Indexed collections;

  3. Collections of primitive values.


"Use JPA when possible, and Hibernate extensions where you can't do without" is a reasonable solution, but... It smells.... Anyway, the code becomes not portable enough when using Hibernate extensions. May be, it would be better to skip JPA and relay on Plain Old Hibernate (POH)?



XML Config vs. Annotations: Prons and Cons


JPA and Hibernate both supports XML mapping config and annotation config.


XML does not require to import annotations in entity classes. It makes entities more portable. They stay a simple POJOs, without any extra dependencies. It makes possible to package them in separate jar and include as a dependency in the client tier.


Annotations make mapping config to live together with property declarations in java file. It is more readable to the developer. It make sense when you don't plan to expose your entities outside the persistence module.

24/08/2007

Java Naming Conventions for Sample Project

Java Naming Conventions for Sample Project

Java package naming

  • com.company.project – project-wide package prefix. Should not be used directly.

  • com.company.project.web – web client package prefix


Common packages

  • com.company.project.commons – project-wide common classes, including exceptions

  • com.company.project.commons.util – project-wide gnerial purpose utilities.

  • com.company.project.commons.persistence – common classes retaled to server side persistence (Persistence API 1.0)

  • com.company.project.commons.ws – WebService related utilities.


Sub-system packages

  • com.company.project.<subsystem>.<component> - may contain exceptions

  • domain – contains interfaces, classes and enums related to subsystem's domain model representation.

  • persistence – persistnt entities should be placed here. EJB 2.1 beans too.

  • component – session beans (EJB3) with CRUD logic (managers over persistence tier)

  • util – various service utilities, e.g. DTO assemblers and helpers

  • business – Session beans with complex logic. These classes deals with component layer and may use persistence entities POJOs as Data Transfer Objects (DTO) with lazy loading within a transaction.

  • util – various service utilities, e.g. DTO assemblers and helpers

  • facade – Contains service facades. Serice facades are POJOs (preferrable) or EJB3 session beans which may access business and component layer beans.

    • jaxws – contains JAXWS service implementations.

      • skeletons – contains generated JAXWS interfaces

    • axis – contains AXIS service facade implementations

      • skeletons – contains axis generated skeletons

    • util – various service utilities, e.g. DTO assemblers and helpers

  • client – contains (web) service clients

    • jaxws – contains JAXWS service client.

      • stubs – contains jaxws generated sstubs

    • axis – contains AXIS service client.

      • stubs – contains axis generated stubs


Java class naming

Following conventions should be applied to class naming:

  • Persistent entity should have an «Entity» suffix

  • Session beans should have an interface and implementation: FooManager and FooManagerBean

  • WebServices session bean implementation should be named with suffix FooPortImpl. If it's a session bean – FooPortBean.

  • Factories should have a «Factory» suffix

  • We use the following names for the parts of an entity / session bean:

  1. Enterprise bean class: <name>Bean

  2. Local home interface: <name>Home

  3. Local interface: <name>.

  • Accessor methods of an enterprise bean class should be grouped by field

  • ...





02/03/2007

JBoss Web Services 1.2.0 has been released

There are a lot of issues were closed, but there are still ones that annoys.
For example, abstract complexTypes are not supported: JBWS-1554.

Important note: when using wstools for wsdl2java generation, don't forget to change "file" attribute to "location" in wstools-config.xml. In other case, you'll see NPE while instatiating java.io.File

redirect