Sunday, February 10, 2013

How to: scan interfaces in a custom Spring namespace

This article does not aim to address how to build a custom Spring namespace, to do so, Spring documentation integrates Extensible XML authoring. But a way to create a proxy based on a interface.
My first idea was to use Spring component-scan to find my annotated interfaces, and to proxy it via a BeanPostProcessor or something similar, but it cannot works because component-scan can only be used to load implementations and BeanPostProcessor as well.
As I'm using a custom namespace, so a parser, I made some research through Spring namespace elements and I found the attribute: base-package. And one of its associated class: ClassPathScanningCandidateComponentProvider. By extending this class, my annotated interfaces can be found, and the parser will be in charge to create the proxy around these interfaces.
The scanner implementation is quiet simple:

static class MyAnnotComponentProvider extends ClassPathScanningCandidateComponentProvider {

        public MyAnnotComponentProvider() {
            super(false);

            addIncludeFilter(new AnnotationTypeFilter(MyAnnot.class, false));
        }

        @Override
        protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
            return beanDefinition.getMetadata().isInterface();
        }
    }

  1. The constructor defines a scanner without any filter by calling the super constructor with false
  2. Add a filter on the annotation to found in the classpath by using AnnotationTypeFilter. The second argument specifies only the search must include meta annotation or not.
  3. Based on the BeanDefinition, isCandidateComponent must must check if the found bean is elligible
Next, use it as follow:

ClassPathScanningCandidateComponentProvider componentProvider = new MyAnnotComponentProvider();
componentProvider.setResourceLoader(parserContext.getReaderContext().getResourceLoader());

final String basePackage = element.getAttribute("base-package");
Set < BeanDefinition > beans = componentProvider.findCandidateComponents(basePackage);
  1. Instanciate the scanner, and give it a ResourceLoader. In a Spring XML parser, it can be reached by ParserContext
  2. Get the package to parse by, for example, get the value of the base-package attribute
  3. Call the method findCandidateComponents to get a Set of BeanDefinition.

Saturday, February 4, 2012

Browser cache, Flex and Maven

A current issue with web application, is the browser cache.

For usual HTML based application, add some meta data is enough:

<meta equiv="CACHE-CONTROL" content="NO-CACHE">
<meta http-equiv="EXPIRES" content="Mon, 01 Jan 1970 00:00:01 GMT">

But with Flex application, it is not so simple.

Flex application are usually wrapped in HTML that allows to detect with the right Flash Player is installed. And if it is not the case, downloading and installing it.

The issue is the Flex SWF name that is specified in the HTML wrapper, makes that browsers put Flex application in cache and don’t reload it.

In the following explanations, the example is a Maven project with a module for the Flex application (using FlexMojos), and a module for the web application.

In the Flex module, the produced SWF file name must be variable, for example, by adding the current version. It is done by giving the final name of the SWF.

In build section, provide the finalName:

<project >
<groupId>my.app</groupId>
<artifactId>myapp-flex-client</artifactId>
<packaging>swf</packaging>
<build>
<finalName>MyFlexApp-${parent.version}</finalName>
<sourceDirectory>src/main/flex</sourceDirectory>
<testSourceDirectory>src/test/flex</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<configuration>
<sourceFile>MyApplication.mxml</sourceFile>
</configuration>
</plugin>
</plugins>
</build>

In the web application, we have to inject the SWF name in the HTML wrapper.

It is done by adding the wrapper goal to Flexmojos plugin.

<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>${flex.mojos.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>wrapper</goal>
<goal>copy-flex-resources</goal>
</goals>
</execution>
</executions>

Adding it, implies to configure it directly in the plugin. The configuration must contains the artefact to wrap (the Flex application) and the name of the wrapper.

<configuration>
<wrapperArtifact>
<groupId>my.app</groupId>
<artifactId>myapp-flex-client</artifactId>
</wrapperArtifact>
<swf>{build.finalName}</swf>
<htmlName>flashClientWrapper.html</htmlName>
</configuration>

The element defines a variable that is injected in the HTML file. Now, it only remains replace the SWF file name in the wrapper by: ${swf}

Tuesday, May 17, 2011

Annotation scanner with Spring

Spring framework, from version 2.5, can retrieve bean based on an annotation set such as @Service, @Repository. This mechanism uses an annotation scanner to retrieve the annotated classes through the classpath.

As Spring is easily extendable, it is possible to work with an annotation scanner dedicated to our own annotations.

The annotation

The annotation we want to use as a class marker, is not a psecial Spring define one. The only requirement is the retention must be runtime and the target must be at least TYPE.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation { }

The scanner

Firstly, we need to create an application context:

GenericApplicationContect applicationContext = new GenericApplicationContext();

And now, the annotation scanner:

ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(applicationContext, false);

An annotation scanner needs an application context to store retrieved classes. The second parameter is used to avoid this scanner search after Spring framework defined annotations. Now, we must configure the scanner to retrieve only our annotation:

scanner.addIncludeFilter(new AnnotationTypeFilter(MyAnnotation.class));

Several filters are available to include or exclude classes from the search, such as RegexPatternTypeFilter.

To trigger the scanning, we must call scan method with a package list as string array:

scanner.scan(packageNames);

Now, just refresh the context and get the annotated instance:

applicationContext.refresh();
Map<String, Object> result = applicationContext.getBeansWithAnnotation(MyAnnotation.class);

The map key is the bean Spring id, and the value is an instance. By default, the id is the simple class name.

Thursday, March 3, 2011

Parameterized Unit Tests

Recently, I have to write a unit test to check link reference validity in static HTML pages. The problem is: how to run test for each URL, without hard coded HTML files location (what append if several files are added ;) and with a minimum of code. The answer is provided by JUnit itself. From version 4, parameterized tests are included: it is a runner that is able to get a collection of values and to execute a test for each of these values.

A parameterized test looks as following:

@RunWith(Parameterized.class)
public class ParamTest {

private String msg;

public ParamTest(String msg) {
this.msg = msg;
}

@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {{"first"}, {"second"}, {"third"}});
}

@Test
public void test(){
System.out.println(msg);
}

}

To get a parameterized test, it has to declare a specific runner with: @RunWith(Parameterized.class). And a static method that return a Collection<Object[]>. By this way, several arguments can be passed. This method must be annotated with @Parameters that declares the method as a parameters provider. A constructor with all arguments as parameters must be written. Then runner will execute the parameters method provider, and for each value, it creates an instance of the test and execute it. So, to use parameters, the constructor can save them as class attributes.

The result is:

first
second
third

Parameterized tests mechanism brings a simple and ellegant way to test things that are not fix.

Sunday, February 13, 2011

Emulate a non supported class in GWT

To develop with GWT, only a Java SDK subset is available, plus GWT specific classes. Mainly (look at JRE emulation for details):

  • java.lang
  • java.lang.annotation
  • java.util
  • java.io
  • java.sql

This emulation mechanism is used to bypass GWT limitations, such as, no reflection due to the JavaScript translation.

As GWT support only a few JDK classes, as developers, we often miss something to do the work. To fill the gap, it is easy to use emulation to implement a full GWT compliant class. To do so, the best practice is to create a directory out of the class path named super, that will contain the emulations. The name of this directory has no importance, it is just done that way in GWT sources. Your package structure takes place under this directory. At this place, a module must be created, it contains only a super-source directive as following:

<super-source path="source_location"/>

path attribute provides the root directory of simulated classes. For example, to simulate a class from package java.io:

The reason to not include emulated classes in classpath, is, these classes must declare the package name from the class they emulate, not the package previously defined:

package java.io;

Now, to use these classes, you should only inherits from the emulation module.

Thursday, December 2, 2010

Devoxx 2010 daily notes: day five

Apache Camel, a powerful open source integration framework

Apache Camel is a parent of ServiceMix and Active MQ. The project has been initiated as a routing library.

Why integration?

  • different stack technology
  • business need

This integration framework is:

  • based on Enterprise integration patterns
  • includes 50 patterns
  • 80 components for connecting to other systems
  • 19 data format for transformation
  • 14 expression languages
  • DSL in three languages: XML, Java and Scala
  • security integration
  • event notification
  • route policy
  • threading model (non blocking routing engine)
  • heavy lift
  • focus on business
  • famous pattern-context based router

Tooling is available for IDE.

The roots of Java EE 6: JSR-299 (CDI) and Weld extensions

Weld (reference implementation) is available in servlet container, it implements CDI.

JSR-299 provides:

  • services for Java EE
    • life cycle management for context
    • type safe dependency injection
    • event notification
    • reduce coupling beans/interceptors
    • decorators intercepting beans (AOP)
    • EL integration
  • extension SPI

Available extensions:

  • hooks on container starting
  • hooks JEE transaction boundaries

Definition by XML is available.

Friday, November 19, 2010

Devoxx 2010 daily notes: day four

Java EE Key Note: The Future Roadmap of Java EE

Java EE wil evolved to cloud platform and, to do so, it will needs modularity based on Java SE.

JSF 2.1

JSF 2.1 will propose:

  • transient state saving
  • XML view cleaning
  • targeted to HTML 5

JMS

JMS is an old specification, which need to evelove for addressing new communication layers:

  • resolving specification ambiguities
  • standardized vendor extension
  • integration with other specifications
  • integration with the web tier (websocket, JSON, NIO2)

JPA 2.1

JPA targets to improve standardization, flexibility and control of persistence context synchronization. The metamodel will be extended to ORM.

Several addition will take place in this release:

  • add event listener
  • outer join with ON conditions
  • update and delete query based
  • mapping between JPQL and criteria queries
  • DB and vendor function invocation
  • support stored procedure

The expert group will be done for january 2011, but the release date could be delay by J2EE timeline (modularity is waiting for Java SE 8).

JAX-RS

JAX-RS 2.0 should be commited in december.

Actually, JAX-RS specification is not included into web profile.

A client API will be added:

  • low level builder pattern
  • high level response matching

JAX-RS will be adapted for MVC architecture based on JSP and Scalate.

Asynchronous, base on Atmosphere (HTTP streaming), will be too added with validation and injection. For exeample, @Context will be replaced by @Inject).

Comparing JVM Web Frameworks

In 2004, criteria to choose a web framework were:

  • request, component or RIA
  • stateful or stateless
  • project community
  • project futur
  • maintenance
  • technical features

And the choice could be described this way:

  • High traffic: request framework
  • Intranet: component
  • Products: products vendor

Now, in 2010, criteria are:

  • development productivity
  • developer perception
  • learning curve
  • project health
  • developer availability
  • job trends
  • templating
  • components
  • ajax
  • plugin
  • scalability
  • REST support
  • multi language
  • validation
  • books
  • doc
  • mobile
  • risk

After a comparison, to top five is:

  • Spring MVC (pro: configuration, integrtion, REST support; cons: instant reload)
  • GWT (pro: write in Java, easy to learn; cons: slow compilation)
  • Rails (pro: easy to learn, doc; con: performance, development tools)
  • Grails (pro: esay for Java programmers; cons: targeted to Java programmers)
  • Wiket (pro: for Java developpers; cons: no developpers available)

Standard DI with @Inject and JSR-330

CDI is a joined proposition from Google and Spring. It is resumed by five annotations and one interface.

@Inject identifies injectable members, that can be any visible fields (static or instance).

Injection order is:

  1. constructor
  2. fields
  3. methods

By default each time an injection must be done, a new instance is created.

@Qualifier allows to solve naming ambiguities by providing a way to create annotation to qualify a classe.

Interface Provide is a kind of factory where injection is not enough to create an object.

Guice and Spring Framework implements this JSR.

The Java Persistence Criteria API

JPA started with JPQL, a SQL like query language that can be used in static queries (@NamedQuery) and dynamic queries.

JPQL for dynamic query is:

  • String based: very easy to do
  • SQL like syntax
  • But it is String: risk of performance lost, lost of readability
  • No type safety

Criteria API is object based and typesafe (use of a metamodel).

CriteriaQuery are composite:

  • roots
  • join
  • expression
  • predicates
  • selections
  • ordering
  • grouping
  • method to assign: select(), multiselect(), from()
  • browse result: getSingleResult()

CriteriaBuilder: a factory of CriteriaBuilder for Expression and Predicate:

select c from Customer c;

TypedQuery tq = em.createQuery(Customer);

List resultList = tq.getResultList();

  • join -> root.join("orders");
  • where -> cq.where(cb.equal(root.get("...")).select(root)

There is hole in type safety in join and where: usage of string to specify attribute name.

The solution used by JPA is to generate at compile time a static metamodel (logical view).

Directly accessible via EntityManager.getMetamodel(), it is defined by a hierarchy of interfaces to describes types and attributes. So, browsing the metamodel is possible.

Now, it is possible to replace String in criteria by metamodel attribute or by accessing directly to the metamodel (path navigation).

Path navigation brings tha ability to access attributes of composite object: c.get(attribute_a).get(attribute_b). It is used to compound predicates.

CriteriaQuey is able to create subqueries and to call database specific function: cb.function("NAME", return_type, path);

Criteria parameters are created by using CriteriaBuilder and can be named.

Queries are modifiable.

HTML 5 Fact and Fiction

HTML 5 is mainly a collection of features.

It is actually better supported on mobile devices than on desktop.

HTML 5 is driven by mobile development. Developping a native application for each platform is too cheaper, we need a common platform, and this the web.

Feature detection can be done with Javascript and preferably by using library such as Modernizr.

Now, browser evolution is driven by specification. This can avoid a quirck mode where standard is more or less respected. HTML header file becomes:

HTML brings very feww components. So, developers uses external library, but there is no standard. HTML 5 comes with new input types. If they are not yet supported by browser, a text field is displayed. One of the target of such component is to brings facilities to mobile devices. For example, an email input field results to the @ symbol to be directly available on the keyboard.

It defines too things that are used from decades such as headers and footers.

It brings too:

  • autofocus
  • local storage: response to heavy cookie usage
  • offline mode: cache the application
  • microdata: semantic web
  • multithreading
  • geolocation (not part of HTML 5)

Activiti in Action

Activiti is a BPM open source tool , it is now mainly developed by Alfresco, but these are 2 distinct products, it is supported by SpringSource and Signavio. Activiti is based on the BPMN 2.0 standard, and the data can be persisted in an XML format.

Activiti allows you to model a process in BPMN 2.0 using “Activiti modeler” (from Signavio), or via an eclipse-based interface. At each step of the process, you can define who can execute the task, and define what are the information that should be filled in. Afterwards, you can initiate process instances, and each person involved will have access to the “activiti explorer” where he will have the possibility to fill in the required information. Once a process step is completed, activity notifies the next person involved that he has a task to do. The “activiti explorer” also provides analysts with process instances status and statistics (it is also possible to create easily a BIRT report about process instances report).

Activiti also provides other modules:

  • Activiti Probe (check process status)
  • Activiti Cycle (BPM collaboration platform)
  • iPhone client
  • Grails integration

Finally, Activiti is highly customizable and can be easily embedded into another application (you can, for instance, request to add a document into Alfresco at a particular process step using 5 lines of Java code …)

  • SpringSource provides an integration via a bean
  • A full query API provides access to the Activiti data
  • REST interface provided (used by an iPhone application