Jackson default conversion behavior (java json library spring uses)

So I complain. I think it could be done better but I didn’t do any research as why this is the default behavior of Jackson so you can educate me the whole reason behind this design. Since Jackson is the json library SpringMVC has picked, I’m using it.

By default, Jackson will convert any

  • public method
  • starts with “get”
  • takes no arguments
  • returns a value

from a POJO to json.

Is it not smart enough to figure out how many of those method are actually truly getters? And how many of them may be convenience methods?

Here’s an example:

public class Foo {
	private List<String> messsages = new ArrayList<String>();

	public List<String> getMesssages() {
		return messsages;
	}

	public void setMesssages(List<String> messsages) {
		this.messsages = messsages;
	}
	
	public String getLastMessage() {
		if(getMesssages().isEmpty()) {
			return "";
		} else {
			return getMesssages().get(getMesssages().size()-1);
		}
	}
}
@Test
public void test() throws JsonGenerationException, JsonMappingException, IOException {
	ObjectMapper mapper = new ObjectMapper();
	Foo foo = new Foo();
	String jsonFoo = mapper.writeValueAsString(foo);
	System.out.println(jsonFoo);
	
	Foo convertedFoo = mapper.readValue(jsonFoo, Foo.class);
}

This test fails because

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "lastMessage" (Class net.pureessence.Foo), not marked as ignorable

You have some options to get around this issue of course.

Exclude the convenience method so Jackson will NOT convert it

@JsonIgnoreProperties({
    "lastMessage"
})
public class Foo {
...

or

...
@JsonIgnore
public String getLastMessage() {
...

Pick which properties Jackson should INCLUDE in its conversion

@JsonPropertyOrder({
	"messages"
})
@JsonAutoDetect(value=JsonMethod.FIELD)
public class Foo {
	@JsonProperty private List<String> messsages = new ArrayList<String>();
...

I’m sure there are other options I have not mentioned that you may use to get around the issue.

Either way it requires your close attention and care and most likely tests of your exact json conversion to help you pay attention to how your changes on the POJO will affect your json conversion. I wish the default behavior of Jackson would just convert real properties only. Such as something that have both getters & setters. More here and here.

my github repo for the test

Spring JdbcTemplate to get db function output

e.g. SQL

select myFunction(param1, param2) from dual

returns a String value.

Do this using Spring JdbcTemplate via:

String result = getJdbcTemplate().queryForObject(sql, 
	new Object[] {
		param1, param2
	},
	String.class
);

See any big issue doing it this way? I personally don’t. I assume Spring will throw a SQL exception if for any reason the function errs out?

Jackson Ignore Property/Convenience Method

Here’s something I learned about Jackson and you may run into it.

What gets serialized by default?

Properties of an object are initially determined by process called auto-detection: all member methods and fields are checked to find:

  • “Getter” methods: all no-argument public member methods which return a value, and conform to naming convention of “getXxx” (or “isXxx”, if return type is boolean; called “is-getter”) are considered to infer existence of property with name “xxx” (where property name is inferred using bean convention, i.e. the leading capitali letter(s) is changed to lower case
  • field properties: all public member fields are considered to represent properties, using field name as is.

This means Jackson will map any convenience methods you create on the POJO that’s public and starts with “get” and returns a value. This may NOT be the behavior you want.

@JsonIgnoreProperties can be used at a class level and it works for me.

But in order to prevent me from tediously adding all of convenience methods on my POJO to the list, I started to use “return” as the keyword instead of “get” so Jackson will ignore those methods by default. Of course if you want JSTL to be able to show the convenience method output on the screen, the convenience method has to begin with “get”. So I’m using a mix of solutions to this problem.

Java Generics – conditionally instantiate a class

From Class to list of Enums

public static <T extends Enum> List<T> getList(Class<T> clazz) {
    return Arrays.asList(clazz.getEnumConstants());
}

So if I want to instantiate a class via some condition, I can do the following but still how do I know what type to use?

public class Foo {
	public String getName() {
		return "hi";
	}
}
public class Foo2013 extends Foo {
	public String getAge() {
		return "age";
	}
}
public class FooFactory {
	@SuppressWarnings("unchecked") // what do I need to do to not having to use this??
	public static <F extends Foo> F getFoo(int year) {
		try {
			if (year >= 2013) {
				return (F) Foo2013.class.newInstance();
			} else {
				return (F) Foo.class.newInstance();
			}
		} catch (InstantiationException e) {
			// TODO
		} catch (IllegalAccessException e) {
			// TODO
		}
		return null;
	}
}
public class FooFactoryTest {
	@Test
	public void testFooFactory() {
		Foo foo = FooFactory.getFoo(2011);
		Assert.assertEquals(Foo.class, foo.getClass());

		Foo foo2013 = FooFactory.getFoo(2013);  // <-- how can I do Foo2013 foo2013 without repeating the logic?
//		foo2013.getAge();
		Assert.assertEquals(Foo2013.class, foo2013.getClass());
	}
}

https://github.com/dodozhang21/JavaGenerics

2011 nfjs Central Iowa Software Symposium

My survey responses to the 2011 nfjs Central Iowa Software Symposium event for my company.

Benefits to you and the company from attending this event:
Keep up to date regarding the current technologies and development in the Java community.

Information that your co-workers / the company should be aware of:
Functional programming is making a big splash on the JVM. We really should come out of the traditional OO & imperative programming mindset and start think of solving programming challenges in a multi-paradigm fashion. We should upgrade from CVS to Git :)

Information that you learned that may have negative impacts to the company:
None

Would recommend this event / company presenting to someone else? Why?
Yes. The presenters have great knowledge about their topics. They always make me think harder and different about what I am doing at work.

Additional Comments or Suggestions:
I greatly enjoyed learning more about Scala, akka and functional programming thinking. The multi-paradigm session by Ted Neward opened my eyes. I took logic & functional programming courses in college and was super impressed by how concise and powerful those languages can be used to solve particular issues. Now many frameworks on the JVM prove that as Java programmers (who are innately OO & imperative), we may fully utilize the power of programming languages of other paradigms. This motivates me to explore a newer realm of programming.

I learned a lot from the Seven wastes of software development session e.g. communication is 38% tone, 7% words & 55% body languages. Therefore we should avoid plain emails for especially business rules discussion; converse with a coworker face to face is a much more effective way of communication. I think I don’t always do well in this area. Perhaps programmers are generally shy and introverted. I need to learn to open up more.

I also loved the Spock session although I feel Spock as a framework is yet completely mature for prime time. The fact it doesn’t have a version 1.x release somewhat speaks for this. (And it’s not yet in maven central repository.) I love its various features. But it’s still under heavy development phase as its community is actively adding more features to the framework. If we start using it now, we may need to upgrade our code dramatically later to get its full effects e.g. the @Unroll feature is going to change soon. However, I’m super excited to revisit it in a few months or so to see where it’s at. The fact that it’s a test framework great for both state testing & interaction testing (mocking) is awesome! It sounds like the mocking part of it is yet as mature as other mocking frameworks e.g. Mockito. For example, it doesn’t support partial mock/spy. This does not make me want to switch from Mockito to use it.

I will also use many of the new features of Groovy I learned since I just started using Groovy for testing. The SQL class Groovy has is extremely powerful and gave me many ideas as how I can utilize it to make testing more dynamic and more maintenance free.

SPEL! I conquered you on a Friday!

Today is my first attempt at using SPEL. After a mighty struggle, I was able to conquer it!

Background:

I needed a year variable for some work on a jsp page. It’s not always defined. I know for our routable datasource, a default year is required in order for it to work. I wanted to use the same default year but I only want the variable to be defined once and used in both places.

So I looked into SPEL.

It seems like the correct solution for the problem.

My original idea:


As it turns out, SPEL does not yet support embedded variables. SPEL, you must improve yourself!

My workaround:

I do not love it but it accomplishes my goal of not defining it more than one place.

Define the variable in a properties file e.g. application.properties
defaultYear=2011

Then use placeholder instead of SPEL notation to include it in spring.

Syntax grrr syntax:

Sadly some of my time was to learn the fact you CANNOT put a space between # and { in SPEL. For example, # {bean.property} will NOT work, but #{bean.property} will. It seems obvious afterwards but the error message you get just DOES NOT help you come to that conclusion.

Moral of the story:

SPEL is very handy but it’s yet perfect. Do keep that in mind as an alternative solution when dealing with Spring. If you use annotation, you can do @Value(“#{bean.property}”). Refer documentation for more info.

Java concurrency – Multiple queue monitors

At work, I’ve implemented a queue monitor batch application. Due to business rule changes, it now needs to monitor two queues. Instead of creating another batch application, I really wanted to stick with the same application but just create two threads, each monitoring its own queue.

However, the twist I need is to have the main batch application thread die as soon as either queue monitoring thread dies.

I’ve been searching for a graceful way to handle such a concurrency need in Java. Thank you to Gary Myers, I’ve got a great start on it.

The basic idea is to pass a java blocking queue to both of the threads and if either thread fails, do blockingQueue.offer to indicate so. Then in the main thread, it will check for the blocking queue’s result. blockingQueue.take() blocks/waits for it to return and then continues the execution of the main thread.

Things I learned that made today AMAZING!

  • Put repositories in the pom.xml instead of settings.xml for maven to look through multiple repositories
  • Use SynchronousQueue to ensure only 1 element at a time may exist in the queue
  • Use daemon to make sure the JVM will die even if there is a thread running
  • You can EMBED ActiveMQ using spring so you don’t have install it at all

Below is a simple concurrency example that demonstrates the idea from Gary Myers.

Worker:

public class Worker implements Runnable {
   private BlockingQueue<String> finishedQueue;
   private String result;
   private long sleepTime;
   
   public Worker(BlockingQueue<String> finishedQueue, String result, long sleepTime) {
      this.finishedQueue=finishedQueue;
      this.result=result;
      this.sleepTime=sleepTime;
   }
   
   public void run() {
      try {
         TimeUnit.SECONDS.sleep(sleepTime);
         finishedQueue.offer(result); //you have to use offer to get this queue to work.  It will throw an exception if there is something in the queue.
      } catch(InterruptedException e) {
         e.printStackTrace();
      }
   }
}

DaemonThreadFactory:

public class DaemonThreadFactory implements ThreadFactory {
   private AtomicInteger counter;
   
   public DaemonThreadFactory() {
      this.counter=new AtomicInteger(0);
   }
   
   public Thread newThread(Runnable r) {
      Thread thread=new Thread(r);
      
      //if you wanted you can make this class generic by having the constructor take arguments that can be used to configure the following
      thread.setDaemon(true); //need it to be daemon so the JVM will die even if there is a thread running
      thread.setName("Daemon Thread: " + counter.incrementAndGet()); //you don't have to give it a name, but I always do.
      
      return thread;
   }
}

Test the threads in a simple example:

public class Main {
   public static void main(String[] args) throws InterruptedException {
      ExecutorService service=Executors.newFixedThreadPool(2, new DaemonThreadFactory());
      SynchronousQueue<String> queue=new SynchronousQueue<String>(); //this queue can hold 1 element at a time, so basically the first thread to finish will be the one to successfully put the element in the queue
      //create the runnables before hand so that extra time isn't spent instantiating the runnables at submission time.
      Runnable runnable1=new Worker(queue, "Runnable 1", 4);
      Runnable runnable2=new Worker(queue, "Runnable 2", 3);
      
      service.execute(runnable1);
      service.execute(runnable2);
      
      System.out.println("before queue");
      System.out.println(queue.take());
      System.out.println("after queue");
      
      service.shutdown(); 
   }
}

I will not go into the details of the code I added for queue monitoring as they are a lot more involved.

The coolest thing I learned about ActiveMQ is how you can embed it using the following spring configuration:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:jms="http://www.springframework.org/schema/jms"
       xmlns:amq="http://activemq.apache.org/schema/core"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       				http://www.springframework.org/schema/jms http://www.springframework.org/schema/context/spring-jms-3.0.xsd
					http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
 
    <!--  Embedded ActiveMQ Broker -->
    <amq:broker id="broker" useJmx="false" persistent="true">
        <amq:transportConnectors>
            <amq:transportConnector uri="tcp://localhost:0" />
        </amq:transportConnectors>
    </amq:broker>

    <!--  ActiveMQ Destination  -->
    <amq:queue id="destination" physicalName="com.threads.example.queue" />

    <!-- JMS ConnectionFactory to use, configuring the embedded broker using XML -->
    <amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost" />

    <!-- JMS Producer Configuration -->
    <bean id="jmsProducerConnectionFactory" 
          class="org.springframework.jms.connection.SingleConnectionFactory"
          depends-on="broker"
          p:targetConnectionFactory-ref="jmsFactory" />

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"
          p:connectionFactory-ref="jmsProducerConnectionFactory"
          p:defaultDestination-ref="destination" />
</beans>

Once done, your application will run without your manual ActiveMQ installation. Above is from the example here.

If running in Eclipse…

  • Install m2eclipse plugin if you have not
  • Import -> Maven -> Existing Maven Projects
  • Select the MultipleQueueMonitors folder
  • Add src, resources, properties as source folders
  • Change the jre to whatever you want to use

The following error may occur in Eclipse

Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.4.c:
The matching wildcard is strict, but no declaration can be found for element 'amq:broker'. 

To fix it, you must associate the ActiveMQ XSD URL with the schema.

Go to XML->XML Catalog in Preferences, and add a User Specified Entry.

Location: http://activemq.apache.org/schema/core/activemq-core-5.3.0.xsd
Key Type: Namespace Name
Key: http://activemq.apache.org/schema/core

Then add a second one:

Location: http://activemq.apache.org/schema/core/activemq-core-5.3.0.xsd
Key Type: Schema Location
Key: http://activemq.apache.org/schema/core/activemq-core.xsd

Hit OK.

For more info, visit this stackoverflow thread.

>>>Check out or download the source from my github account if you are interested<<<

Eclipse 3.6 freezes at startup

My Eclipse 3.6 froze today at startup. I think what I did was that I clicked on the shortcut a bit too fast and two instances of Eclipse started running at the same time. I got an error message for one saying “workspace in use”. I killed the one that showed the error message but then my Eclipse will no longer start up.

I searched around for solutions.

The one that SORTA worked for me is below from here.

  • cd .metadata/.plugins
  • mv org.eclipse.core.resources org.eclipse.core.resources.bak
  • Start eclipse. (It should show an error message or an empty workspace because no project is found.)
  • Close all open editors tabs.
  • Exit eclipse.
  • rm -rf org.eclipse.core.resources (Delete the newly created directory.)
  • mv org.eclipse.core.resources.bak/ org.eclipse.core.resources (Restore the original directory.)
  • Start eclipse and start working. :-)

However, just doing that did not exactly solve my problem. I ended up going to the .metainfo/.plugins/org.eclipse.core.resources/.project directory and started deleting random project and trial on error. I finally found the project that was the culprit and fixed my issue.

Another suggestion by a coworker that has worked before if Eclipse freezes at startup is:

  • cd workspace\.metadata\.plugins\org.eclipse.ui.workbench
  • Make backup of workbench.xml
  • Edit workbench.xmlfile and remove all <editor> tags.

m2eclipse plugin jdk warning

More info – old issue but I ran into it on every freaking machine at home.

After I installed the m2eclipse plugin on Eclipse 3.6, I keep getting the following warning on the console:

The Maven Integration requires that Eclipse be running in a JDK, beacuase a number of Maven core plugins are using jars from the JDK.

Please make sure the -vm options in eclipse.ini is pointing to a JDK and verify that Installed JREs are also using JDK installs.

The solution that worked for me is changing the shortcut properties for eclipse e.g.

C:\JAVA\eclipse\eclipse.exe -vm "C:\Program Files\Java\jdk1.6.0_25\bin\javaw.exe"

I couldn’t get the eclipse.ini updates to work for some stupid reason.

Eclipse 3.6 Auto Static Import

After I started using JUnit 4, I really want Eclipse to automatically import org.junit.Assert.* statically for me. So when I do ctrl+space on methods like assertTrue, it will do:

import static org.junit.Assert.*;

for me.

I’ve figured it out for a while but I’ve been noticing it conflicting with my save action -> organize imports setting.

I finally got fed up and decided to investigate a bit further today.

Below are screenshots of Eclipse version 3.6.

  • Preferences -> Java -> Editor -> Content Assit -> Favorites all of the paths you wish to import statically e.g. org.junit.Assert.*
  • Then if you have Preferences -> Java -> Editor -> Save Actions -> Organize imports selected

    Make sure you update Preferences -> Java -> Code Style -> Orangize Imports to have Number of static imports needed for .* (e.g. ‘java.lang.Math.*) to 1.

    This way when you save your java files in Eclipse, it will not change your org.junit.Assert.* import to org.junit.Assert.assertTrue import. Otherwise it will require you to import again if you wish to use another method like assertFalse which in my opinion is annoying.