Featured FREE Whitepapers

What's New Here?

spring-logo

Spring – Designing the domain model and the service layer

We are going to build application for timesheet management. So let’s think about some uses cases and entities first. Let me write them in the few bullets:Task is assigned to employee by manager. One task can be assigned to many employees. Employee fills the amount of hours that he worked on certain task to the system. Manager/Employee views reports on timesheets (timesheets can be altered).Let’s revisit those points a little and let’s try to transform this plain human language to some relations and entities that programmer can spot.Entities: Manager, Employee, Timesheet, TaskOkay, we should now have better grasp about the domain, so let’s create maven project and implement classes. With Maven you get nice and clean project structure. All you need is installed Maven and having pom.xml in your project. You can either do that “by hand” and building application via terminal (in this case just create regular project and add pom.xml file). I prefer using some additional tooling. IntelliJ IDEA, NetBeans and Springsource Tool Suite have out of the box Maven support. If you’re using plain Eclipse, check m2eclipse plugin. In either way, here is some basic Maven configuration for our project: <project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd'> <modelVersion>4.0.0</modelVersion> <groupId>org.timesheet</groupId> <artifactId>org.timesheet</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Timesheet Management On Spring</name> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> </project> Now let’s implement domain model. Create package org.timesheet.domain and define following classes. package org.timesheet.domain;public class Employee {private String name; private String department;public Employee(String name, String department) { this.name = name; this.department = department; } public String getName() { return name; } public String getDepartment() { return department; } }package org.timesheet.domain;public class Manager {private String name;public Manager(String name) { this.name = name; } public String getName() { return name; } }package org.timesheet.domain;import java.util.ArrayList; import java.util.Arrays; import java.util.List;public class Task {private List<Employee> assignedEmployees = new ArrayList<Employee>(); private Manager manager; private boolean completed; private String description; public Task(String description, Manager manager, Employee... employees) { this.description = description; this.manager = manager; assignedEmployees.addAll(Arrays.asList(employees)); completed = false; }public Manager getManager() { return manager; } public List<Employee> getAssignedEmployees() { return assignedEmployees; } public void addEmployee(Employee e) { assignedEmployees.add(e); } public void removeEmployee(Employee e) { assignedEmployees.remove(e); } public void completeTask() { completed = true; } }package org.timesheet.domain;public class Timesheet {private Employee who; private Task task; private Integer hours; public Timesheet(Employee who, Task task, Integer hours) { this.who = who; this.task = task; this.hours = hours; }public Employee getWho() { return who; }public Task getTask() { return task; } public Integer getHours() { return hours; } /** * Manager can alter hours before closing task * @param hours New amount of hours */ public void alterHours(Integer hours) { this.hours = hours; }@Override public String toString() { return 'Timesheet [who=' + who + ', task=' + task + ', hours=' + hours + ']'; }} As you can see, Manager and Employee classes don’t have many properties, they’re here just for the sake of having type safe model. In the “real world”, they’d probably have various other properties like surname, birthday, address and so on, maybe even common parent class. Also, we don’t really care about various constraints now. For example, we can only fill integer hours on tasks and so on. Now it’s time to define our service layer – define business operations and establish interface for those. So let’s make package org.timesheet.service. At first, we will create GenericDao interface, where we will define basic CRUD operations for every entity in the system. package org.timesheet.service;import java.util.List;public interface GenericDao<E, K> {void add(E entity); void update(E entity); void remove(E entity); E find(K key); List<E> list(); } For now, let’s not worry about the actual persistence layer – let’s create some dummy implementation and store all the data in memory. We will put it in to the new package – org.timesheet.service.impl. Don’t worry, later we’ll use Hibernate for this. Here is the code for the dummy implementation: package org.timesheet.service.impl;import java.util.ArrayList; import java.util.List;import org.timesheet.service.GenericDao;public class InMemoryDao<E, K> implements GenericDao<E, K> { private List<E> entities = new ArrayList<E>();@Override public void add(E entity) { entities.add(entity); }@Override public void update(E entity) { throw new UnsupportedOperationException('Not supported in dummy in-memory impl!'); }@Override public void remove(E entity) { entities.remove(entity); }@Override public E find(K key) { if (entities.isEmpty()) { return null; } // just return the first one sice we are not using any keys ATM return entities.get(0); }@Override public List<E> list() { return entities; }} Next, we will write our first simple test. We will now add our first dependency into pom.xml file to JUnit library. Because it’s the first one, we also need to wrap it into dependencies element like so: <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> Here’s our first very simple unit test for Employee DAO. We won’t do others now, since we don’t really have anything to test yet. What’s more important though, is how we depend on implementation of DAO in the test (we use new InMemoryDao…). This is bad, because we should only test public API of defined interface. Later in this tutorial, you will see how Spring helps us to solve such problems. package org.timesheet.service;import static org.junit.Assert.*;import java.util.List;import org.junit.Before; import org.junit.Test; import org.timesheet.domain.Employee; import org.timesheet.service.impl.InMemoryDao;public class EmployeeDaoTest { private GenericDao<Employee, Long> employeeDao = new InMemoryDao<Employee, Long>(); @Before public void setUp() { for (int i = 0; i < 5; i++) { Employee e = new Employee('Mike ' + i, 'IT'); employeeDao.add(e); } } @Test public void testAdd() { int oldSize = employeeDao.list().size(); Employee e = new Employee('Bob', 'IT'); employeeDao.add(e); int newSize = employeeDao.list().size(); assertFalse (oldSize == newSize); } @Test public void testRemove() { int oldSize = employeeDao.list().size(); Employee e = employeeDao.find(1L); employeeDao.remove(e); int newSize = employeeDao.list().size(); assertFalse (oldSize == newSize); } @Test public void testUpdate() { //TODO: need real implementation } @Test public void testList() { List<Employee> list = employeeDao.list(); assertNotNull (list); assertFalse (list.isEmpty()); }} If you want, you can also write unit tests for remaining tests for the other DAOs. But since we don’t have proper implementation to test now, we’ll do it later together. Things are not always so easy though. It’s not only about CRUD operations, it’s also about business operations that are not generic enough to be expressed in simple DAOs. So let’s define few business operations and create separate service for them. We’ll call this service TimesheetService. package org.timesheet.service;import org.timesheet.domain.Employee; import org.timesheet.domain.Manager; import org.timesheet.domain.Task;import java.util.List;/** * Business that defines operations on timesheets */ public interface TimesheetService { /** * @return Finds the busiest task (with the most of employees). * Returns {@code null} when tasks are empty. */ Task busiestTask(); /** * Finds all the tasks for the employee. * @param e Employee * @return Tasks */ List<Task> tasksForEmployee(Employee e); /** * Finds all the tasks for the manager. * @param m Manager * @return Tasks */ List<Task> tasksForManager(Manager m); } Okay, so far so good. You have now idea what’s the business domain we will be using in the next examples. You might be wondering now – we haven’t use any Spring yet, why? Remember that Spring’s original purpose is to simplify enterprise java development and encourage POJO development model. So it will be very easy to use Spring with this basic model, so we won’t have our core logic mixed with unnecessary dependencies. On the picture below there is structure of the project we’ve built so far, so make sure you’re good.Reference: Part 1 – Designing the domain model and the service layer from our JCG partner Michal Vrtiak at the vrtoonjava blog....
powermock-logo

Using PowerMock to Mock Constructors

In my opinion, one of the main benefits of dependency injection is that you can inject mock and/or stub objects into your code in order to improve testability, increase test coverage and write better and more meaningful tests. There are those times, however, when you come across some legacy code that doesn’t use dependency injection and held together by composition rather than aggregation. When this happens, you have three options:Ignore the problem and not write any tests. Refactor like mad, changing everything to use dependency injection. Use PowerMock to mock constructorsObviously, option 1 isn’t a serious option, and although I’d recommend refactoring to move everything over to dependency injection, that takes time and you have to be pragmatic. That’s where PowerMock comes in… this blog demonstrates how to use PowerMock to mock a constructor, which means that when your code calls new it doesn’t create a real object, it creates a mock object. To demonstrate this idea, the first thing we need is some classes to test, which are shown below. public class AnyOldClass { public String someMethod() { return "someMethod"; } }public class UsesNewToInstantiateClass {public String createThing() {AnyOldClass myclass = new AnyOldClass();String returnValue = myclass.someMethod(); return returnValue; } }The first class, AnyOldClass, is the class that the code instantiates by calling new. In this example, as the name suggests, it can be anything. The second class, the aptly named UsesNewToInstantiateClass, has one method, createThing(), which when called does a: AnyOldClass myclass = new AnyOldClass();This is all pretty straight forward, so we’ll move quickly on to the PowerMock assisted JUnit test: import static org.easymock.EasyMock.expect; import static org.junit.Assert.assertEquals; import static org.powermock.api.easymock.PowerMock.expectNew; import static org.powermock.api.easymock.PowerMock.replay; import static org.powermock.api.easymock.PowerMock.verify;import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.easymock.annotation.Mock; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner;@RunWith(PowerMockRunner.class) @PrepareForTest(UsesNewToInstantiateClass.class) public class MockConstructorTest {@Mock private AnyOldClass anyClass;private UsesNewToInstantiateClass instance;@Test public final void testMockConstructor() throws Exception {instance = new UsesNewToInstantiateClass();expectNew(AnyOldClass.class).andReturn(anyClass);final String expected = "MY_OTHER_RESULT"; expect(anyClass.someMethod()).andReturn(expected);replay(AnyOldClass.class, anyClass); String result = instance.createThing(); verify(AnyOldClass.class, anyClass); assertEquals(expected, result); }}Firstly, this class has the usual PowerMock additions of: @RunWith(PowerMockRunner.class) @PrepareForTest(UsesNewToInstantiateClass.class)at the top of the file plus the creation of the anyOldClass mock object. The important line of code to consider is: expectNew(AnyOldClass.class).andReturn(anyClass);This line of code tells PowerMock to expect a call to new AnyOldClass() and return our anyClass mock object. Also of interest are the calls to replay and verify. In the example above, they both have two arguments. The first, AnyOldClass.class relates to the expectNew(…) call above, whilst the second, anyClass refers to the straight forward mock call expect(anyClass.someMethod()).andReturn(expected);. There are those times when you should really let new do what it does: create a new object of the requested type. There is a body of opinion that says you can over-isolate your code when testing and that mocking everything reduces the meaning and value of a test. To me there’s no right answer to this and it’s a matter of choice. It’s fairly obvious that if your code accesses an external resource such as a database, then you’d either refactor and implement DI or use PowerMock. If your code under test doesn’t access any external resources, then it’s more of a judgement call on how much code isolation is too much? This perhaps needs some thought and may be the subject for another blog on anther day… Reference: Using PowerMock to Mock Constructors from our JCG partner Roger Hughes at “Captain Debug’s” Blog....
apache-camel-logo

Camel: Build a message based application

This is a long article that contains three separate topics:Getting started with Apache Camel with Java Improving startup of routes with a CamelRunner Building message based application using CamelBut since I’ve prepared a camel-demo-1.0.0-SNAPSHOT-project.zip that has all these materials included, I thought it would easier to combine them and present it as whole.Getting started with Apache Camel with Java Trying out Camel with few Groovy lines is one thing, but getting a full scale project in Java is another matter. Today, I will show you how to get things started on Apache Camel with Maven based project. You may also use the provided camel-demo as project template to jump start your own Apache Camel project. You would just need to rename the Java package and rename the pom’s group and artifact id’s to match your need.Preparing a Maven based project with Camel dependencies Unzip the camel-demo project source, and you will see the basic directory layout. camel-demo +- bin +- config +- data +- src +- pom.xml +- README.txt What makes this demo a Camel based project is just the declaration in pom.xml. Let’s take a look the file and its dependencies. <?xml version='1.0' encoding='UTF-8'?> <project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'><modelVersion>4.0.0</modelVersion> <groupId>deng.cameldemo</groupId> <artifactId>camel-demo</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging><properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <slf4j.version>1.6.6</slf4j.version> <camel.version>2.10.1</camel.version> </properties><build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.3</version> <configuration> <descriptorRefs> <descriptorRef>project</descriptorRef> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies><!-- Unit testing lib --> <dependency> <groupId>junit</groupId> <artifactId>junit-dep</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-library</artifactId> <version>1.2.1</version> <scope>test</scope> </dependency><!-- Logging lib --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> <scope>runtime</scope> <optional>true</optional> </dependency><!-- Apache Commons lib --> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.0.1</version> </dependency><!-- Apache Camel --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-groovy</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jackson</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-mina</artifactId> <version>${camel.version}</version> </dependency></dependencies></project> This pom.xml decalares a Java based application and it will produce jar. It requires minimal of JDK 6 or higher. Besides the typical junit and hamcrest for unit testing, I also added slf4j for logging. I have added couple Apache’s commons-lang/io to the project as well. I think these are basic settings that any Java based application should use them. The maven-assembly-plugin I have declared is only for this demo packging purpose, and you may change or remove to suite your own project need. For Camel dependencies, you would need minimal camel-core for routes building. And then you can add any additional components you plan to use in your project. I have added the following for building typical message based application development:The camel-spring – we want to have option to declare Camel routes in xml files as configuration. See camel-demo/config directory for samples. The camel-jackson – we want to process messaging data in our application as JSON format. The camel-mina – we want to send messaging data accross network through TCP socket. The camel-groovy – [optional] we want to be able to add dynamic scripting to route, even inside the xml config. This is great for debug and POC.Note that since we use multiple camel components dependencies, I choose to set a Maven property ${camel.version} so that when we upgrade Camel, it’s easier to maintain the pom.xml file in one place. You should able to cd into the project directory and run mvn compile to verify that the project. It should compile without error.Improving startup of routes with a CamelRunner With the project pom.xml file ready, you can start creating Camel routes to handle your own business logics. Before we get too excited, let’s try out a simple HelloRoute to see how it works and how we can run it first. Here is the route defnition code in src/main/java/deng/cameldemo/HelloRoute.java. package deng.cameldemo;import org.apache.camel.builder.RouteBuilder;public class HelloRoute extends RouteBuilder { @Override public void configure() throws Exception { from('timer://helloTimer?period=3000'). to('log:' + getClass().getName()); } }Take a test ride with the Camel To see above in action, we need to add it into a CamelContext and start the context. For Java standalone program, we would write this setup code in a Main class. The Camel actually comes with a org.apache.camel.main.MainSupport abstract class that you may use to extend your own Main. However, I think it would be even nicer if Camel would provide a CamelRunner that can run like this. $ java CamelRunner deng.cameldemo.HelloRoute Such CamelRunner would be very user friendly and re-usable to have, so that’s what I did. I wrote one like this: package deng.cameldemo;import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext;/** * A main program to start Camel and run as a server using RouteBuilder class names or * Spring config files. * * <p>Usage: * * java deng.cameldemo.CamelRunner deng.cameldemo.HelloRoute * * or * * java -Dspring=true deng.cameldemo.CamelRunner /path/to/camel-spring.xml * * @author Zemian Deng */ public class CamelRunner { public static void main(String[] args) throws Exception { CamelRunner runner = new CamelRunner(); runner.run(args); }private static Logger logger = LoggerFactory.getLogger(CamelRunner.class); public void run(String[] args) throws Exception { if (Boolean.parseBoolean(System.getProperty('spring', 'false'))) runWithSpringConfig(args); else runWithCamelRoutes(args);// Wait for user to hit CRTL+C to stop the service synchronized(this) { this.wait(); } }private void runWithSpringConfig(String[] args) { final ConfigurableApplicationContext springContext = new FileSystemXmlApplicationContext(args);// Register proper shutdown. Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { try { springContext.close(); logger.info('Spring stopped.'); } catch (Exception e) { logger.error('Failed to stop Spring.', e); } } });// Start spring logger.info('Spring started.'); }private void runWithCamelRoutes(String[] args) throws Exception { final CamelContext camelContext = new DefaultCamelContext(); // Register proper shutdown. Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { try { camelContext.stop(); logger.info('Camel stopped for {}', camelContext); } catch (Exception e) { logger.error('Failed to stop Camel.', e); } } });// Added RouteBuilder from args for (String className : args) { Class<?> cls = Class.forName(className); if (RouteBuilder.class.isAssignableFrom(cls)) { Object obj = cls.newInstance(); RouteBuilder routeBuilder = (RouteBuilder)obj; camelContext.addRoutes(routeBuilder); } else { throw new RuntimeException('Unable to add Camel RouteBuilder ' + className); } }// Start camel camelContext.start(); logger.info('Camel started for {}', camelContext); } } To help you run the main class, I have provided a run-java wrapper script under the project’s bin directory, so that you may quickly test it without having to setup classpath. $ mvn package $ bin/run-java deng.cameldemo.CamelRunner deng.cameldemo.HelloRoute You will see that the program will load the HelloRoute in a DefaultCamelContext and start it as a server. The HelloRoute itself will generate a 3 seconds timer message and send it to a logger, which should be printing onto your console screen. This will continue forever until you hit CTRL+C to end it. NOTE: You only have to invoke mvn package command once, so that it will package up all the dependencies jars in order for run-java to auto-detect them. If you are not going to use maven-assembly-plugin during package phase, then use mvn dependency:copy-dependencies command explicitly will work fine as well.Take a test ride with the Camel, Part 2: running Camel with Spring xml configuration The HelloRoute example above would simply provide route definition that formed by using component URI’s. It will be nice if we can configure the route in a declarative manner so that we may change the route without re-compile a class file. This will be very handy especially if you are not familiar with each component’s options and want to explore and try things out. Well, that’s what the camel-spring is for. Beside giving you an option to load route in xml config file, it also provides a very flexible way to register custom services/processors bean in the Spring IoC container. If you are a keen reader, you will notice in the CamelRunner code above that it has an extra runWithSpringConfig part. So the CamelRunner can actually bootstrap any Spring xml file and start a context as a server. You may use it like this: $ bin/run-java deng.cameldemo.CamelRunner -Dspring=true config/hellocamel-spring.xmlThe config/hellocamel-spring.xml is just an equivalent of our HelloRoute code but in Spring xml form: <beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation=' http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd'><camelContext id='helloCamel' xmlns='http://camel.apache.org/schema/spring'> <route> <from uri='timer://jdkTimer?period=3000'/> <to uri='log://deng.cameldemo.HelloCamel'/> </route> </camelContext></beans> This remove the need to compile/re-compile HelloRoute to define the Camel route to run.Building message based application using Camel To present you with a more practical demo, I would show you further on how to setup Camel to process message based application. In many IT shops, it’s common that you would have a server to take message data as input and process them. A practical use case is to take any JSON formated message and transform it into object and process it. To do this in Camel, what you want to build is a route that will take input messages from a TCP port, and then process it in a pipeflow with any business logic you may have. You will run the route as a server, and then client may use any mean to submit the message to the TCP port. Client may even be another thin Camel client app to submit data as well. Let me show you how to get started. Writing the server side code with Camel route The server side would need a route to listen from a TCP port, and this is provided by camel-mina component. The first step is you need a route. package deng.cameldemo;import org.apache.camel.builder.RouteBuilder;public class TcpMsgRoute extends RouteBuilder { @Override public void configure() throws Exception { String port = System.getProperty('port', '12345'); from('mina:tcp://localhost:' + port + '?sync=false'). to('log:' + getClass().getName()); } }Then the next step is … done! No way, you mean that’s all there to it for a server? Too good to be true? Well, let’s try it out $ bin/run-java deng.cameldemo.CamelRunner deng.cameldemo.TcpMsgRoute -Dport=12345 15:21:41 main INFO org.apache.camel.impl.DefaultCamelContext:1391 | Apache Camel 2.10.1 (CamelContext: camel-1) is starting 15:21:41 main INFO org.apache.camel.management.ManagementStrategyFactory:43 | JMX enabled. 15:21:42 main INFO org.apache.camel.impl.converter.DefaultTypeConverter:45 | Loaded 172 type converters 15:21:42 main INFO org.apache.camel.component.mina.MinaConsumer:59 | Binding to server address: localhost/127.0.0.1:12345 using acceptor: org.apache.mina.transport.socket.nio.SocketAcceptor@2ffad8fe 15:21:42 main INFO org.apache.camel.impl.DefaultCamelContext:2045 | Route: route1 started and consuming from: Endpoint[mina://tcp://localhost:12345?sync=true] 15:21:42 main INFO org.apache.camel.management.DefaultManagementLifecycleStrategy:859 | StatisticsLevel at All so enabling load performance statistics 15:21:42 main INFO org.apache.camel.impl.DefaultCamelContext:1426 | Total 1 routes, of which 1 is started. 15:21:42 main INFO org.apache.camel.impl.DefaultCamelContext:1427 | Apache Camel 2.10.1 (CamelContext: camel-1) started in 0.505 seconds 15:21:42 main INFO deng.cameldemo.CamelRunner:93 | Camel started for CamelContext(camel-1) Voila! The server is up and waiting for your users to send messages through port 12345. Not too bad for few lines of code.Writing the client side code with Camel ProducerTemplate Since our server expose a TCP port and take in any text content message, you can create any client that’s capable writing to a TCP socket. In here, I will show you how to use Camel to write a thin client. package deng.cameldemo.client;import java.io.FileReader; import org.apache.camel.CamelContext; import org.apache.camel.ProducerTemplate; import org.apache.camel.impl.DefaultCamelContext; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory;public class TcpMsgSender { public static void main(String[] args) throws Exception { TcpMsgSender runner = new TcpMsgSender(); runner.run(args); }private static Logger logger = LoggerFactory.getLogger(TcpMsgSender.class); public void run(String[] args) throws Exception { String fileName = args.length > 0 ? args[0] : 'data/msg.txt'; String[] hostPort = (args.length > 1 ? args[1] : 'localhost:12345').split(':'); String host = hostPort[0]; String port = hostPort.length > 1 ? hostPort[1] : '12345'; logger.info('Sending tcp message {} to host={}, port={}', new Object[]{ fileName, host, port});String text = IOUtils.toString(new FileReader(fileName)); logger.debug('File size={}', text.length());CamelContext camelContext = new DefaultCamelContext(); ProducerTemplate producer = camelContext.createProducerTemplate(); producer.sendBody('mina:tcp://' + host + ':' + port + '?sync=false', text); logger.info('Message sent.'); } } This TcpMsgSender can send any text file to your server endpoint. Try this out while your server is running: $ bin/run-java deng.cameldemo.client.TcpMsgSender data/test-msg.json localhost:12345 15:22:35 main INFO deng.cameldemo.client.TcpMsgSender:24 | Sending tcp message data/test-msg.json to host=localhost, port=12345 15:22:35 main DEBUG deng.cameldemo.client.TcpMsgSender:27 | File size=47 15:22:35 main INFO org.apache.camel.impl.converter.DefaultTypeConverter:45 | Loaded 172 type converters 15:22:35 main INFO org.apache.camel.management.ManagementStrategyFactory:43 | JMX enabled. 15:22:35 main INFO deng.cameldemo.client.TcpMsgSender:32 | Message sent.You should able to verify from your server console output that it received the msg. The msg I sent is in data/test-msg.json, which contains this simple text: { 'firstName' : 'Zemian', 'lastName' : 'Deng' }Note that our server simply receive plain text and log it. We will discuss how to process the message next.Processing message data in JSON format with Camel and Spring xml config You thought the server code was easy from above, guess again. You can actually replace the TcpMsgRoute with just some simple xml lines! <beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation=' http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd'><camelContext id='tcpMsgServer' xmlns='http://camel.apache.org/schema/spring'> <route> <from uri='mina:tcp://localhost:12345?sync=false'/> <to uri='log://deng.cameldemo.TcpMsgServer'/> </route> </camelContext></beans>Save it as config/tcpmsgserver-spring.xml. Then re-run the server, and you should get the same result as above. $ bin/run-java deng.cameldemo.CamelRunner -Dspring=true config/tcpmsgserver-spring.xmlNow let us improve the above xml to further process the JSON message data. We will like to transform the plain text to a Java object then process by a custom bean. To do that, we first would need to add unmarshal component to the route. This is where the camel-jackson comes into play. In our demo, the unmarshalling step would convert the JSON text into a java.util.Map and then pass it to a processor bean named myMsgProcessor. Let’s create a new xml file named config/tcpmsgserver-json-spring.xml as follow. <beans xmlns='http://www.springframework.org/schema/beans' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation=' http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd'><camelContext id='tcpMsgServer' xmlns='http://camel.apache.org/schema/spring'> <route> <from uri='mina:tcp://localhost:12345?sync=false'/> <to uri='log://deng.cameldemo.TcpMsgServer'/> <unmarshal> <json library='Jackson'/> </unmarshal> <to uri='bean:myMsgProcessor?method=process'/> </route> </camelContext><bean id='myMsgProcessor' class='deng.cameldemo.MyMsgProcessor'> </bean></beans>The myMsgProcessor is an Spring bean that we provide custom logic code to process the data. At this point we have a full Java object to manipulate. The content of the processor can be any POJO with the method name specified in the URI. Here is an example one: package deng.cameldemo;import org.apache.camel.builder.RouteBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map;public class MyMsgProcessor { private static Logger logger = LoggerFactory.getLogger(MyMsgProcessor.class); public void process(Map<String, String> data) { logger.info('We should slice and dice the data: ' + data); } } Try re-run the server with the new xml file above, and you should able to re-invoke the same client command to test it out. Here is a sample output of my server: $ bin/run-java deng.cameldemo.CamelRunner -Dspring=true config/tcpmsgserver-json-spring.xml 17:05:25 main INFO org.springframework.context.support.FileSystemXmlApplicationContext:456 | Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@4200309: startup date [Sat Sep 15 17:05:25 EDT 2012]; root of context hierarchy 17:05:25 main INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader:315 | Loading XML bean definitions from file [/Users/zemian/projects/sandbox/camel-demo/config/tcpmsgserver-json-spring.xml] 17:05:27 main INFO org.springframework.beans.factory.support.DefaultListableBeanFactory:557 | Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@27b75165: defining beans [template,consumerTemplate,tcpMsgServer:beanPostProcessor,tcpMsgServer,myMsgProcessor]; root of factory hierarchy 17:05:27 main INFO org.apache.camel.spring.SpringCamelContext:1391 | Apache Camel 2.10.1 (CamelContext: tcpMsgServer) is starting 17:05:27 main INFO org.apache.camel.management.ManagementStrategyFactory:43 | JMX enabled. 17:05:27 main INFO org.apache.camel.impl.converter.DefaultTypeConverter:45 | Loaded 172 type converters 17:05:28 main INFO org.apache.camel.component.mina.MinaConsumer:59 | Binding to server address: localhost/127.0.0.1:12345 using acceptor: org.apache.mina.transport.socket.nio.SocketAcceptor@5a3cae4a 17:05:28 main INFO org.apache.camel.spring.SpringCamelContext:2045 | Route: route1 started and consuming from: Endpoint[mina://tcp://localhost:12345?sync=false] 17:05:28 main INFO org.apache.camel.management.DefaultManagementLifecycleStrategy:859 | StatisticsLevel at All so enabling load performance statistics 17:05:28 main INFO org.apache.camel.spring.SpringCamelContext:1426 | Total 1 routes, of which 1 is started. 17:05:28 main INFO org.apache.camel.spring.SpringCamelContext:1427 | Apache Camel 2.10.1 (CamelContext: tcpMsgServer) started in 0.695 seconds 17:05:28 main INFO deng.cameldemo.CamelRunner:61 | Spring started. 17:05:35 Camel (tcpMsgServer) thread #3 - MinaThreadPool INFO deng.cameldemo.TcpMsgServer:96 | Exchange[ExchangePattern:InOnly, BodyType:String, Body:{ 'firstName' : 'Zemian', 'lastName' : 'Deng' }] 17:05:35 Camel (tcpMsgServer) thread #3 - MinaThreadPool INFO deng.cameldemo.MyMsgProcessor:11 | We should slice and dice the data: {lastName=Deng, firstName=Zemian} Pay attention that Camel will auto convert the data format in your route! Our client only sends the plain text as JSON format, but when server receives it, it unmarshals it using Jackson library, and then converts it into a java Map object. It then passes the map object into our processor bean. Also, in this demo, I choose to use a generic java.util.Map as processor method argument (which is output of the JSON unmarshal), but you can easily define your own business data type, such as MyCustomerData. This reveals the power of Camel, since you don’t need to push the message in your flow, but only worry about writing your ‘processor’ as a POJO. The Camel will ‘glue’ components together to form a route and carry the message data through the pipeline flow. On the same token, when you write your business logic in one or more processors, it’s a good idea that you limit your POJO logic to be as small unit as possible. When you do this, then you can maximize the reusability of the processors. The bigger POJO you make, with many business logics mixed in, it will also make it difficult to test. So I recommend you when developing these processor beans, try to think them as LEGO pieces — small POJO. You want to let Camel define the route and glue the LEGO pieces togther. Once you get into this habit of thiking, then you can use Camel in a more effectively way to solve many of your domain problems. Well, that’s all for today folks. I hope you enjoyed the Camel ride. Happy coding and don’t forget to share! Reference: Building message based application using Camel from our JCG partner Zemian Deng at the A Programmer’s Journal blog....
apache-myfaces-logo

Configure timeout for CDI conversations

CDI conversation scope is a nice feature when developing JSF applications. Imagine you have large data tables which take a long time to be loaded. You normally don’t want to place the loaded data in session scoped beans by reason of high memory consumption. And you can’t place the loaded data in view scoped beans because you wouldn’t like always to reload data again if user leave and enter the same view. It would be nice only to keep data if user enters the same page within a certain time interval and reload them again if the bean was not accessed within this time interval. This can be achieved by conversation scoped bean with timeout. We will deal with MyFaces CODI (CDI Extensions) and see how to set a custom timeout for beans annotated with @ConversationScoped. The default timeout is 30 min. what is too long for our example. We will configure it for 1 min. The first step is to extend CODI’s ConversationConfig and overwrite the method getConversationTimeoutInMinutes(). Let’s write a class AlternativeConversationConfig. package controller.cdi;import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Alternative; import javax.enterprise.inject.Specializes; import org.apache.myfaces.extensions.cdi.core.api.config.ConfigEntry; import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.config.ConversationConfig;@ApplicationScoped @Alternative @Specializes public class AlternativeConversationConfig extends ConversationConfig {@ConfigEntry public int getConversationTimeoutInMinutes() { return 1; } }The important thing is the annotation @Specializes which allows to inject AlternativeConversationConfig instead of ConversationConfig at every existing places. The second step is a proper entry in beans.xml to use (activate) our class on all injection points for ConversationConfig. <alternatives> <class>controller.cdi.AlternativeConversationConfig</class> </alternatives>Server’s log output during startup contains these lines now config implementation: controller.cdi.AlternativeConversationConfig$Proxy$_$$_WeldClientProxy config implementation: controller.cdi.AlternativeConversationConfig method: getConversationTimeoutInMinutes value: 1To check if everything is ok, we can write a conversation scoped bean and use it in facelets. import java.io.Serializable; import javax.faces.event.ActionEvent; import javax.inject.Named; import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ConversationScoped;@Named @ConversationScoped public class CdiBeanConversationScoped implements Serializable { private int counter; public int getCounter() { return counter; } public void increment(ActionEvent e) { counter++; } }<h:outputText id='counter' value='Conversation scoped counter: #{cdiBeanConversationScoped.counter}'/> <p:commandButton value='Increment counter' process='@this' update='counter' actionListener='#{cdiBeanConversationScoped.increment}'/>The counter will expire after 1 min. if no access to the bean happens within this time interval. Simple push the button to increment the counter, wait longer than 1 min. and increment it again. You will see that counter was reseted. Reference: Configure timeout for CDI conversations from our JCG partner Oleg Varaksin at the Thoughts on software development blog....
jboss-hibernate-logo

Hibernate: save vs persist and saveOrUpdate

What is difference between save and saveOrUpdate or Difference between save and persist are common interview question in any Hibernate interview, much like Difference between get and load method in Hibernate. Hibernate Session class provides couple of ways to save object into database by methods like save , saveOrUpdate and persist . You can use either save() , saveOrUpdate() or persist() based upon your requirement for persisting object into Database. Along with Spring framework Interview questions, Hibernate questions are also quite popular on J2EE interviews because of its status as leading ORM. It’s good to prepare some questions from Hibernate before appearing in any J2EE interviews. One of them is Difference between save , saveOrUpdate and persist, which we will see in this Hibernate article. Difference between save and saveOrUpdate in Hibernate Main difference between save and saveOrUpdate method is that save() generates a new identifier and INSERT record into database while saveOrUpdate can either INSERT or UPDATE based upon existence of record. Clearly saveOrUpdate is more flexible in terms of use but it involves an extra processing to find out whether record already exists in table or not. In summary save() method saves records into database by INSERT SQL query, Generates a new identifier and return the Serializable identifier back. On the other hand saveOrUpdate() method either INSERT or UPDATE based upon existence of object in database. If persistence object already exists in database then UPDATE SQL will execute and if there is no corresponding object in database than INSERT will run. Difference between save and persist method in Hibernate In last section we saw What are difference between save and saveOrUpdate and now we will see Difference on save vs persist method.First difference between save and persist is there return type. Similar to save method persist also INSERT records into database but return type of persist is void while return type of save is Serializable object. Another difference between persist and save is that both methods make a transient instance persistent. However, persist() method doesn’t guarantee that the identifier value will be assigned to the persistent instance immediately, the assignment might happen at flush time. One more thing which differentiate persist and save method in Hibernate is that is there behaviour on outside of transaction boundaries. persist() method guarantees that it will not execute an INSERT statement if it is called outside of transaction boundaries. save() method does not guarantee the same, it returns an identifier, and if an INSERT has to be executed to get the identifier (e.g. ‘identity’ generator), this INSERT happens immediately, no matter if you are inside or outside of a transaction. Fourth difference between save and persist method in Hibernate is related to previous difference on save vs persist. Because of its above behaviour of persist method outside transaction boundary, its useful in long-running conversations with an extended Session context. On the other hand save method is not good in a long-running conversation with an extended Session context.These were some differences between save, saveOrUpdate and persist method of Hibernate. All three method are related to saving Object into database but there behaviour are quite different. Knowledge of save , persist and saveOrUpdate not only helps to decide better use of Hibernate API but also help you to do well in Hibernate interviews. Don’t forget to share! Reference: Difference between save vs persist and saveOrUpdate in Hibernate from our JCG partner Javin Paul at the Javarevisited blog....
software-development-2-logo

Software Development tips and tricks

These are just some tips and tricks I learnt over my career that I’d like to share. This list does not contains silver bullets and it doesn’t pretend to be complete or be an absolute truth. It’s just a list that I hope may be helpful for someone. 1 ) Push the coding to the last This point can be also be read as think before coding. I found myself, lots of times, especially in the beginning of my career, in rush of writing classes, methods, interfaces as soon as I was receiving a spec for a new functionality. This impulse turned out 90% of the times into a PAINFUL situation. The spec was unclear and so unclear was my code; The spec was too ‘code oriented’ and so blindly coding this was producing wrong design/ implementation that needed to be trashed out and completely re-designed; Many other are the disadvantages of writing code straight away after receiving a spec. So, lesson learnt and this is what I’m doing now after receiving a spec/story to develop:I stay away from the keyboard! I print the spec (sorry amazonian jaguars ) and I take my time to read them carefully. Do not think that everything you will read there is exempt of mistakes or cannot be done in better and simpler ways. At the end of the day, people who wrote the specs, know little or nothing about the software, what they know is how to make more money with new functionality. If something is not clear to you, it will not clarify magically by itself if you start to code. Ask questions to other colleagues, to the business, clarify as much as possible and only when you feel confident, when you see the real pitcure of what they really want, then and only then you can switch the monitor on and click on the eclipse icon…2 ) Simple = perfect Make the 2 famous principles, KISS and YAGNI, part of your blood, skin and bones. Strive for simplicity, forget about the trends, focus on the most basic thing that will give you what is needed. Don’t think straight about XML configuration, spring/seam framework, drools, aspects, multithreading solutions, ejbs, or whatever complex/cool technology you know or you heard out there, nobody really cares about the technologies you use. What everyone cares is that your code does what is supposed to do, it is READABLE and it is MAINTAINABLE. Pure java is enough to cover 90% or more of everything you need. Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live. Make him happy, write simple, clear straightforward code. I remember I read somewhere that, if you read your code after 1 or 2 years and you immediately understand everything is doing and you cannot simplify it more, than your code is PERFECT.3 ) Paper and pen I never found a tool more useful than paper and pen to design software. Before writing software I usually spend a bit of time trying to put the idea of the design down on paper. I then , if in doubt, go through it with a colleague. Because it is on paper I can fast go to the point with my pair and he can quick tell me if I’m missing something. Knowing that you are missing something in a piece of paper, it’s far way better then knowing that you are missing something in the code! So don’t waste time using UML tools, unless what you are doing is big-fantastic-amazing-new architectural prototype. 4 ) Don’t leave for tomorrow what you can do today If you are fixing a bug or adding new functionality and you notice in the existing code, DUPLICATION or BAD NAMES or a POSSIBLE BUG then FIX IT IMMEDIATELY. Don’t wait for the next sprint and don’t add a technical story in the technical backlog. Technical stories laid in the backlog for long time, when/if it will be the time to work on it, it will be more complicated to re-understand the context of the problem and fix it. The exception it’s when the fix/refactoring is too complex and required long time, then it’s appropriate to create a story in the technical backlog! 5 ) You have time! Really, you have time! Don’t rush. There is no competition and you are not at the programming Olympics. Your job is to deliver good quality code. That’s it. This is your job! If you feel that a task takes longer that what you initially estimated, just make the team aware in the next stand up and that’s it. If a client/manager is screaming above your shoulders because he wants something faster than you can deliver, it’s not your problem!!! When they say ‘I want this functionality to be ready asap’ translated in Truthlish it means ‘I want this functionality to be PERFECT with NO BUGS asap’. They will be happier to wait more and have less bugs than having a fast release full of issues. So take your time and be intransigent on the quality level of your software and forget about external pressures! 6 ) Implement leaves first So, you just received a brand new story to develop and you want to implement it right. For example the story is about calculating item prices. One price for each item. Each price is obtained with a different calculation. Choose one item price logic and as first thing write a unit test against this logic. Don’t be stressed about implementing the whole design or writing interfaces, abstract classes etc. Focus on one small leaf per time! When the first leaf is finished, start with a second test for the second small logic you want to implement. The design will come out almost by itself. The tests will tell you which direction is best to take.7 ) Do Pair programming! I fully applied this technique only recently (less than 1 year ago) and I have to say, it’s powerful! It is twice productive than working alone, the quality of the code is superior, the development speed is increased. A strength of this technique is the fact that is funny. being funny and so more stimulating means that you are more focused and you pay more attention to details. You can learn a lot doing pair programming, so push for it as much as you can! 8 ) Rarely use checked Exceptions Every time I use an API that force me to put around its method call the try and catch block, it makes me nervous, like a violent psychopath, but often I don’t know where they leave. Especially if there is nothing I can do about the exception. What the hell I’ m supposed to do with this error? If you want to use checked Exception used them ONLY if the client can reasonably recover from it at run time! Remember that checked exceptions will spread all over your design in case you need to extend the behavior! 9 ) Say NO to Hacks Programming is like sex. One mistake and you have to support it for the rest of your life. (Michael Sinz). And Hacks ARE mistakes! Simply don’t implement hacks. I did it in the past, for whatever reasons ( no time,pressure, desire to release a feature as soon as possible, managers screaming, Orcs, Leprechauns, whatever), and now after years we need to maintain them. Hacks are difficult to understand,they break the normal logic flow of your code and they are hard to die! You implement an hack today and tomorrow (1 year after maybe ) someone else will need to fix a bug on this hack and ..well good luck with that! Spend more time on the spec if the hack is a business request, and explain why this will cost a lot to maintain. Propose other solutions, discuss it with your team, a better solution is on the way! 10 ) Forget about comments, just write proper names! Write proper names when writing packages, classes, methods and variables. Write names that make sense, ask a review before committing your code, but don’t explain verbally what you have done, try first letting your reviewer read the code, and see how good you were in writing self explanatory code! Comments need to be maintained, otherwise they are misleading. How often did you fix a bug in the code and you changed the class documentation?me, rarely!Use javadoc only if it is really necessary!and if you do,then remember to update them every time you change the code and enforce the same behavior in your team! 11 ) Reinvent the wheels Read books, blogs, tutorial, etc as much as possible, but always with a critical and open mind! The same apply when listening to your team or leader. Don’t be fooled by authorities, think always with your own mind. If you decide to go for some approach it must be because you believe in it. Because you see good reasons to do so. If you feel that something could be done better or you see problems in the approach you are using , discuss it with your team and try to clarify your doubts. If after talking to the team you still feel that things should be done differently, then push for better approaches and fight for your ideas! Sometimes, to progress, you need to reinvent the wheels or at this time we were all developing in FORTRAN. Don’t forget to share! Reference: Some development tips and tricks from our JCG partner Marco Castigliego at the Remove duplication and fix bad names blog....
software-development-2-logo

Programming Like Kent Beck

Three of us, namely Stig, Krzysztof, and Jakub, have had the pleasure of spending a week with Kent Beck during Iterate Code Camp 2012, working together on a project and learning programming best practices. We would like to share the valuable lessons that we have learnt and that made us better programmers (or so we would like to think at least). Values Underlying the Programming Style Most of the things that we have learnt stem from three basic values: communication, simplicity, and flexibility (in the order of importance). We will introduce them briefly here, you can find a more detailed description in Kent’s book Implementation Patterns, along with few fundamental practices such as the application of symmetry.Communication Programs are read much more often than written and therefore should communicate clearly their intent. Code is primarily means of communication. (For a typical enterprise system, a lot of code will be modified by many programmers over 5 – 15 years and they’ll all need to understand it.)Simplicity Eliminate excess complexity. Apply simplicity at all levels. Simplicity helps communication by making programs easier to understand. Communication helps simplicity by making it easier to see what is excess complexity.Flexibility “Making workable decisions today and maintaining the flexibility to change your mind in the future is a key to good software development.” — Implementation Patterns, Kent Beck Programs should be flexible in the ways they change, they should make common changes easy or at least easier. Complexity can often arise from excess flexibility, but if that flexibility is not needed then it is waste. The best kind of flexibility comes from simplicity coupled with extensive tests. Trying to create flexibility through design phases or the likes usually ends up with this kind of “complex flexibility”. Most of the time you do not have enough information to make a proper design decision about where your program will need to change, so the lean mantra of postponing your decisions til the last responsible moment is a valid and useful approach. That is when you have the best grounds for any decision.Summary Write code that communicates well what and why is done so that your co-workers and future maintainers can take it over without too much cost. (Yet you have to assume some level of skill and knowledge in you audience.) You cannot foresee the future so keep your code simple and sufficiently flexible so that it can evolve.Key Learnings 1. You Ain’t Gonna Need It! What is today’s demo? What test to start with? Before we arrived, we settled on a topic that we thought would be fun and challenging. We settled on trying our hands at prototyping a highly scalable, distributed database. We expected upon arrival to spend few hours discussing approaches to how we should actually implement this. After all, there are lot of things to consider: replication strategies, consistent hashing, cluster membership auto-discovery, and conflict resolution, to name a few. If you have just 5 days, you need to plan how to implement it in the simplest possible way. What to do. What to skip. Right? Wrong. Instead of any planning, Kent just asked us what would be the demo we would like to show at the end of the day. And his next question was what test to write. It turned out to be a very smart approach because we actually implemented only a very small subset of the possible functionality, deciding daily what to do next based on our experiences with the problem so far. Any discussion from the beginning longer than 10 minutes would be 90% wasted time. This doesn’t mean that planning is bad (though the resulting plans are usually useless), it only means that we usually do much more of it than we actually need. Getting real feedback and basing our decisions on that, on real data, is much more practical and valuable than any speculations. Therefore prefer on-going planning based on feedback and experience to extensive up-front planning. Ask yourself: What am I going to present at the next demo/meeting/day? What test to write to reflect that and thus guide my development effort?2. Write High-Level Tests to Guide the Development The goal of our second day was replication, demonstrated by writing to one instance, killing it, and reading the (replicated) data from the second instance. We started by writing a corresponding test, which follows these steps closely, nearly literally: List<Graft> grafts = Graft.getTwoGrafts(); Graft first = grafts.get(0); Graft second = grafts.get(1);first.createNode().put("key", "value") first.kill();assertNotNull(second.getNodeByProperty("key", "value")); (The API of course evolved later into something more general.) Now the interesting thing is that this is not a unit test. It is basically an integration test, or to use a less technical term, a story test exercising a rather high-level feature. A feature of interest to the customer. While a unit tests tells me “this class is working as intended,” a story test tells me “this feature works as intended”. I used to think about TDD at the unit/class level but this is TDD at a much higher level. It has some interesting properties:It helps measure real progress of the project because it exercises something that is actually meaningful to the customer (if you permit me to use this “customer” in a little blurry fashion) It helps keep you focused on delivering business functionality (by being on its level) It’s likely to stay mostly unchanged and live much longer than unit tests or actually most of the code base because it is on such a conceptual levelNow, according to the testing pyramid, there are of course fewer story tests than there are unit tests, and story tests do not test all possible cases. Does it mean that you need to do all these story tests and then do them again only in smaller unit tests? No, that is not the point. Getting back to the principle of flexibility and the way things change, create additional unit tests only when you need them. For example when you encounter some case where the first story test did not actually “capture the whole” properly, or when you discover a really important corner case, or when you want to focus on implementing a part of the overall solution. Speculating about failure points can be just as wasteful as speculating about design.3. Best Practices for [Unit] Testing Write Tests From the End We normally start a test with an idea of what we want to verify, but we may be not completely sure how to arrive there. Therefore it is good practice to express what we do know, the desired end-result, first. We do this in the form of an assertion and only then shift our focus to figuring how to get there. That’s how we started the test of replication in Graft, shown above. This is an application of the key principle of focus.Write Implementation in Tests, Refactor Later You know the functionality you want and so you start writing the test for it. Instead of thinking about how it should be organized (what classes to create, where to put them, whether to use a factory class or a factory method), why not initially write the code directly in the test method? You can always factor out the code later. This way you can focus on what’s really important – describing the desired functionality with a test – instead of being distracted by secondary considerations. Additionally, by postponing the decision about the internal organization of the implementation, you will have more knowledge when actually deciding it and you will likely end up with a better solution. Key principles: Focus, avoiding premature decision-making.Bottom-up Design Avoids:assuming too much, too early locking yourself into a specific design and premature design restricting yourself (you will usually end up with the design you first intended)Start by implementing small parts of functionality. Then combine them to form more complex behavior. Don’t get distracted by dependencies, write simple stubs for them that you will replace later with real implementations. Using this technique you are not bound to design decisions taken at the beginning as in the ‘top-down’ approach. It requires a little bit of intuition and some experience, but combined with TDD it helps to make better design and implementation. We found this technique quite useful as we didn’t know the final solution at the beginning. When developing Graft, we haven’t designed the whole application up-front. We picked a use case on the first day, implemented it, and continued by choosing and implementing other use cases each day.Act & Assert at the Same Level of Abstraction Our Graft DB has a telnet-like interface for receiving commands from users. Consider the following two (simplified) variations of the addComment test: // Test 1 Graft db = ...; this.subject = new CommandProcessor(db); subject.process("addComment eventId my_comment");assertThat(subject.process("getComments eventId")).isEqualTo("my_comment"); // Test 2 (same setUp) subject.process("addComment eventId my_comment");assertThat(db.getComments("eventId")).containsOnly("my_comment"); The first test, while testing the addComment command, uses another command – getComments – to check the resulting state. It uses only a single API entry point – subject – during the whole test. The second test accesses directly the underlying database instance and its API to get the same data, i.e. aside of subject it uses also the underlying db. Thus the first test is not truly “unit” test as it depends on the correctness of another method of the tested class. The second test is much more focused and potentially simpler to write as it accesses directly the target data structure and thus performs the checks right at the source. We would argue that tests like the first one, which perform all operations at the same level, namely the level of the public API of the object under test, are better. “Better” here means easier to understand and, more importantly, much more stable and maintainable because they are not coupled to the internal implementation of the functionality being tested. The price of increased complexity of these unit-integration tests (due to relying on multiple methods in each test) is absolutely worth the gain. Tests similar to the second one are none the less more common, either accessing directly the underlying layers (an object, property, database, …) or using mocks to gain the possibility of direct verification of side-effects. These techniques often lead to coupled and hard to maintain tests and should be limited to the “private unit tests,” as described and argued in Never Mix Public and Private Unit Tests!4. Focus!Put tasks that pop up on a Later list instead of doing them at once Focus on fixing the test first – however ugly and simple (and refactor later) Focus on the current needs – no premature abstractionOne thing that really caught our attention is Kent’s focus on what he is doing at any moment. Being focused means concentrating on finishing that one thing you’re currently doing without getting distracted by other concerns, however important or simple to fix. (Side note: Never say never.) When having a failing test, focus on making it pass quickly, no matter how ugly the (temporary) solution is or that it “cuts corners.” If you notice along the way something else that needs to be done – giving a method a better name, removing a dead code, fixing an unrelated bug – don’t do it, put it on a task list and do it later. Otherwise you risk losing your attention and the current context. Do one thing at a time. When making a test pass, focus just on that, and leave concerns such as good code til the subsequent refactoring (which should follow shortly). (This reminds me of the Mikado method for large-scale refactorings, whose main purpose is also to keep focus and not getting lost in many sidetracks.) A related practice is to focus on the current needs when implementing a feature, without speculatively designing for tomorrow’s needs (possibly literally tomorrow). Focus on what is needed right now, to finish the current task, and make the solution simple so that it will be easy to refactor and extend for both known and unforseen future needs. As Kent argues in Implementation Patterns (and others elsewhere), we’re very bad at speculative design, i.e. the future needs are usually quite different from what we expected and therefore it’s better to create solutions that are simple and with that also flexible. You of course need to pay some attention to the future needs but far less than we tend to do. Admit to yourself that you cannot predict the future. Even if you know what else is going to be required, how can you know that no new requirements that would change or delay that (up til infinity) will appear?Some other stuff we learned Parallel Design Parallel design means that when changing a design, you keep the old design as long as possible while gradually adding the new one and then you gradually switching to the new design. This applies both at large and also (surprisingly) small scale. Though it’s costly – you have to figure out how to have them both run and it requires more effort to have them both – it often pays off because it’s safer and it enables resumable refactoring, discussed below. An example of a high-level parallel design is the replacement of a RDBMS with a NoSQL database. You’d start by implementing the code for writing into the new DB, then you would use it and write both to the old and the new one, then you would start also reading from the new one (perhaps comparing the results to the old code to verify their correctness) while still using the old DB’s data. Next you would start actually using the NoSQL DB’s data, while still writing to/reading from the old DB (so that you could easily switch back). Only when the new DB proves itself would you gradually remove the old DB. An example of a micro-level parallel design is the replacement of method parameters (message etc.) with the object they come from (an Edge), as we did for notifyComment: - public void notifyComment(String message, String eventName, String user) { - notifications.add(user + ": commented on " + eventName + " " + message); --- + public void notifyComment(Edge target) { + notifications.add(target.getTo().getId() + ": commented on " + target.getFrom().getId() + " " + target.get("comment")); The steps were:Adding the Edge as another parameter (Refactor – Change Method Signature) Replacing one by one usages of the original parameters with properties of the target Edge (Infinitest running tests automatically after each change to verify we’re still good) Finally removing all the original parameters (Refactor – Change Method Signature)The good thing is that your code always works and you can commit or stop at any time.Resumable Refactoring If you apply the practices described below when performing a larger-scale refactoring then your code will always be buildable and you will be able to stop in the middle of the refactoring and continue (or not) at any later time. The practices are parallel design and going forward in small, safe steps i.e. steps that provably do not break anything. In essence it’s about keeping the oversight and control, at each step you know exactly what you did which broke the test and this way you can not only quickly put the application back in a working state, but also quickly hone in on what exactly caused the problem. (The Mikado method mentioned above is a great guide for refactoring systems where every change reveals a number of other changes required to make it possible. Of course the ultimate resource for refactoring legacy systems is Michael Feathers’s Working Effectively with Legacy Code).Refactor on Green, at Will The dogmatic TDD practitioners claim that you cannot change the behavior of production code unless some test forces you to do so. Thus it might be refreshing to hear that Kent doesn’t hesitate to generalize the code (e.g. by replacing fakes with a real implementation) even though there are no tests that require the generalization to pass. On the other hand it doesn’t mean that forcing a generalization by tests is a bad thing or that you should not do it. This is basically a question of the economics of software development, of balancing the cost (of writing and maintaining tests) with the benefits (defect and regression prevention). It’s a question of the risk involved and of your confidence in your coding skills. Kent has rightfully much more confidence in his coding skills (and much more experience with it) than many of us. Our confidence is quite low based on past experiences and therefore we’ll probably go on enforcing generalizations with tests. We’d close this topic by quoting Kent speaking about how much testing to do: I get paid for code that works, not for tests, so my philosophy is to test as little as possible to reach a given level of confidence (I suspect this level of confidence is high compared to industry standards, but that could just be hubris). If I don’t typically make a kind of mistake (like setting the wrong variables in a constructor), I don’t test for it. I do tend to make sense of test errors, so I’m extra careful when I have logic with complicated conditionals. When coding on a team, I modify my strategy to carefully test code that we, collectively, tend to get wrong. Different people will have different testing strategies based on this philosophy, but that seems reasonable to me given the immature state of understanding of how tests can best fit into the inner loop of coding. Ten or twenty years from now we’ll likely have a more universal theory of which tests to write, which tests not to write, and how to tell the difference. In the meantime, experimentation seems in order.Symmetry in the Code Symmetry is an abstract concept, more specific than the values of communication, simplicity, and flexibility, but still rather general. In Implementation Patterns Kent refers to symmetry as a programming principle. Code with symmetries is easier to grasp than code that is asymmetric. It’s easier to read and understand. So what, more specifically, is symmetric code? To quote Kent again: Symmetry in code is where the same idea is expressed the same way everywhere it appears in the code. Imagine a code where the some idea, like “getting the last updated document from the DB,” is implemented several times. The code is asymmetric if the method names differ, if they do things in different order, if there are some important differences between them. When you ask yourself “what does this method do” and you arrive at pretty much the same answer for all methods in spite of all the differences, then you have some violation of symmetry. An example of symmetry in code is keeping the abstraction level consistent within a code block, like a method. if the block is a mix of low level assignments and method calls, you may want to see if you can abstract away the assignments with a method. The astute reader have probably noticed that consistency is a large part of symmetry: being consistent with abstraction levels, consistent with method naming, and so on. But symmetry is more abstract in that it deals more with ideas, not rules (such as the rule that class and method names should be in camel-case).And What Do you Know, Even Some More …Manage your energy – be aware of your energy and stop before becoming tired. Don’t forget to take breaks. A rested developer is multiple times more productive than a tired one. (J.B. Rainsberger in The Economics of Software Design shares the story of working so intensively that he became exhausted and totally unproductive). Pair-programming is a skill one must consciously learn (and it may be more challenging for some personality types, which shall to be respected) Prefer IDE’s refactorings to manual changes – f.ex. none of us had ever before used the “inline” refactoring while Kent uses it all the time. Once you master the refactorings, they’ll become much more efficient than changing things manually and, more importantly, they avoid the small but non-zero probability of breaking something (remember that Murphy guy who said – what can break will break)Code You can find code for Iterate Code Camp 2012 on GitHub – bit.ly/codecamp2012Conclusion We hope that you, our dear reader, find some of these ideas interesting and have got inspired to try them in your daily practice, as we did.Related ResourcesJakub’s blog post Principles for Creating Maintainable and Evolvable Tests summarizes some complementary principles for writing tests that he learnt from Kent Rich Hickey: Simple Made Easy – a great talk that explains the crucial difference between “simple” (vs. complex) and “easy” and how our languages and tools aren’t as simple as they should be, often because they try to be easyReference: Programming Like Kent Beck from our JCG partner Jakub Holy at the The Holy Java blog....
twitter-logo

Twitter REST API from Scala and Java using signpost

If you’ve read some other articles on this blog you might know that I like creating visualizations of various datasets. I’ve just started a small project where I want to visualize some data from Twitter. For this I want to retrieve information about followers and profile information directly from twitter. I actually started looking for a set of all twitter accounts, but could only find one that was two years old. So, only option left, directly access the twitter API and get the data myself. There are a couple of open source libraries out that we can use directly from Scala (or java) but as far as I could see they use the old v1 API and not the v1.1 API. The old API has a very strict data rate limit, which is a bit lighter in the new API. And besides that I’m more interested in the raw data and parsing the returning JSON isn’t that hard with Scala (or Java for that matter).Register an application at twitter First thing to do, and easiest way to get started is registing a new application for your twitter account. Go to https://dev.twitter.com/apps/new and create a new application. Don’t worry about the urls, since we won’t be using the OAuth callback mechanism:Depending on what you want to do with the API you need to give additional permissions to this app. Default is ‘read-only’, if you want to allow your new application to post or access your direct messages you need to update the permissions. This is done from the settings page of your application:Once you’ve created the application and setup the correct permissions you can generate an access token. Doing this will avoid having to go through the complete OAuth dance. You do this by going to your new app details and at the bottom select the ‘create my access token’ option.Now you’ll have a set of tokens (see the details part of your applications):We’ll use these tokens to authenticate the requests we’ll make to twitter.Using a OAuth library The OAuth protocol is a pretty good documented protocol, but implementing it yourself is a lot of work and very error-prone. Luckily there are many OAuth libraries that can help you. I’ve tried a couple and the one that’s most easy to use (at least for me) was signpost. The examples below show how to do this from Scala, but you can follow the same approach for Java. First the dependencies. I’ve used sbt and from signpost I use the client with support for HTTP commons. In sbt add the following: .. libraryDependencies ++= Seq( 'oauth.signpost' % 'signpost-core' % '1.2', 'oauth.signpost' % 'signpost-commonshttp4' % '1.2', 'org.apache.httpcomponents' % 'httpclient' % '4.2', ... ) For maven you can use the same libraries. Next we can write a simple test to see if everything is working. In java it looks like this: import oauth.signpost.OAuthConsumer; import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer; import org.apache.commons.io.IOUtils; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; public class Tw { static String AccessToken = 'access token for your app'; static String AccessSecret = 'access secret for your app'; static String ConsumerKey = 'consumer key for your app'; static String ConsumerSecret = 'consumer secret for your app'; /** * @param args */ public static void main(String[] args) throws Exception { OAuthConsumer consumer = new CommonsHttpOAuthConsumer( ConsumerKey, ConsumerSecret); consumer.setTokenWithSecret(AccessToken, AccessSecret); HttpGet request = new HttpGet('http://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=josdirksen'); consumer.sign(request); HttpClient client = new DefaultHttpClient(); HttpResponse response = client.execute(request); int statusCode = response.getStatusLine().getStatusCode(); System.out.println(statusCode + ':' + response.getStatusLine().getReasonPhrase()); System.out.println(IOUtils.toString(response.getEntity().getContent())); } } And in Scala it looks pretty much the same: import org.apache.http.client.HttpClient import org.apache.http.impl.client.DefaultHttpClient import org.apache.http.client.methods.HttpGet import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer import org.apache.commons.io.IOUtils object TwitterPull { val AccessToken = 'access token for your app'; val AccessSecret = 'access secret for your app'; val ConsumerKey = 'consumer key for your app'; val ConsumerSecret = 'consumer secret for your app'; def main(args: Array[String]) { val consumer = new CommonsHttpOAuthConsumer(ConsumerKey,ConsumerSecret); consumer.setTokenWithSecret(AccessToken, AccessSecret); val request = new HttpGet('http://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=josdirksen'); consumer.sign(request); val client = new DefaultHttpClient(); val response = client.execute(request); println(response.getStatusLine().getStatusCode()); println(IOUtils.toString(response.getEntity().getContent())); } } When you run this the output will look something like this: 200 {"previous_cursor_str":"0","next_cursor":0,"ids": [48342167,21011010,824959303,97242821,16953163,218083367,20869799,5234221,13604142,80 4783128,271050984,405121284,26470609,50201837,1723451,374494377,120867838,14311946,25 3114713,39554511,7375412,42507395,112806109,92787154,218238023,110443797,76922155,198 798790,294104985,305625416,217698029,21803482,14927822,15453445,15715866,15657036,186 956616,36028164,70380613,326158542,573546312,14401332,521488579,9108612,576970378,293 236313,16398366,16220300,15234937,32000283,439444353,14300622,67204409,155850135,1419 8255,32264673,15852981,313248158,20123099,608942046,234930032,36896958,18466675,45496 942,330899833,18980755,88253383,461023805,31175627,11044952,142780445,63175189,107991 607,94830953,600993241,6195002,115391430,550080945,381418927,168603682,142388604,8258 462,218411138,30450578,77728346,2521381,182867524,494119147,29426983,572417260,943448 49,325413275,389354525,501438275,164346498,22730282,8293302,21085554,341645357,569788 53,180507788,10074002,22536424,14247654,581293627,15259428,483317230,462826270,477464 1,15366832,96850673,278486993,22273826,17716679,14566626,158473088,20461042,161242434 ,43756629,40163100,141165981,5325152,7620782,266749648,524476136,557713614,39602637,1 8843154,1623,565954426,39639621,166672305,18683074,233118689,44876099,235258223,21931 0062,10699922,12660502,218030046,91552210,19361980,206645598,35346200,58440021,470388 557,26495649,59066453,40292255,543375441,33242290,6015852,317150447,22935775,23230034 6,476045917,90913482,249088920,67658976,614873,522722520,186766721,285517705,71683175 ,131444964,166501605,477920664,38154550,18738205,8861832,15594932,18536741,7595202,46 5378842,11838952,14848133,431696576,14358671,414520167,222578501,67058139,28976735,95 601387,426582611,24874129,418762594,128157235,106030956,31352215,18733178,260196778,1 53179029,91842580,229494512,83414433,285579699,19957600,54295155,14929418,51516573,20 0076011,18758733,17776895,59397841,216802709,149834999,327507356,8200322,174345369,10 8636400,27504001,326877592,139919716,49949338,215035403,118421144,49410665,149550914, 18446431,25662335,261725134,267634174,57737391,146506056,126964949,71055234,20870640, 210196418,222806923,13290742,72247756,180410163,14784480,36684216,25611502,95614691,5 4629161,112967594,181656257,17994312,72918901,140082918,149087212,137272324,99534020, 121755576,93964779,35848342,43059008,34704029,87672717,113137792,17863333,90407665,90 591814,54297023,57924897,87551006,28300354,48990752,26188013],"previous_cursor":0, "next_cursor_str":"0"If you get a 403 check whether the tokens match. Happy coding and don’t forget to share! Reference: Access the Twitter REST API (v1.1) from Scala and Java using signpost from our JCG partner Jos Dirksen at the Smart Java blog....
java-logo

Java Hidden code

Sometime ago I came across the issue of invisible characters in Strings. These can really cause confusion because they are invisible. String a = "Hello\u200e"; String b = "Hello\u200f"; System.out.println('\'' + a + "' and '" + b + "' are length " + a.length() + " and " + b.length() + ", equals() is " + a.equals(b));prints 'Hello?' and 'Hello?' are length 6 and 6, equals() is falseInvisible identifiers Imagine my reaction to discovering you can use invisible characters in identifiers in Java :P. These characters cannot appear at the start of identifiers in Java but can be anywhere else. System.out.println("String _\u200e = \"Hello \";"); System.out.println("String _\u200f = \"World\";"); System.out.println("String _\u200e\u200f = \" !!\";"); System.out.println("System.out.println(_\u200e+_\u200f+_\u200e\u200f);");prints String _? = "Hello "; String _? = "World"; String _?? = " !!"; System.out.println(_?+_?+_??);which when run prints Hello World !!So we have three identifiers which all appear the same because they have different invisible characters in their names !! Amazingly this code compiles, runs and prints all the characters which can be in an identifier but not start them. The code contains \u202e which really messes with the display of the code. for (char c??h = 0; c??h < Character.MAX_VALUE; c??h++) if (Character.isJavaIdentifierPart(c??h) && !Character.isJavaIdentifierStart(c??h)) System.out.printf("%04x <%s>%n", (int) c??h, "" + c??h);Reference: Hidden code from our JCG partner Peter Lawrey at the Vanilla Java blog. ...
jcg-logo

JCG Flashback – 2011 – W37

Hello guys, Time for another post in the JCG Flashback series. These posts will take you back in time and list the hot articles on Java Code Geeks from one year ago. So, let’s see what was popular back then: 5. Simple Twitter: Play Framework, AJAX, CRUD on Heroku This is a cool tutorial on how to build a very basic Ajax-based Twitter clone with Play! Framework which will be deployed on Heroku. Check it out! 4. Java Concurrency Tutorial – Semaphores Java concurrency is always a topic of interest and this article discusses semaphores and how they can be used in order to develop concurrent, multi-threaded code. 3. The OpenJDK as the default Java on Linux This was an announcement back then mentioning that OpenJDK will be the default Java on Linux from now on (with Java SE 7 being the reference implementation). 2. The Java Logging Mess An interesting article discussing the logging approaches used in a Java environment and how those have come to be a bit complicated. Of course don’t miss our other hot article on this topic, 10 Tips for Proper Application Logging. 1. Scala use is less good than Java use for at least half of all Java projects Another article by David Pollak, discussing Scala and how it can be an alternative to Java in many cases and by a certain class of developers. Don’t miss it! That’s all guys. Stay tuned for more, here at Java Code Geeks. And don’t forget to share! Cheers, Ilias ...
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close