Friday, March 23, 2012

Maven Compiler Version from Command Line

Maven 2 default compiler version was 1.3, then for latest releases the default is 1.5. Maven 3 allows to set the compiler just in the parent pom.

Here is how to specify from command line the maven property that will set which compiler to use
$ mvn clean install -Dmaven.compiler.source=1.6 -Dmaven.compiler.target=1.6
This comes in handy especially to avoid errors like:
annotations are not supported in -source 1.3
(use -source 5 or higher to enable annotations)
    @Override public void initialize() {
Of course you can always edit the pom files as below but that would probably not be a good practice when you are not the owner of the project and the team maintaining it is using a different maven/compiler version than yours.
<plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>2.3.2</version>
      <configuration>
        <source>1.6</source> 
        <target>1.6</target>
      </configuration>
    </plugin>

Tuesday, March 13, 2012

Open local file link from chrome

Update 20130918: Chrome now have removed any support but there is a plugin for chrome which would do the trick. Update 20120918: Version "21.0.1180.89 m" for WinXP at least does allow to open local files using file:/// while the drag and drop functionality will result in "about:blank" in the address bar.

Google Chrome takes security seriously as far as I have seen so far. While other browsers will allow to open file:// links with just a click Chrome won't let you.

However that can be annoying in those intranet applications where you do need access to Windows UNC paths (so common in Corporate Environment)

Actually Chrome does allow you to open the file but you need to drag and drop the link in the address bar. This works of course for Windows OS.

As an example use this link to open the content of your Windows hosts file​​​​​​​​​​​​​​​​​​​​​

Monday, March 12, 2012

Sort KEY and CONSTRAINT in mysqldump for data migration scripts with gawk

No matter what you do you have to persist the data and your storage metadata or schema will change as the project evolves.

Managing the changes can be tricky and challenging costing your team endless hours spent reconciling what is in production against local and integration environments in order to push model changes to your staging environment.

As we currently generate most of our model directly from JPA as I posted before there is a serious need to see what is different from current proposed model and existing database schema.

In MySQL you have mysqldump tool however there is an important feature request which has not be addressed yet at the time of this writing.

Basically KEY and CONSTRAINT are not ordered and so as you modify the schema your diff will be alerting about false positives. You end up spending simply too much time inspecting differences.

I have decided to spend some time to make sure I get a consistent ordered mysqldump that my team can use to reconcile data from production with any other environment. That is why I coded a gawk script to sort mysqldump output.

Here is how to use the script to understand how unsorted your local mysql DATABASE is:
$ mysqldump --routines --no-data -h localhost -u USERNAME -pPASSWORD DATABASE > local.sql
$ ./mysqldump_sort.gawk < local.sql > local_sorted.sql
$ diff local.sql local_sorted.sql

Friday, March 09, 2012

Install curl is Solaris 10

Following a similar example as described in here for wget are the steps I followed to install curl in a Solaris 10 machine today. Keep in mind that depending on the libraries already installed in your systems you might not need some steps here or probably you will need more so I do recommend you read my post on installing wget first.
$ gunzip curl-7.24.0-sol10-x86-local.gz
$ pkgadd -d curl-7.24.0-sol10-x86-local 
$ gunzip libssh2-1.4.0-sol10-x86-local.gz 
$ pkgadd -d libssh2-1.4.0-sol10-x86-local 
$ gunzip openssl-1.0.0g-sol10-x86-local.gz 
$ pkgadd -d openssl-1.0.0g-sol10-x86-local 
$ /usr/local/bin/curl

Sunday, March 04, 2012

Calling Any Spring Service from JSTL

Update

There is actually a cleaner way to expose some (or all in one shot even not recommended) spring injected beans through the use of InternalResourceViewResolver#setExposedContextBeanNames:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   <property name="exposedContextBeanNames">
      <list>
         <value>employeeService</value>
         <value>clientService</value>
      </list>
   </property>
</bean>
In JSP you then just need to refer to the service:
<c:set var="clients" scope="request" value="${clientService.findAll()}"/>

Original post

There are times when you want to expose Spring Services through JSTL.

It is annoying though to have to create a new taglib definition plus a new Java method whenever you are in needs to expose certain functionality in JSP.

Did I say I like separation of concerns :-) You will say, but wait a minute exposing anything to JSP will be dangerous. Then I would respond, forcing to touch java for exposing functionality to the front end is not Agile.

So there is no silver bullet nor unique answer and the pragmatic architect knows how to respond to design questions: It depends.

Yes, you can go evil with the approach I am explaining here so you will need to limit the packages you expose to the front end, do visual code review and even come up with ingenious automated code review but I do believe this approach results in faster response to business needs at least for some "authorized" JSPs.

For example I have a team where people building reports and ETLs are not the same as those programming the back end or the front end application. I need them to build cool forms to accepts parameters from users and use those parameters to render reports and trigger ETL processes. I cannot afford the data analysts to be waiting for Java back end developers in order to inject from Controllers the objects they need in each page.

So first of all you need a class that will use reflection to invoke any Spring Service:
package com.nestorurquiza.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.springframework.context.ApplicationContext;

public final class SpringUtils {
    
    private SpringUtils(){}
    
    public static Object runService( ApplicationContext ctx, String service, String method, Object... params ) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Class c = Class.forName(service);
        Object springService = ctx.getBean(c);
        Class[] classes = null;
        if( params != null ) {
            classes = new Class[params.length];
            int i = 0;
            for( Object o : params ) {
                classes[i++] = o.getClass();
            }
        }
        
        Method m = c.getDeclaredMethod(method, classes);
        Object o = m.invoke(springService, params);
        return o;
    }

}

You need a class that will be able to interact with a Servlet Container to get the Spring Application Context:
package com.nestorurquiza.utils;

import java.lang.reflect.InvocationTargetException;

import org.springframework.context.ApplicationContext;

import com.nestorurquiza.utils.web.ApplicationServletContextListener;

public final class SpringWebUtils {
    
    private SpringWebUtils(){}
    
    public static Object runService( String service, String method, Object[] params ) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        //ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext()); 
        ApplicationContext ctx = ApplicationServletContextListener.getWebApplicationContext();
        return SpringUtils.runService(ctx, service, method, params);
    }
}
A taglib (SpringUtils.tld):
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemalocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>2.1</tlib-version>
<uri>SpringUtils</uri>

<function>
<name>runService</name>
<function-class>com.nestorurquiza.utils.SpringWebUtils</function-class>
<function-signature>
java.lang.Object runService( java.lang.String, java.lang.String, java.lang.Object[] )
</function-signature>
</function>
</taglib>
In JSP:
...
<%@ taglib prefix="spu" uri="/WEB-INF/tld/SpringUtils.tld"%>
<c:set var="clients" scope="request" value="${spu:runService('com.nestorurquiza.service.ClientService', 'findAll', null)}"/>
<tr>
<td ><spring:message code="label.clientName"/>:</td>
<td>
<form:select path="clients" >
<form:options items="${clients}" itemValue="id" itemLabel="name" />
</form:select>
</td>
<td><!-- errors for client or fund here --></td>
</tr>
...
<% String[] aParams = { "USA" };
request.setAttribute("aParams", aParams); %>
<c:set var="someClients" scope="request" value="${spu:runService('com.nestorurquiza.service.ClientService', 'findByName',aParams)}"/>
<tr>
<td ><spring:message code="label.clientName"/>:</td>
<td>
<form:select path="someClients" >
<form:options items="${someClients}" itemValue="id" itemLabel="name" />
</form:select>
</td>
<td><!-- errors for client or fund here --></td>
</tr>
As you can see you can call any service wether they need parameters or not. I have used some scriptlet to get an array because for some reason the below won't work in my current environment:
<c:set var="params" value="'USA'"/>
<c:set var="aParams" value="${fn:split(params, ',')}"/>

Followers