Gradle Test Failure Telling You More

I read this article:

http://java.dzone.com/articles/gradle-goodness-show-more

and tried the code to see how it worked for me.

Code:
https://github.com/cinq/gradle-test.git

The only real gotcha was that FC17 installed Gradle 1.0 while 1.6 is available and the example only works with 1.6. I downloaded and installed the latest version to get the same results as outlined in the article.

I know that Spring has switched over to Gradle as the build system so I should probably get more familiar with it.

They have a free online ebook that I will read:

http://www.gradleware.com/registered/books/building-and-testing/

Spring 3.1 and Rest headaches

To get the rest interfaces I planned to work in my Spring application were a bit of a headache because I did not do many things correctly.

First thing I was not aware was the changes to the web.xml:

<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <servlet-name>spring</servlet-name>
</filter-mapping>

These lines were added right after the DispatcherServlet. Without these lines I was getting errors on the DELETE method saying that the POST method was not implemented.

I also had a lot of trouble trying to generate a dynamic URL for the Rest calls. I could not get code similar to this to work:

<form:form action="<%= formUrl%>" method="delete">
	<input type="submit" value="Delete"/>
</form:form>

I tried the construct to generate the URL and it would not accept a string concatenated with a property from an object.

I add to declare a variable to do the concatenation:

String formUrl = "/admin/something/" + something.getId();

At least everything is working right now but that is a few hours lost to figuring out what works and why. Coding fun!

Spring Data JPA

I have an existing project where I wanted to start using the Spring Data JPA library to stop having to do all the code involved in a DAO. It sounded like a smart idea (without any prior knowledge) but when I tried to implement I realized that every time you try something new there are a few hurdles and unexpected surprises.

Searching for solution and tutorial with Google might be a good fallback plan but I found so many references to different ways that I got confused before sorting it out a bit. What you don’t easily see in all the solutions is which version of which library they are using until you have read most of the solution. I wish we could more easily search for examples and tutorial based on library versions.

Versions

Here is what I used for my project:

Spring Core 3.1.2.RELEASE
Spring Data 1.1.0.RELEASE
Apache Derby 10.2.2.0 (old version)
Hibernate 3.6.9 (old version)

 Limitations

Since I was working within an existing project I needed to work with certain things in place that I could not remove to use the Spring Data JPA library.

I needed to work with some XML files for the application context.

I needed to work with Apache Derby (old version).

I needed to work with Hibernate (old version).

Code changes

First thing that I needed to do was to add some dependencies in my pom.xml to be able to use Spring Data JPA.


<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>

It took me some trial and error to also realize that I needed an entity manager and since I was using Hibernate the logical choice was:


<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.6.9.Final</version>
</dependency>

I already had the Hibernate dependency in my pom.xml before starting:


<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.9.Final</version>
</dependency>

In my Java code I already had an entity that I wanted to use but because of the other entities that were managed under hibernate without Spring Data JPA I had to move this one to its own package so I could use some package scanning. Here is the entity code:


package com.cinq.test.domain;

import java.util.GregorianCalendar;

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class Event {

@Column(nullable=false)
private Long id;
@Column(nullable=false)
private String title;
@Column
private String Description;
@Column(nullable=false)
private GregorianCalendar date;

public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public GregorianCalendar getDate() {
return date;
}
public void setDate(GregorianCalendar date) {
this.date = date;
}

}

I needed to create a public interface to bind this entity to the Spring Data JPA “magic”. It simply needs to extend the CrudRepository and all the CRUD code is created for you.


package com.cinq.test.repository;

import org.springframework.data.repository.CrudRepository;

import com.cinq.test.domain.Event;

public interface EventRepository extends CrudRepository{

}

I also needed to add some quick configuration to my app-servlet.xml to get Spring to scan for repositories at startup:

All the code is available at:

Issues that needs to be worked out

The application runs on Tomcat but is giving an exception for a class not found on JBoss 7.1.1. I will have to look at the vfs settings for a default install.

I still need to fix the form submission.

 

References:

Spring Data – JPA (Starting point at SpringSource)
The Persistence Layer with Spring 3.1 and JPA (Starting point – tutorial)
Difference between configuring data source in persistence.xml and in spring configuration files (highlighted that with Spring 3.1 you don’t need the persistence.xml)
5 minutes with – Jpa transaction (highlighted the databasePlatform property in the xml configuration)
Problems with Spring maven hibernate org/hibernate/ejb/HibernatePersistence (need for hibernate-entity-manager)
13. Data access with JDBC (reference material for many items)

Eclipse completion template

Someone gave me some  code for a logger auto-completion template that I should use in Eclipse.

After searching on Google and discovering where it is in STS 3.1.0 I added this simple template to auto-complete my logger to use slf4j:

${:import(org.slf4j.Logger, org.slf4j.LoggerFactory)}private static final Logger ${logger} = LoggerFactory.getLogger(${enclosing_type}.class);

This is configurable under the Window -> Preferences -> Java -> Editor -> Templates

 

sts31-editor-template

 

I created a new template that I named logger, context is Java, a description (slf4j logging) and the pattern mentioned earlier.

Quite simple and so convenient that it will remove this bad habit of copying and pasting code with the wrong class name.

 

Spring 3 @Secured

I wanted to use the security annotation for my controllers and needed to do some searching to figure out how to get it to work.

Our application has a lot of legacy Spring 2.0 code so sometimes I am not sure how it will workout to mix the different ways to do things.

In my experimentation I was able to add security with the good old way:

<http auto-config="true">
    <intercept-url pattern="/something/protected**" access="ROLE_ADMIN">
    <... more config...>
</http>

As much as this was working I wanted the new annotation way in my controller code more than this xml configuration.

After reading a few articles I understood that I needed to add this line:

<global-method-security secured-annotations="enabled"/>

But it only works if it is within the same file where I have my other annotation scanning done for the application:

<!– @MVC –>
<context:component-scan base-package=”com.cinq.test”/>

I have a separate file for my security configuration but if I inserted the global-method-security configuration in there Spring would not apply my security annotation. A couple of answers on Stack Overflow mentioned that it needed to be in the same configuration file as the component-scan to work and as soon as I did this modification it started to work. So my main servlet xml configuration looks something like:

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xmlns:context=”http://www.springframework.org/schema/context&#8221;
xmlns:mvc=”http://www.springframework.org/schema/mvc&#8221;
xmlns:p=”http://www.springframework.org/schema/p&#8221;
xmlns:sec=”http://www.springframework.org/schema/security&#8221;
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd&#8221;
default-autowire=”byName” default-init-method=”init”>

<!– @MVC –>
<context:component-scan base-package=”com.cinq.test”/>
<context:component-scan base-package=”com.cinq.something”/>
<!– Security Annotation –>
<sec:global-method-security secured-annotations=”enabled”/>

My controller can now use this type of code:

@Controller
@RequestMapping("/protected/something")
public class SomethingController {
    @Autowired
    private ModelObject modelObject;
    @Secured("ROLE_TRANSFER")
    @RequestMapping(method=RequestMethod.GET)
    public String transferForm(Model model){
        // We need the list of sites
        ArrayList<String> sites = new ArrayList<String>();
        for ( ModelObject oneofthem : modelObjectDao.findAll()) {
            sites.add(oneofthem.getSite());
        }
        Collections.sort(sites);
        model.addAttribute("sites", sites);
 
       <SNIP SOME CODE>
       return "/WEB-INF/views/Transfer/form.jsp";
   }
 
    @Secured("ROLE_TRANSFER")
    @RequestMapping(value="/confirmation", method=RequestMethod.POST)
    public String confirmation(@RequestParam("site") String site, @RequestParam("date") String date, @RequestParam("requester") String requester) {

        return "/WEB-INF/views/schemaTransfer/confirmation.jsp";
    }
}

The URL calls will return a 403 if your credentials don’t have the ROLE_TRANSFER as an assigned role.

I like this simple way of annotating the behavior you want from your controller. Less file to maintain makes it easier for me to understand what behavior to expect from the code.

Can’t find this error message on Google or Bing

error_string         : 01070712:3: Caught configuration exception (0), Invalid monitor rule instance identifier: 47 – ltm/validation/MonitorRule.cpp, line 1323

I am trying to troubleshoot some error I am getting with my F5 iControl application and it seems that no one ever encountered this issue before.

Hard to believe.

I posted a question on the DevCentral Forums hoping to get some help but I am managing my expectations that others have faced this exact problem.

I have found a post that has the “Invalid monitor rule instance identifier” portion but the solution is to open a case with F5 support which I have also done.

F5 Support informed me that this error meant that in my configuration (bigip.conf) there was an issue on line 1323.  I find this error misleading because I was expecting the error was with the MonitorRule.cpp on line 1323. After looking at the configuration I could not figure out anything wrong. I did a QkView (for support) and everything started to work again. This makes absolutely no sense but since it is working I can’t troubleshoot anymore.

Spring 3.1 modelAttribute

Still working on this post…

Maddening searches to figure out how to properly use the modelAttribute keyword in the controller and the forms.

Here is a list of the mistakes I corrected to get to my goal

  • Typo: @ModelAttribute in the Java classes but modelAttribute in the jsp. Lower case “m” for jsp pages. When you have it right the id field in your rendered jsp page shows the proper model attribute name.
    <form:form modelAttribute=”madmartin” action=”/madmartin/${id}” method=”post”>
    gives html like this:
    <form id=”madmartin” action=”/madmartin/393216″ method=”post”>
    Got it from this page:  http://www.springbyexample.org/examples/spring-web-flow-subflow-webapp-jsp-example.html
    Too many other pages had it wrong. Mad +1
  • Could not use the @ModelAttribute on a method to create my object and then put data in the method processing the request. I had to put the @ModelAttribute in the argument of the method processing the request.
    I think this is the result of my misunderstanding of some feature. Idiot +1
  • Stole some code from the Spring documentation to fix a conversion issue from String to Date format I used in one of my model.
        @InitBinder
        public void initBinder(WebDataBinder binder) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            dateFormat.setLenient(false);
            binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
        }

    Code re-use at it’s best. Copy and Paste +1

StringBuilder VS StringBuffer

I am doing a code review and out of the blue I see that he has replaced the StringBuffer variable with a StringBuilder.

I could ask why but I figured it would be better to read a bit before I ask the question.

The first advantage I find for StringBuilder is that it is faster because it is not synchronized. This means that the advantage of StringBuffer is that it is thread-safe.

After reading this post about never using StringBuffer you can question what thread-safety means with StringBuffer and probably always use StringBuilder.

There is also a bonus performance comment about never using a String in a loop to append values to it.

I have learned a something useful with this code review (as always if I take the time to do it right).