Featured FREE Whitepapers

What's New Here?

mybatis-logo

MyBatis Tutorial – CRUD Operations and Mapping Relationships – Part 2

To illustrate we are considering the following sample domain model: There will be Users and each User may have a Blog and each Blog can contain zero or more posts. The Database structure of the three tables are as follows:               CREATE TABLE user ( user_id int(10) unsigned NOT NULL auto_increment, email_id varchar(45) NOT NULL, password varchar(45) NOT NULL, first_name varchar(45) NOT NULL, last_name varchar(45) default NULL, blog_id int(10) unsigned default NULL, PRIMARY KEY (user_id), UNIQUE KEY Index_2_email_uniq (email_id), KEY FK_user_blog (blog_id), CONSTRAINT FK_user_blog FOREIGN KEY (blog_id) REFERENCES blog (blog_id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE blog ( blog_id int(10) unsigned NOT NULL auto_increment, blog_name varchar(45) NOT NULL, created_on datetime NOT NULL, PRIMARY KEY (blog_id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE post ( post_id int(10) unsigned NOT NULL auto_increment, title varchar(45) NOT NULL, content varchar(1024) NOT NULL, created_on varchar(45) NOT NULL, blog_id int(10) unsigned NOT NULL, PRIMARY KEY (post_id), KEY FK_post_blog (blog_id), CONSTRAINT FK_post_blog FOREIGN KEY (blog_id) REFERENCES blog (blog_id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; Here I am going to explain how to fetch and map *-has-One and One-To-Many result mappings. package com.sivalabs.mybatisdemo.domain;public class User { private Integer userId; private String emailId; private String password; private String firstName; private String lastName; private Blog blog; //setters and getters }   package com.sivalabs.mybatisdemo.domain;import java.util.ArrayList; import java.util.Date; import java.util.List;public class Blog {private Integer blogId; private String blogName; private Date createdOn; private List<Post> posts = new ArrayList<Post>(); //setters and getters }   package com.sivalabs.mybatisdemo.domain;import java.util.Date;public class Post { private Integer postId; private String title; private String content; private Date createdOn; //setters and getters } In mybatis-config.xml, configure type aliases for beans. <typeAliases> <typeAlias type='com.sivalabs.mybatisdemo.domain.User' alias='User'/> <typeAlias type='com.sivalabs.mybatisdemo.domain.Blog' alias='Blog'/> <typeAlias type='com.sivalabs.mybatisdemo.domain.Post' alias='Post'/> </typeAliases>   *-has-One Result Mapping: In UserMapper.xml, configure sql queries and result maps as follows: <mapper namespace='com.sivalabs.mybatisdemo.mappers.UserMapper'><resultMap type='User' id='UserResult'> <id property='userId' column='user_id'/> <result property='emailId' column='email_id'/> <result property='password' column='password'/> <result property='firstName' column='first_name'/> <result property='lastName' column='last_name'/> <association property='blog' resultMap='BlogResult'/> </resultMap><resultMap type='Blog' id='BlogResult'> <id property='blogId' column='blog_id'/> <result property='blogName' column='BLOG_NAME'/> <result property='createdOn' column='CREATED_ON'/> </resultMap><select id='getUserById' parameterType='int' resultMap='UserResult'>SELECT U.USER_ID, U.EMAIL_ID, U.PASSWORD, U.FIRST_NAME, U.LAST_NAME, B.BLOG_ID, B.BLOG_NAME, B.CREATED_ON FROM USER U LEFT OUTER JOIN BLOG B ON U.BLOG_ID=B.BLOG_ID WHERE U.USER_ID = #{userId} </select><select id='getAllUsers' resultMap='UserResult'> SELECT U.USER_ID, U.EMAIL_ID, U.PASSWORD, U.FIRST_NAME, U.LAST_NAME, B.BLOG_ID, B.BLOG_NAME, B.CREATED_ON FROM USER U LEFT OUTER JOIN BLOG B ON U.BLOG_ID=B.BLOG_ID </select></mapper> In JUnit Test, write a method to test the association loading. public void getUserById() { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.getUserById(1); System.out.println(user.getBlog()); }finally{ sqlSession.close(); } }   One-To-Many Results Mapping: In BlogMapper.xml configure Blog to Posts relationship as follows: <mapper namespace='com.sivalabs.mybatisdemo.mappers.BlogMapper'><resultMap type='Blog' id='BlogResult'> <id property='blogId' column='blog_id'/> <result property='blogName' column='BLOG_NAME'/> <result property='createdOn' column='CREATED_ON'/> <collection property='posts' ofType='Post' resultMap='PostResult' columnPrefix='post_'></collection> </resultMap><resultMap type='Post' id='PostResult'> <id property='postId' column='post_id'/> <result property='title' column='title'/> <result property='content' column='content'/> <result property='createdOn' column='created_on'/> </resultMap><select id='getBlogById' parameterType='int' resultMap='BlogResult'>SELECT b.blog_id, b.blog_name, b.created_on, p.post_id as post_post_id, p.title as post_title, p.content as post_content, p.created_on as post_created_on FROM blog b left outer join post p on b.blog_id=p.blog_id WHERE b.BLOG_ID=#{blogId} </select><select id='getAllBlogs' resultMap='BlogResult'> SELECT b.blog_id, b.blog_name, b.created_on as blog_created_on, p.post_id as post_post_id, p.title as post_title, p.content as post_content, p.created_on as post_created_on FROM blog b left outer join post p on b.blog_id=p.blog_id </select></mapper> In JUnit Test, write a test method to test blog-to-posts relationship mapping. public void getBlogById() { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); Blog blog = blogMapper.getBlogById(1); System.out.println(blog); List<Post> posts = blog.getPosts(); for (Post post : posts) { System.out.println(post); } }finally{ sqlSession.close(); } }   Spring Integration MyBatis-Spring is a subproject of MyBatis and provides Spring integration support which drastically simplifies the MyBatis usage. For those who are familiar with Spring’s way of Dependency Injection process, using MyBatis-Spring is a very simple. First let us see the process of using MyBatis without Spring. 1. Create SqlSessionFactory using SqlSessionFactoryBuilder by passing mybatis-config.xml which contains DataSource properties, List of Mapper XMLs and TypeAliases etc. 2. Create SqlSession object from SqlSessionFactory 3. Get Mapper instance from SqlSession and execute queries. 4. Commit or rollback the transaction using SqlSession object. With MyBatis-Spring, most of the above steps can be configured in Spring ApplicationContext and SqlSession or Mapper instances can be injected into Spring Beans. Then we can use Spring’s TransactionManagement features without writing transaction commit/rollback code all over the code. Now let us see how we can configure MyBatis+Spring integration stuff. Step#1: Configure MyBatis-Spring dependencies in pom.xml   <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency><dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.1.1</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>3.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.1.1.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> <scope>runtime</scope> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>2.2.2</version> </dependency>   Step#2: You don’t need to configure Database properties in mybatis-config.xml. We can configure DataSource in Spring Container and use it to build MyBatis SqlSessionFactory. Instead of SqlSessionFactoryBuilder, MyBatis-Spring uses org.mybatis.spring.SqlSessionFactoryBean to build SqlSessionFactory. We can pass dataSource, Mapper XML files locations, typeAliases etc to SqlSessionFactoryBean. <bean id='dataSource' class='org.apache.commons.dbcp.BasicDataSource'> <property name='driverClassName' value='${jdbc.driverClassName}'/> <property name='url' value='${jdbc.url}'/> <property name='username' value='${jdbc.username}'/> <property name='password' value='${jdbc.password}'/> </bean><bean id='sqlSessionFactory' class='org.mybatis.spring.SqlSessionFactoryBean'> <property name='dataSource' ref='dataSource' /> <property name='typeAliasesPackage' value='com.sivalabs.mybatisdemo.domain'/> <property name='mapperLocations' value='classpath*:com/sivalabs/mybatisdemo/mappers/**/*.xml' /> </bean> Step#3: Configure SqlSessionTemplate which provides ThreadSafe SqlSession object. <bean id='sqlSession' class='org.mybatis.spring.SqlSessionTemplate'> <constructor-arg index='0' ref='sqlSessionFactory' /> </bean>   Step#4: To be able to inject Mappers directly we should register org.mybatis.spring.mapper.MapperScannerConfigurer and configure the package name where to find Mapper Interfaces.   <bean class='org.mybatis.spring.mapper.MapperScannerConfigurer'> <property name='basePackage' value='com.sivalabs.mybatisdemo.mappers' /> </bean>   Step#5: Configure TransactionManager to support Annotation based Transaction support.   <tx:annotation-driven transaction-manager='transactionManager'/><bean id='transactionManager' class='org.springframework.jdbc.datasource.DataSourceTransactionManager'> <property name='dataSource' ref='dataSource' /> </bean>   Step#6: Update the Service classes and register them in Spring container.   package com.sivalabs.mybatisdemo.service;import java.util.List; import org.apache.ibatis.session.SqlSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;import com.sivalabs.mybatisdemo.domain.User; import com.sivalabs.mybatisdemo.mappers.UserMapper;@Service @Transactional public class UserService { @Autowired private SqlSession sqlSession; //This is to demonstrate injecting SqlSession objectpublic void insertUser(User user) { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.insertUser(user); }public User getUserById(Integer userId) { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); return userMapper.getUserById(userId); }}   package com.sivalabs.mybatisdemo.service;import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.sivalabs.mybatisdemo.domain.Blog; import com.sivalabs.mybatisdemo.mappers.BlogMapper;@Service @Transactional public class BlogService { @Autowired private BlogMapper blogMapper; // This is to demonstratee how to inject Mappers directlypublic void insertBlog(Blog blog) { blogMapper.insertBlog(blog); }public Blog getBlogById(Integer blogId) { return blogMapper.getBlogById(blogId); }public List<Blog> getAllBlogs() { return blogMapper.getAllBlogs(); } }   Note: When we can directly inject Mappers then why do we need to inject SqlSession objects? Because SqlSession object contains more fine grained method which comes handy at times. For Example: If we want to get count of how many records got updated by an Update query we can use SqlSession as follows: int updatedRowCount = sqlSession.update('com.sivalabs.mybatisdemo.mappers.UserMapper.updateUser', user); So far I didn’t find a way to get the row update count without using SqlSession object. Step#7 Write JUnit Tests to test UserService and BlogService.   package com.sivalabs.mybatisdemo;import java.util.List;import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.sivalabs.mybatisdemo.domain.User; import com.sivalabs.mybatisdemo.service.UserService;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations='classpath:applicationContext.xml') public class SpringUserServiceTest { @Autowired private UserService userService;@Test public void testGetUserById() { User user = userService.getUserById(1); Assert.assertNotNull(user); System.out.println(user); System.out.println(user.getBlog()); }@Test public void testUpdateUser() { long timestamp = System.currentTimeMillis(); User user = userService.getUserById(2); user.setFirstName('TestFirstName'+timestamp); user.setLastName('TestLastName'+timestamp); userService.updateUser(user); User updatedUser = userService.getUserById(2); Assert.assertEquals(user.getFirstName(), updatedUser.getFirstName()); Assert.assertEquals(user.getLastName(), updatedUser.getLastName()); }}   package com.sivalabs.mybatisdemo;import java.util.Date; import java.util.List;import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.sivalabs.mybatisdemo.domain.Blog; import com.sivalabs.mybatisdemo.domain.Post; import com.sivalabs.mybatisdemo.service.BlogService;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations='classpath:applicationContext.xml') public class SpringBlogServiceTest { @Autowired private BlogService blogService;@Test public void testGetBlogById() { Blog blog = blogService.getBlogById(1); Assert.assertNotNull(blog); System.out.println(blog); List<Post> posts = blog.getPosts(); for (Post post : posts) { System.out.println(post); } }@Test public void testInsertBlog() { Blog blog = new Blog(); blog.setBlogName('test_blog_'+System.currentTimeMillis()); blog.setCreatedOn(new Date());blogService.insertBlog(blog); Assert.assertTrue(blog.getBlogId() != 0); Blog createdBlog = blogService.getBlogById(blog.getBlogId()); Assert.assertNotNull(createdBlog); Assert.assertEquals(blog.getBlogName(), createdBlog.getBlogName());}}   Reference: MyBatis Tutorial: Part 3 – Mapping Relationships,  MyBatis Tutorial : Part4 – Spring Integration from our JCG partner Siva Reddy at the My Experiments on Technology blog. ...
scala-logo

Scaling Scala vs Java

In my previous post I showed how it makes no sense to benchmark Scala against Java, and concluded by saying that when it comes to performance, the question you should be asking is ‘How will Scala help me when my servers are falling over from unanticipated load?’ In this post I will seek to answer that, and show that indeed Scala is a far better language for building scalable systems than Java. However, don’t expect our journey to get there to be easy. For a start, while it’s very easy to do micro benchmarks, trying to show how real world apps do or don’t handle the loads that are put on them is very hard, because it’s very hard to create an app that’s small enough to demo and explain in a single blog post that is at the same time big enough to actually show how real world apps behave under load, and it’s also very hard to simulate real world loads. So I am going to take one small aspect of something that might go wrong in the real world, and show just one way in which Scala will help you, where Java won’t. Then I will explain that this is just the tip of the iceberg, there are far more situations, and far more features of Scala that will help you in the real world. An online store For this exercise I have implemented an online store. The architecture of this store is in the diagram below:As you can see, there is a payment service and a search service that the store talks to, and the store handles three types of requests, one for the index page that doesn’t require going to any other services, one for making payments that uses the payments service, and another for searching the stores product list which uses the search service. The online store is the part of the system that I am going to be benchmarking, I will implement one version in Java, and another in Scala, and compare them. The search and payment services won’t change. Their actual implementations will be simple JSON APIs that return hard coded values, but they will each simulate a processing time of 20ms. For the Java implementation of the store, I am going to keep it as simple as possible, using straight servlets to handle requests, Apache Commons HTTP client for making requests, and Jackson for JSON parsing and formatting. I will deploy the application to Tomcat, and configure Tomcat with the NIO connector, using the default connection limit of 10000 and thread pool size of 200. For the Scala implementation I will use Play Framework 2.1, using the Play WS API which is backed by the Ning HTTP client to make requests, and the Play JSON API which is backed by Jackson to handle JSON parsing and formatting. Play Framework is built using Netty which has no connection limit, and uses Akka for thread pooling, and I have it configured to use the default thread pool size, which is one thread per CPU, and my machine has 4. The benchmark I will be performing will be using JMeter. For each request type (index, payments and search) I will have 300 threads spinning in a loop making requests with a random 500-1500ms pause in between each request. This gives an average maximum throughput of 300 requests per second per request type, or 900 requests per second all up. So, let’s have a look at the result of the Java benchmark:On this graph I have plotted 3 metrics per request type. The median is the median request time. For the index page, this is next to nothing, for the search and payments requests, this is about 77ms. I have also plotted the 90% line, which is a common metric in web applications, it shows what 90% of the requests were under, and so gives a good idea of what the slow requests are like. This shows again almost nothing for the index page, and 116ms for the search and payments requests. The final metric is the throughput, which shows number of requests per second that were handled. We are not too far off the theoretical maximum, with the index showing 290 requests per second, and the search and payments requests coming through at about 270 requests per second. These results are good, our Java service handles the load we are throwing at it without a sweat. Now let’s take a look at the Scala benchmark:As you can see, it’s identical to the Java results. This is not surprising, since both the Java and the Scala implementations of the online store are doing absolutely minimal work code wise, most of the processing time is going in to making requests on the remote services. Something goes wrong So, we’ve seen two happy implementations of the same thing in Scala and Java, shrugging off the load I give them. But what happens when things aren’t so fine and dandy? What happens if one of the services that they are talking to goes down? Let’s say the search service starts taking 30 seconds to respond, after which point it returns an error. This is not an unusual failure situation, particularly if you’re load balancing through a proxy, the proxy tries to connect to the service, and fails after 30 seconds, giving you a gateway error. Let’s see how our applications handle the load I throw at them now. We would expect the search request to take at least 30 seconds to respond, but what about the others? Here’s the Java results:Well, we no longer have a happy app at all. The search requests are naturally taking a long time, but the payments service is now taking an average of 9 seconds to respond, the 90% line is at 20 seconds. Not only that, but the index page is similarly impacted – users are not going to be waiting that long if they’ve browsed into your site for the home page to show up. And the throughput of each has gone down to 30 requests per second. This is not good, because your search service went down, your whole site is now practically unusable, and you will soon start losing customers and money. So how does our Scala app fair? Let’s find out:Now before I say anything else, let me point out that I’ve bounded the response time to 160ms – the search requests are actually taking about 30 seconds to respond, but on the graph, with 30 seconds next to the other values, they hardly register a line a pixel high. So what we can see here is that while search is unusable, our payments and index request response times and throughput are unchanged. Obviously, customers aren’t going to be happy with not being able to do searches, but at least they can still use other parts of your site, see your home page with specials, and even still make payments for items. And hey, Google isn’t down, they can always use Google to search your site. So you might lose some business, but the impact is limited. So, in this benchmark, we can see that Scala wins hands down. When things start to go wrong, a Scala application will take it in it’s stride, giving you the best it can, while a Java application will likely just fall over. But I can do that in Java Now starts the bit where I counter the many anticipated criticisms that people will make of this benchmark. And the first, and most obvious one, is that in my Scala solution I used asynchronous IO, whereas in my Java solution I didn’t, so they can’t be compared. It is true, I could have implemented an asynchronous solution in Java, and in that case the Java results would have been identical to the Scala results. However, while I could have done that, Java developers don’t do that. It’s not that they can’t, it’s that they don’t. I have written a lot of webapps in Java that make calls to other systems, and very rarely, and only in very special circumstances, have I ever used asynchronous IO. And let me show you why. Let’s say you have to do a series of calls on a series of remote services, each one depending on data returned from the previous. Here’s a good old fashioned synchronous solution in Java: User user = getUserById(id); List<Order> orders = getOrdersForUser(user.email); List<Product> products = getProductsForOrders(orders); List<Stock> stock = getStockForProducts(products); The above code is simple, easy to read, and feels completely natural for a Java developer to write. For completeness, let’s have a look at the same thing in Scala: val user = getUserById(id) val orders = getOrdersForUser(user.email) val products = getProductsForOrders(orders) val stock = getStockForProducts(products) Now, let’s have a look at the same code, but this time assuming we are making asynchronous calls and returning the results in promises. What does it look like in Java? Promise<User> user = getUserById(id); Promise<List<Order>> orders = user.flatMap(new Function<User, List<Order>>() { public Promise<List<Order>> apply(User user) { return getOrdersForUser(user.email); } } Promise<List<Product>> products = orders.flatMap(new Function<List<Order>, List<Product>>() { public Promise<List<Product>> apply(List<Order> orders) { return getProductsForOrders(orders); } } Promise<List<Stock>> stock = products.flatMap(new Function<List<Product>, List<Stock>>() { public Promise<List<Stock>> apply(List<Product> products) { return getStockForProducts(products); } } So firstly, the above code is not readable, in fact it’s much harder to follow, there is a massively high noise level to actual code that does stuff, and hence it’s very easy to make mistakes and miss things. Secondly, it’s tedious to write, no developer wants to write code that looks like that, I hate doing it. Any developer that wants to write their whole app like that is insane. And finally, it just doesn’t feel natural, it’s not the way you do things in Java, it’s not idiomatic, it doesn’t play well with the rest of the Java ecosystem, third party libraries don’t integrate well with this style. As I said before, Java developers can write code that does this, but they don’t, and as you can see, they don’t for good reason. So let’s take a look at the asynchronous solution in Scala: for { user <- getUserById(id) orders <- getOrdersForUser(user.email) products <- getProductsForOrders(orders) stock <- getStockForProducts(products) } yield stock In contrast to the Java asynchronous solution, this solution is completely readable, just as readable as the Scala and Java synchronous solutions. And this isn’t just some weird Scala feature that most Scala developers never touch, this is how a typical Scala developer writes code every day. Scala libraries are designed to work using these idioms, it feels natural, the language is working with you. It’s fun to write code like this in Scala! This post is not about how with one language you can write a highly tuned app for performance that’s faster than the same app written in another language highly tuned for performance. This post is about how Scala helps you write applications that are scalable by default, using natural, readable and idiomatic code. Just like a ball in lawn bowls has a bias, Scala has a bias to helping you write scalable applications, where Java makes you swim upstream. But scaling means so much more than that The example I’ve provided of Scala scaling well where Java doesn’t is a very specific example, but then what situation where your app is failing under high load isn’t? Let me give a few other examples of where Scala’s much nicer asynchronous IO support helps you to write scalable code:Using Akka, you can easily define actors for different types of requests, and allocate them different resource limits. So if certain parts of your single application start struggling or receiving unanticipated load, those parts may stop responding, but the rest of your app can stay healthy. Scala, Play and Akka make handling single requests using multiple threads running in parallel doing different operations incredibly simple, allowing you to have requests that do a lot in very little time. Klout wrote an excellent article about how they did just that in their API. Because asynchronous IO is so simple, offloading processing onto other machines can be safely done without tying up threads on the first machine.  Java 8 will make asynchronous IO simple in Java Java 8 is probably going to include support for closures of some sort, which is great news for the Java world, especially if you want to do asynchronous IO. However, the syntax still won’t be anywhere near is readable as the Scala code I showed above. And when will Java 8 be released? Java 7 was released last year, and it took 5 years to release that. Java 8 is scheduled for summer 2013, but even if it arrives on schedule, how long will it take for the ecosystem to catch up? And how long will it take for Java developers to switch from a synchronous to an asynchronous mindset? In my opinion, Java 8 is too little too late. So this is all about asynchronous IO? So far all I’ve talked about and shown is how easy Scala makes asynchronous IO, and how that helps you scale. But it doesn’t stop there. Let me pick another feature of Scala, immutability. When you start using multiple threads to process single requests, you start sharing state between those threads. And this is where things get very messy, because the world of shared state in a computer system is a crazy world where impossible things happen. It’s a world of deadlocks, a world of updating memory in one thread, but another thread not seeing that change, a world of race conditions, and a world of performance bottle necks because you over eagerly marked some methods as synchronized. However, it’s not that bad, because there is a very simple solution, make all your state immutable. If all your state is immutable, then none of the above problems can happen. And this is again where Scala helps you big time, because in Scala, things are immutable by default. The collection APIs are immutable, you have to explicitly ask for a mutable collection in order to get mutable collections. Now in Java, you can make things immutable. There are some libraries that help you (albeit clumsily) to work with immutable collections. But it’s so easy to accidentally forget to make something mutable. The Java API and language itself don’t make working with immutable structures easy, and if you’re using a third party library, it’s highly likely that it’s not using immutable structures, and often requires you to use mutable structures, for example, JPA requires this. Let’s have a look at some code. Here is an immutable class in Scala: case class User(id: Long, name: String, email: String) That structure is immutable. Moreover, it automatically generates accessors for the properties. Let’s look at the corresponding Java: public class User { private final long id; private final String name; private final String email;public User(long id, String name, String email) { this.id = id; this.name = name; this.email = email; }public long getId() { return id; }public String getName() { return name; }public String getEmail() { return email } } That’s an enormous amount of code! And what if I add a new property? I have to add a new parameter to my constructor which will break existing code, or I have to define a second constructor. In Scala I can just do this: case class User(id: Long, name: String, email: String, company: Option[Company] = None) All my existing code that calls that constructor will still work. And what about when this object grows to have 10 items in the constructor, constructing it becomes a nightmare! A solution to this in Java is to use the builder pattern, which more than doubles the amount of code you have to write for the object. In Scala, you can name the parameters, so it’s easy to see which parameter is which, and they don’t have to be in the right order. But maybe I might want to just modify one property. This can be done in Scala like this: case class User(id: Long, name: String, email: String, company: Option[Company] = None) { def copy(id: Long = id, name: String = name, email: String = email, company: Option[Company] = company) = User(id, name, email, company) }val james = User(1, 'James', 'james@jazzy.id.au') val jamesWithCompany = james.copy(company = Some(Company('Typesafe'))) The above code is natural, it’s simple, it’s readable, it’s how Scala developers write code every day, and it’s immutable. It is aptly suited to concurrent code, and allows you to safely write systems that scale. The same can be done in Java, but it’s tedious, and not at all a joy to write. I am a big advocate of immutable code in Java, and I have written many immutable classes in Java, and it hurts, but it’s the lesser of two hurts. In Scala, it takes more code to use mutable objects than to use immutable. Again, Scala is biased towards helping you scale. Conclusion I cannot possibly go into all the ways in which Scala helps you scale where Java doesn’t. But I hope I have given you a taste of why Scala is on your side when it comes to writing Scalable systems. I’ve shown some concrete metrics, I’ve compared Java and Scala solutions for writing scalable code, and I’ve shown, not that Scala systems will always scale better than Java systems, but rather that Scala is the language that is on your side when writing scalable systems. It is biased towards scaling, it encourages practices that help you scale. Java, in contrast, makes it difficult for you to implement these practices, it works against you. If you’re interested in my code for the online store, you can find it in this GitHub repository. The numbers from my performance test can be found in this spreadsheet.   Reference: Scaling Scala vs Java from our JCG partner James Roper at the James and Beth Roper’s blogs blog. ...
java-logo

Google Guava – Synchronization with Monitor

The Google Guava project is a collection of libraries that every Java developer should become familiar with. The Guava libraries cover I/O, collections, string manipulation, and concurrency just to name a few. In this post I am going to cover the Monitor class. Monitor is a synchronization construct that can be used anywhere you would use a ReentrantLock. Only one thread can occupy a monitor at any time. The Monitor class has operations of entering and leaving which are semantically the same as the lock and unlock operations in ReentrantLock. Additionally, the Monitor supports waiting on boolean conditions. Comparing Monitor and ReentrantLock For starters it would be helpful to do a side by side comparison the Monitor and ReentrantLock. public class ReentrantLockSample { private List<String> list = new ArrayList<String>(); private static final int MAX_SIZE = 10;private ReentrantLock rLock = new ReentrantLock(); private Condition listAtCapacity = rLock.newCondition();public void addToList(String item) throws InterruptedException { rLock.lock(); try { while (list.size() == MAX_SIZE) { listAtCapacity.await(); } list.add(item); } finally { rLock.unlock(); } } }   public class MonitorSample { private List<String> list = new ArrayList<String>(); private static final int MAX_SIZE = 10;private Monitor monitor = new Monitor(); private Monitor.Guard listBelowCapacity = new Monitor.Guard(monitor) { @Override public boolean isSatisfied() { return (list.size() < MAX_SIZE); } };public void addToList(String item) throws InterruptedException { monitor.enterWhen(listBelowCapacity); try { list.add(item); } finally { monitor.leave(); } } } As you can see from the example, both have virtually the same number of lines of code. The Monitor adds some complexity around the Guard object compared to the ReentrantLock Condition. However, the clarity of the addToList method in Monitor more than makes up for it. It could just be my personal preference, but I have always found the while(something==true){ condition.await() } to be a little awkward. Usage Guidelines It should be noted that enter methods that return void should always take the form of: monitor.enter() try{ ...work.. }finally{ monitor.leave(); } and enter methods that return a boolean should look like: if(monitor.enterIf(guard)){ try{ ...work.. }finally{ monitor.leave(); } }else{ .. monitor not available.. }   Boolean Conditions There too many enter methods on the Monitor class to effectively cover in one post, so I am going to pick my top three and present then in order from minimal blocking to the maximum.tryEnterIf – threads will not wait to enter the monitor and will only enter if the guard condition returns true. enterIf – threads will wait to enter the monitor but only if the guard condition returns true. There are also enterIf method signatures that allow for specifying a timeout as well as an enterIfInterruptibly version. enterWhen – threads will wait indefinitely for the monitor and the condition to return true, but can be interrupted. Likewise there are options to specify timeouts as well as an enterWhenUniterruptibly version.  Conclusion I have not yet had the chance to use the Monitor at work, but I can see the usefulness in the granularity of the boolean guard conditions. I have written some basic example code and an accompanying unit test, that demonstrate some of the functionality covered in this post. They are available here. As always your comments/suggestions are welcome. In my next post I will cover more of what can be found in Guava concurrency. ResourcesGuava Project Home Monitor API Sample Code  Reference: Google Guava – Synchronization with Monitor from our JCG partner Bill Bejeck at the Random Thoughts On Coding blog. ...
java-logo

Java Intrinsics and Performance

The original question was How to count the number of 1’s a number will have in binary? I included a performance comparison of using Integer.bitCount() which can be turned into an intrinic i.e. a single machine code instruction POPCNT and the Java code which does the same thing. Question How do I count the number of 1’s a number will have in binary? So let’s say I have the number 45, which is equal to 101101 in binary and has 4 1’s in it. What’s the most efficient way to write an algorithm to do this? Answer Instead of writing an algorithm to do this it’s best to use the built in function. Integer.bitCount() What makes this especially efficient is that the JVM can treat this as an intrinsic. i.e. recognise and replace the whole thing with a single machine code instruction on a platform which supports it e.g. Intel/AMD To demonstrate how effective this optimisation ispublic static void main(String... args) { perfTestIntrinsic();perfTestACopy(); }private static void perfTestIntrinsic() { long start = System.nanoTime(); long countBits = 0; for (int i = 0; i < Integer.MAX_VALUE; i++) countBits += Integer.bitCount(i); long time = System.nanoTime() - start; System.out.printf("Intrinsic: Each bit count took %.1f ns, countBits=%d%n", (double) time / Integer.MAX_VALUE, countBits); }private static void perfTestACopy() { long start2 = System.nanoTime(); long countBits2 = 0; for (int i = 0; i < Integer.MAX_VALUE; i++) countBits2 += myBitCount(i); long time2 = System.nanoTime() - start2; System.out.printf("Copy of same code: Each bit count took %.1f ns, countBits=%d%n", (double) time2 / Integer.MAX_VALUE, countBits2); }// Copied from Integer.bitCount() public static int myBitCount(int i) { // HD, Figure 5-2 i = i - ((i >>> 1) & 0x55555555); i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); i = (i + (i >>> 4)) & 0x0f0f0f0f; i = i + (i >>> 8); i = i + (i >>> 16); return i & 0x3f; }prints Intrinsic: Each bit count took 0.4 ns, countBits=33285996513 Copy of same code: Each bit count took 2.4 ns, countBits=33285996513 Each bit count using the intrinsic version and loop takes just 0.4 nano-second on average. Using a copy of the same code takes 6x longer (gets the same result)   Reference: Java Intrinsics and Performance from our JCG partner Peter Lawrey at the Vanilla Java blog. ...
akka-logo

Non-blocking I/O – discovering Akka

Here comes the time to follow some good practices when implementing actors. One of the most important rules we should follow is avoiding any blocking input/output operations, polling, busy waiting, sleeping, etc. Simply put, actor while handling a message should only depend on CPU and if it doesn’t need CPU cycles it should immediately return from receive and let other actors to process. If we follow this rule strictly, Akka can easily handle hundreds of thousands of messages per second using just a handful of threads. It shouldn’t come as a surprise that even though our application can comprise thousands of seemingly independent actors (e.g. one actor per each HTTP connection, one player in MMO game, etc.), each actor gets only a limited CPU time within a pool of threads. With default 10 threads handling all the actors in the system, one blocking or sleeping actor is enough to reduce the throughput by 10%. Therefore 10 actors sleeping at the same time completely halt the system. For that reason calling sleep() or actively waiting for a response from some other actor is highly discouraged within receive. Unfortunately there is no mature asynchronous library equivalent to JDBC (but watch postgresql-netty, adbcj, async-mysql-connector and also related: mongodb-async-driver) and using NIO is rather problematic. But we should seek for alternatives and avoid blocking code whenever possible. In our sample application fetching random numbers from external web service was implemented in quite naive way: val url = new URL("https://www.random.org/integers/?num=" + batchSize + "&min=0&max=65535&col=1&base=10&format=plain&rnd=new") val connection = url.openConnection() val stream = Source.fromInputStream(connection.getInputStream) sender ! RandomOrgServerResponse(stream.getLines().map(_.toInt).toList) stream.close() This code blocks waiting for an HTTP reply for up to one minute. This means our actor can’t handle any other message for several seconds. Moreover it holds one thread (by default out of ten) from Akka worker pool. This pool is suppose to be shared among thousands of actors, so that feels a bit selfish. Luckily mature asynchronous HTTP client libraries exist, namely async-http-client (based on netty, with Scala wrapper called Dispatch) and Jetty HttpClient. For test purposes we’ll use the first one (and leave Dispatch for later). API is quite obvious: it asks us for target URL and a callback object, which will be used when reply arrives. Thus sending HTTP request is asynchronous and non-blocking (actor can quickly consume more incoming messages) and the response arrives asynchronously from a different thread: implicit def block2completionHandler[T](block: Response => T) = new AsyncCompletionHandler[T]() { def onCompleted(response: Response) = block(response) }def receive = { case FetchFromRandomOrg(batchSize) => val curSender = sender val url = "https://www.random.org/integers/?num=" + batchSize + "&min=0&max=65535&col=1&base=10&format=plain&rnd=new" client.prepareGet(url).execute { response: Response => val numbers = response.getResponseBody.lines.map(_.toInt).toList curSender ! RandomOrgServerResponse(numbers) } } We are very close to really dangerous bug in the code above. Notice how I make a local copy of sender called curSender. If I wouldn’t do this, the block of code executed when a response arrives would read current value of sender. Current, that is if our actor was handling some other message at a time, it would point to a sender of that other message. As a side note that’s one of the reasons why variables accessed from anonymous inner classes in Java have to be final. It’s also a good reason to avoid arbitrary code blocks called asynchronously inside actors. It’s much better to extract them to a separate class outside of the actor to avoid accidental access to internal actor state. Let’s leave our example for a while. Imagine how scalable our general architecture would be for a general RSS/Atom feed reader as a service. For each feed URL we can create one actor (and we monitor thousands of feeds, thus that many actors). Actor sends an asynchronous request to each site and waits for a response. Theoretically using just one worker thread we can handle thousands of feeds/servers, processing the results on the fly as they come (after all each server has a different response time). In a classic, blocking model we can only process as many feeds concurrently as many threads we can use (certainly not several thousands), not to mention each thread requires significant amount of memory. If you see some similarities to node.js you are on the right track. This framework is based entirely on asynchronous I/O, thus being able to handle large amount of concurrent connections using only one (!) thread. Source code for this article is available on GitHub in non-blocking-io tag. This was a translation of my article “Poznajemy Akka: nieblokujace I/O” originally published on scala.net.pl.   Reference: Non-blocking I/O – discovering Akka from our JCG partner Tomasz Nurkiewicz at the Java and neighbourhood blog. ...
akka-logo

Two actors – discovering Akka

Hope you are having fun so far, but our application has serious performance defect. After measuring response times of the RandomOrgRandom class we developed in the previous part we will notice something really disturbing (the chart represents response times of subsequent invocations in milliseconds):In turns out that regularly response time (time to return one random number) is greater by several orders of magnitude (logarithmic scale!) Remembering how the actor was implemented the reason is quite obvious: our actor fetches eagerly 50 random numbers and fills the buffer, returning one number after another. If the buffer is empty, actor performs blocking I/O call to random.org web service which takes around half of a second. This is clearly visible on the chart – every 50th invocation is much, much slower. In some circumstances such behaviour would be acceptable (just like unpredictable garbage collection can increase latency of a response once in a while). But still let’s try to improve our implementation. Do you have any idea how we can make response times more predictable and flat? I suggest monitoring the buffer size and when it becomes dangerously close to being empty, we initiate fetching random numbers in background. We hope that thanks to this architectural change will never be completely empty as the background response will arrive before we hit the bottom. However, we are not forced to eagerly fetch too many random numbers. Do you remember the original naive implementation using Java synchronization? It had the same problem as our current system with just one actor. But now we will finally see the true power of actor-based Akka system. To implement the improvement suggested above we would need background thread to fetch numbers and some method of synchronization on the buffer (as it would be accessed concurrently. In Akka each actor is logically single-threaded, thus we are not bothered by synchronization. First we will divide responsibilities: one actor (RandomOrgBuffer) will hold the buffer of random numbers and return them when requested. Second actor (RandomOrgClient) will barely be responsible for fetching new batches of random numbers. When RandomOrgBuffer discovers low buffer level, it asks RandomOrgClient (by sending a message) to start fetching new random numbers. Finally when RandomOrgClient receives a response from the random.org server, it sends new batch of random numbers to RandomOrgBuffer (of course using a reply message again). RandomOrgBuffer fills the buffer with new numbers. Let’s start from the second actor, responsible for the communication with random.org web service in the background. This actor initiates HTTP request when it receives FetchFromRandomOrg message – message holding the desired batch size to fetch. When the response arrives, we parse it and send the whole batch back to the sender (RandomOrgBuffer in this case). This code is quite similar to what we have already seen in fetchRandomNumbers(): case class FetchFromRandomOrg(batchSize: Int)case class RandomOrgServerResponse(randomNumbers: List[Int])class RandomOrgClient extends Actor { protected def receive = LoggingReceive { case FetchFromRandomOrg(batchSize) => val url = new URL("https://www.random.org/integers/?num=" + batchSize + "&min=0&max=65535&col=1&base=10&format=plain&rnd=new") val connection = url.openConnection() val stream = Source.fromInputStream(connection.getInputStream) sender ! RandomOrgServerResponse(stream.getLines().map(_.toInt).toList) stream.close() } } Now it’s time for the actual actor handling requests from potentially multiple clients asking for single random numbers. Unfortunately the logic becomes quite complicated (but at least we don’t have to worry about synchronization and thread-safety). First of all RandomOrgBuffer must now handle two different messages: RandomRequest as before coming from client code and new RandomOrgServerResponse (see code above) containing batch of new random numbers sent from RandomOrgClient. Secondly RandomOrgBuffer must remember that it initiated the process of fetching new random codes by sending FetchFromRandomOrg. Otherwise we risk starting multiple concurrent connections to random.org or piling them up unnecessarily. class RandomOrgBuffer extends Actor with ActorLogging {val BatchSize = 50val buffer = new Queue[Int] var waitingForResponse = falseval randomOrgClient = context.actorOf(Props[RandomOrgClient], name="client") preFetchIfAlmostEmpty()def receive = { case RandomRequest => preFetchIfAlmostEmpty() sender ! buffer.dequeue() case RandomOrgServerResponse(randomNumbers) => buffer ++= randomNumbers waitingForResponse = false }private def preFetchIfAlmostEmpty() { if(buffer.size <= BatchSize / 4 && !waitingForResponse) { randomOrgClient ! FetchFromRandomOrg(BatchSize) waitingForResponse = true } }} The key part is preFetchIfAlmostEmpty() method that initiates the process of fetching random numbers (in background, by a different actor). If the buffer level is too low (I assume 1/4 of the batch size) and we are not already waiting for a response from random.org, we send appropriate message to RandomOrgClient. We also call this method immediately on startup (when the buffer is completely empty) in order to have warmed up buffer when first request arrives. Notice how one actor can create an instance of another actor by calling context.actorOf (actually it’s an ActorRef). This code contains tremendous bug, can you spot it? Imagine what will happen if suddenly RandomOrgBuffer receives hundreds of RandomRequest messages at the same time? More than the buffer size, even immediately after filling it up? Or if the request comes straight after the actor instantiation, when the buffer is still empty? Unfortunately me must handle the situation when RandomRequest arrives and our buffer is completely empty while the random.org response didn’t came back yet. However we cannot simply block, waiting until the response with new random numbers batch arrives. We cannot do this from one simple reason: if we are sleeping or waiting in other way while handling RandomRequest, we cannot handle any other message, including RandomOrgServerResponse - remember that one actor can handle only one message at a time! Not only we would introduce dead-lock in our application, but also break one of the most important rules in Akka: never block or sleep inside an actor – more on that in next articles. Correct way of handling this situation is to have a queue of awaiting actors – which sent us RandomRequest but we were incapable of sending a reply immediately due to an empty buffer. As soon as we get RandomOrgServerResponse back, our priority is to handle these awaiting actors and then focus on subsequent requests in real time. There is an interesting edge case – if the number of awaiting actors was so big that after fulfilling their requests the buffer is almost empty again, we send FetchFromRandomOrg immediately one more time. It can get even more interesting – imagine the buffer is empty and we still haven’t satisfied all pending actors. The following code handles all these twists: class RandomOrgBuffer extends Actor with ActorLogging {val BatchSize = 50val buffer = new Queue[Int] val backlog = new Queue[ActorRef] var waitingForResponse = false//...def receive = LoggingReceive { case RandomRequest => preFetchIfAlmostEmpty() if(buffer.isEmpty) { backlog += sender } else { sender ! buffer.dequeue() } case RandomOrgServerResponse(randomNumbers) => buffer ++= randomNumbers waitingForResponse = false while(!backlog.isEmpty && !buffer.isEmpty) { backlog.dequeue() ! buffer.dequeue() } preFetchIfAlmostEmpty() }} In our final version the backlog queue represents pending actors. Notice how RandomOrgServerResponse is handled: if first tries to satisfy as many pending actors as possible. Obviously our goal was to eliminate extremely big response times so we should strive to minimal backlog queue usage as every actor placed there is more likely to wait longer. In ideal world backlog queue is always empty and the RandomOrgBuffer adjusts the batch size requested each time depending on current load (fetching smaller or bigger batches as well as adjusting the threshold below which buffer is considered almost empty). But I’ll leave these improvements to you. Finally we can measure RandomOrgBuffer response times (linear scale, latencies are no longer so unevenly distributed):Handling of incoming messages in RandomOrgBuffer became quite complex. I’m especially worried about the waitingForResponse flag (I hate flags!) In the next article we will learn how to deal with this in very clear, idiomatic and object-oriented way. This was a translation of my article “Poznajemy Akka: dwoch aktorow” originally published on scala.net.pl.   Reference: Two actors – discovering Akka from our JCG partner Tomasz Nurkiewicz at the Java and neighbourhood blog. ...
java-logo

Guava’s Strings Class

In the post Checking for Null or Empty or White Space Only String in Java, I demonstrated common approaches in the Java ecosystem (standard Java, Guava, Apache Commons Lang, and Groovy) for checking whether a String is null, empty, or white space only similar to what C# supports with the String.IsNullOrWhiteSpace method. One of the approaches I showed was a Guava-based approach that made use of the Guava class Strings and its static isNullOrEmpty(String) method. In this post, I look at other useful functionality for working with Strings that is provided by Guava’s six ‘static utility methods pertaining to String’ that are bundled into the Strings class. Using Guava’s Strings class is straightforward because of its well-named methods. The following list enumerates the methods (all static) on the Strings class with a brief description of what each does next to the method name (these descriptions are borrowed or adapted from the Javadoc documentation).Strings.isNullOrEmpty(String)‘Returns true if the given string is null or is the empty string.’emptyToNull(String)‘Returns the given string if it is nonempty; null otherwise.’nullToEmpty(String)‘Returns the given string if it is non-null; the empty string otherwise.’padStart(String,int,char)Prepend to provided String, if necessary, enough provided char characters to make string the specified length.padEnd(String,int,char)Append to provided String, if necessary, enough provided char characters to make string the specified length.repeat(String,int)‘Returns a string consisting of a specific number of concatenated copies of an input string.’  isNullOrEmpty Guava’s Strings.isEmptyOrNull(String) method makes it easy to build simple and highly readable conditional statements that check a String for null or emptiness before acting upon said String. As previously mentioned, I have briefly covered this method before. Another code demonstration of this method is shown next. Code Sample Using Strings.isNullOrEmpty(String) /** * Print to standard output a string message indicating whether the provided * String is null or empty or not null or empty. This method uses Guava's * Strings.isNullOrEmpty(String) method. * * @param string String to be tested for null or empty. */ private static void printStringStatusNullOrEmpty(final String string) { out.println( 'String '' + string + '' ' + (Strings.isNullOrEmpty(string) ? 'IS' : 'is NOT') + ' null or empty.'); }/** * Demonstrate Guava Strings.isNullOrEmpty(String) method on some example * Strings. */ public static void demoIsNullOrEmpty() { printHeader('Strings.isNullOrEmpty(String)'); printStringStatusNullOrEmpty('Dustin'); printStringStatusNullOrEmpty(null); printStringStatusNullOrEmpty(''); } The output from running the above code is contained in the next screen snapshot. It shows that true is returned when either null or empty String (”) is passed to Strings.isNullOrEmpty(String).nullToEmpty and emptyToNull There are multiple times when one may want to treat a null String as an empty String or wants present a null when an empty String exists. In cases such as these when transformations between null and empty String are desired, The following code snippets demonstrate use of Strings.nullToEmpty(String) and Strings.emptyToNull(String). nullToEmpty and emptyToNull /** * Print to standard output a simple message indicating the provided original * String and the provided result/output String. * * @param originalString Original String. * @param resultString Output or result String created by operation. * @param operation The operation that acted upon the originalString to create * the resultString. */ private static void printOriginalAndResultStrings( final String originalString, final String resultString, final String operation) { out.println('Passing '' + originalString + '' to ' + operation + ' produces '' + resultString + '''); }/** Demonstrate Guava Strings.emptyToNull() method on example Strings. */ public static void demoEmptyToNull() { final String operation = 'Strings.emptyToNull(String)'; printHeader(operation); printOriginalAndResultStrings('Dustin', Strings.emptyToNull('Dustin'), operation); printOriginalAndResultStrings(null, Strings.emptyToNull(null), operation); printOriginalAndResultStrings('', Strings.emptyToNull(''), operation); }/** Demonstrate Guava Strings.nullToEmpty() method on example Strings. */ public static void demoNullToEmpty() { final String operation = 'Strings.nullToEmpty(String)'; printHeader(operation); printOriginalAndResultStrings('Dustin', Strings.nullToEmpty('Dustin'), operation); printOriginalAndResultStrings(null, Strings.nullToEmpty(null), operation); printOriginalAndResultStrings('', Strings.nullToEmpty(''), operation); } The output from running the above code (shown in the next screen snapshot) proves that these methods work as we’d expect: converting null to empty String or converting empty String to null.padStart and padEnd Another common practice when dealing with Strings in Java (or any other language) is to pad a String to a certain length with a specified character. Guava supports this easily with its Strings.padStart(String,int,char) and Strings.padEnd(String,int,char) methods, which are demonstrated in the following code listing. padStart and padEnd /** * Demonstrate Guava Strings.padStart(String,int,char) method on example * Strings. */ public static void demoPadStart() { final String operation = 'Strings.padStart(String,int,char)'; printHeader(operation); printOriginalAndResultStrings('Dustin', Strings.padStart('Dustin', 10, '_'), operation); /** * Do NOT call Strings.padStart(String,int,char) on a null String: * Exception in thread 'main' java.lang.NullPointerException * at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187) * at com.google.common.base.Strings.padStart(Strings.java:97) */ //printOriginalAndResultStrings(null, Strings.padStart(null, 10, '_'), operation);printOriginalAndResultStrings('', Strings.padStart('', 10, '_'), operation); }/** * Demonstrate Guava Strings.padEnd(String,int,char) method on example * Strings. */ public static void demoPadEnd() { final String operation = 'Strings.padEnd(String,int,char)'; printHeader(operation); printOriginalAndResultStrings('Dustin', Strings.padEnd('Dustin', 10, '_'), operation); /** * Do NOT call Strings.padEnd(String,int,char) on a null String: * Exception in thread 'main' java.lang.NullPointerException * at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187) * at com.google.common.base.Strings.padEnd(Strings.java:129) */ //printOriginalAndResultStrings(null, Strings.padEnd(null, 10, '_'), operation); printOriginalAndResultStrings('', Strings.padEnd('', 10, '_'), operation); } When executed, the above code pads the provided Strings with underscore characters either before or after the provided String depending on which method was called. In both cases, the length of the String was specified as ten. This output is shown in the next screen snapshot.repeat A final manipulation technique that Guava’s Strings class supports is the ability to easily repeat a given String a specified number of times. This is demonstrated in the next code listing and the corresponding screen snapshot with that code’s output. In this example, the provided String is repeated three times. repeat /** Demonstrate Guava Strings.repeat(String,int) method on example Strings. */ public static void demoRepeat() { final String operation = 'Strings.repeat(String,int)'; printHeader(operation); printOriginalAndResultStrings('Dustin', Strings.repeat('Dustin', 3), operation); /** * Do NOT call Strings.repeat(String,int) on a null String: * Exception in thread 'main' java.lang.NullPointerException * at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187) * at com.google.common.base.Strings.repeat(Strings.java:153) */ //printOriginalAndResultStrings(null, Strings.repeat(null, 3), operation); printOriginalAndResultStrings('', Strings.repeat('', 3), operation); }Wrapping Up The above examples are simple because Guava’s Strings class is simple to use. The complete class containing the demonstration code shown earlier is now listed. GuavaStrings.java package dustin.examples;import com.google.common.base.Strings; import static java.lang.System.out;/** * Simple demonstration of Guava's Strings class. * * @author Dustin */ public class GuavaStrings { /** * Print to standard output a string message indicating whether the provided * String is null or empty or not null or empty. This method uses Guava's * Strings.isNullOrEmpty(String) method. * * @param string String to be tested for null or empty. */ private static void printStringStatusNullOrEmpty(final String string) { out.println( 'String '' + string + '' ' + (Strings.isNullOrEmpty(string) ? 'IS' : 'is NOT') + ' null or empty.'); }/** * Demonstrate Guava Strings.isNullOrEmpty(String) method on some example * Strings. */ public static void demoIsNullOrEmpty() { printHeader('Strings.isNullOrEmpty(String)'); printStringStatusNullOrEmpty('Dustin'); printStringStatusNullOrEmpty(null); printStringStatusNullOrEmpty(''); }/** * Print to standard output a simple message indicating the provided original * String and the provided result/output String. * * @param originalString Original String. * @param resultString Output or result String created by operation. * @param operation The operation that acted upon the originalString to create * the resultString. */ private static void printOriginalAndResultStrings( final String originalString, final String resultString, final String operation) { out.println('Passing '' + originalString + '' to ' + operation + ' produces '' + resultString + '''); }/** Demonstrate Guava Strings.emptyToNull() method on example Strings. */ public static void demoEmptyToNull() { final String operation = 'Strings.emptyToNull(String)'; printHeader(operation); printOriginalAndResultStrings('Dustin', Strings.emptyToNull('Dustin'), operation); printOriginalAndResultStrings(null, Strings.emptyToNull(null), operation); printOriginalAndResultStrings('', Strings.emptyToNull(''), operation); }/** Demonstrate Guava Strings.nullToEmpty() method on example Strings. */ public static void demoNullToEmpty() { final String operation = 'Strings.nullToEmpty(String)'; printHeader(operation); printOriginalAndResultStrings('Dustin', Strings.nullToEmpty('Dustin'), operation); printOriginalAndResultStrings(null, Strings.nullToEmpty(null), operation); printOriginalAndResultStrings('', Strings.nullToEmpty(''), operation); }/** * Demonstrate Guava Strings.padStart(String,int,char) method on example * Strings. */ public static void demoPadStart() { final String operation = 'Strings.padStart(String,int,char)'; printHeader(operation); printOriginalAndResultStrings('Dustin', Strings.padStart('Dustin', 10, '_'), operation); /** * Do NOT call Strings.padStart(String,int,char) on a null String: * Exception in thread 'main' java.lang.NullPointerException * at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187) * at com.google.common.base.Strings.padStart(Strings.java:97) */ //printOriginalAndResultStrings(null, Strings.padStart(null, 10, '_'), operation); printOriginalAndResultStrings('', Strings.padStart('', 10, '_'), operation); }/** * Demonstrate Guava Strings.padEnd(String,int,char) method on example * Strings. */ public static void demoPadEnd() { final String operation = 'Strings.padEnd(String,int,char)'; printHeader(operation); printOriginalAndResultStrings('Dustin', Strings.padEnd('Dustin', 10, '_'), operation); /** * Do NOT call Strings.padEnd(String,int,char) on a null String: * Exception in thread 'main' java.lang.NullPointerException * at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187) * at com.google.common.base.Strings.padEnd(Strings.java:129) */ //printOriginalAndResultStrings(null, Strings.padEnd(null, 10, '_'), operation); printOriginalAndResultStrings('', Strings.padEnd('', 10, '_'), operation); }/** Demonstrate Guava Strings.repeat(String,int) method on example Strings. */ public static void demoRepeat() { final String operation = 'Strings.repeat(String,int)'; printHeader(operation); printOriginalAndResultStrings('Dustin', Strings.repeat('Dustin', 3), operation); /** * Do NOT call Strings.repeat(String,int) on a null String: * Exception in thread 'main' java.lang.NullPointerException * at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:187) * at com.google.common.base.Strings.repeat(Strings.java:153) */ //printOriginalAndResultStrings(null, Strings.repeat(null, 3), operation); printOriginalAndResultStrings('', Strings.repeat('', 3), operation); }/** * Print a separation header to standard output. * * @param headerText Text to be placed in separation header. */ public static void printHeader(final String headerText) { out.println('\n========================================================='); out.println('= ' + headerText); out.println('========================================================='); }/** * Main function for demonstrating Guava's Strings class. * * @param arguments Command-line arguments: none anticipated. */ public static void main(final String[] arguments) { demoIsNullOrEmpty(); demoEmptyToNull(); demoNullToEmpty(); demoPadStart(); demoPadEnd(); demoRepeat(); } } The methods for padding and for repeating Strings do not take kindly to null Strings being passed to them. Indeed, passing a null to these three methods leads to NullPointerExceptions being thrown. Interestingly, these are more examples of Guava using the Preconditions class in its own code. Conclusion Many Java libraries and frameworks provide String manipulation functionality is classes with names like StringUtil. Guava’s Strings class is one such example and the methods it supplies can make Java manipulation of Strings easier and more concise. Indeed, as I use Guava’s Strings‘s methods, I feel almost like I’m using some of Groovy’s GDK String goodness.   Reference: Guava’s Strings Class from our JCG partner Dustin Marx at the Inspired by Actual Events blog. ...
mybatis-logo

MyBatis Tutorial – CRUD Operations and Mapping Relationships – Part 1

CRUD Operations MyBatis is an SQL Mapper tool which greatly simplifies the database programing when compared to using JDBC directly.                   Step1: Create a Maven project and configure MyBatis dependencies.   <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.0http://maven.apache.org/xsd/maven-4.0.0.xsd'><modelVersion>4.0.0</modelVersion><groupId>com.sivalabs</groupId> <artifactId>mybatis-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging><name>mybatis-demo</name> <url>http://maven.apache.org</url><properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties><build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> </plugins> </build><dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency><dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.1.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> <scope>runtime</scope> </dependency> </dependencies> </project>   Step#2: Create the table USER and a Java domain Object User as follows:   CREATE TABLE user ( user_id int(10) unsigned NOT NULL auto_increment, email_id varchar(45) NOT NULL, password varchar(45) NOT NULL, first_name varchar(45) NOT NULL, last_name varchar(45) default NULL, PRIMARY KEY (user_id), UNIQUE KEY Index_2_email_uniq (email_id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; package com.sivalabs.mybatisdemo.domain; public class User { private Integer userId; private String emailId; private String password; private String firstName; private String lastName;@Override public String toString() { return 'User [userId=' + userId + ', emailId=' + emailId + ', password=' + password + ', firstName=' + firstName + ', lastName=' + lastName + ']'; } //setters and getters }   Step#3: Create MyBatis configuration files. a) Create jdbc.properties file in src/main/resources folder jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis-demo jdbc.username=root jdbc.password=admin b) Create mybatis-config.xml file in src/main/resources folder <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE configuration PUBLIC '-//mybatis.org//DTD Config 3.0//EN' 'http://mybatis.org/dtd/mybatis-3-config.dtd'> <configuration> <properties resource='jdbc.properties'/> <typeAliases> <typeAlias type='com.sivalabs.mybatisdemo.domain.User' alias='User'></typeAlias> </typeAliases> <environments default='development'> <environment id='development'> <transactionManager type='JDBC'/> <dataSource type='POOLED'> <property name='driver' value='${jdbc.driverClassName}'/> <property name='url' value='${jdbc.url}'/> <property name='username' value='${jdbc.username}'/> <property name='password' value='${jdbc.password}'/> </dataSource> </environment> </environments> <mappers> <mapper resource='com/sivalabs/mybatisdemo/mappers/UserMapper.xml'/> </mappers> </configuration>   Step#4: Create an interface UserMapper.java in src/main/java folder in com.sivalabs.mybatisdemo.mappers package.   package com.sivalabs.mybatisdemo.mappers;import java.util.List; import com.sivalabs.mybatisdemo.domain.User;public interface UserMapper {public void insertUser(User user);public User getUserById(Integer userId);public List<User> getAllUsers();public void updateUser(User user);public void deleteUser(Integer userId);}   Step#5: Create UserMapper.xml file in src/main/resources folder in com.sivalabs.mybatisdemo.mappers package.   <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE mapper PUBLIC '-//mybatis.org//DTD Mapper 3.0//EN' 'http://mybatis.org/dtd/mybatis-3-mapper.dtd'><mapper namespace='com.sivalabs.mybatisdemo.mappers.UserMapper'><select id='getUserById' parameterType='int' resultType='com.sivalabs.mybatisdemo.domain.User'> SELECT user_id as userId, email_id as emailId , password, first_name as firstName, last_name as lastName FROM USER WHERE USER_ID = #{userId} </select> <!-- Instead of referencing Fully Qualified Class Names we can register Aliases in mybatis-config.xml and use Alias names. --> <resultMap type='User' id='UserResult'> <id property='userId' column='user_id'/> <result property='emailId' column='email_id'/> <result property='password' column='password'/> <result property='firstName' column='first_name'/> <result property='lastName' column='last_name'/> </resultMap><select id='getAllUsers' resultMap='UserResult'> SELECT * FROM USER </select><insert id='insertUser' parameterType='User' useGeneratedKeys='true' keyProperty='userId'> INSERT INTO USER(email_id, password, first_name, last_name) VALUES(#{emailId}, #{password}, #{firstName}, #{lastName}) </insert><update id='updateUser' parameterType='User'> UPDATE USER SET PASSWORD= #{password}, FIRST_NAME = #{firstName}, LAST_NAME = #{lastName} WHERE USER_ID = #{userId} </update><delete id='deleteUser' parameterType='int'> DELETE FROM USER WHERE USER_ID = #{userId} </delete></mapper>   Step#6: Create MyBatisUtil.java to instantiate SqlSessionFactory.   package com.sivalabs.mybatisdemo.service;import java.io.IOException; import java.io.Reader; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;public class MyBatisUtil { private static SqlSessionFactory factory;private MyBatisUtil() { }static { Reader reader = null; try { reader = Resources.getResourceAsReader('mybatis-config.xml'); } catch (IOException e) { throw new RuntimeException(e.getMessage()); } factory = new SqlSessionFactoryBuilder().build(reader); }public static SqlSessionFactory getSqlSessionFactory() { return factory; } }   Step#7: Create UserService.java in src/main/java folder.   package com.sivalabs.mybatisdemo.service;import java.util.List; import org.apache.ibatis.session.SqlSession; import com.sivalabs.mybatisdemo.domain.User; import com.sivalabs.mybatisdemo.mappers.UserMapper;public class UserService {public void insertUser(User user) { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.insertUser(user); sqlSession.commit(); }finally{ sqlSession.close(); } }public User getUserById(Integer userId) { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); return userMapper.getUserById(userId); }finally{ sqlSession.close(); } }public List<User> getAllUsers() { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); return userMapper.getAllUsers(); }finally{ sqlSession.close(); } }public void updateUser(User user) { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.updateUser(user); sqlSession.commit(); }finally{ sqlSession.close(); }}public void deleteUser(Integer userId) { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.deleteUser(userId); sqlSession.commit(); }finally{ sqlSession.close(); }}}   Step#8: Create a JUnit Test class to test UserService methods.   package com.sivalabs.mybatisdemo;import java.util.List;import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test;import com.sivalabs.mybatisdemo.domain.User; import com.sivalabs.mybatisdemo.service.UserService;public class UserServiceTest { private static UserService userService;@BeforeClass public static void setup() { userService = new UserService(); }@AfterClass public static void teardown() { userService = null; }@Test public void testGetUserById() { User user = userService.getUserById(1); Assert.assertNotNull(user); System.out.println(user); }@Test public void testGetAllUsers() { List<User> users = userService.getAllUsers(); Assert.assertNotNull(users); for (User user : users) { System.out.println(user); }}@Test public void testInsertUser() { User user = new User(); user.setEmailId('test_email_'+System.currentTimeMillis()+'@gmail.com'); user.setPassword('secret'); user.setFirstName('TestFirstName'); user.setLastName('TestLastName');userService.insertUser(user); Assert.assertTrue(user.getUserId() != 0); User createdUser = userService.getUserById(user.getUserId()); Assert.assertNotNull(createdUser); Assert.assertEquals(user.getEmailId(), createdUser.getEmailId()); Assert.assertEquals(user.getPassword(), createdUser.getPassword()); Assert.assertEquals(user.getFirstName(), createdUser.getFirstName()); Assert.assertEquals(user.getLastName(), createdUser.getLastName());}@Test public void testUpdateUser() { long timestamp = System.currentTimeMillis(); User user = userService.getUserById(2); user.setFirstName('TestFirstName'+timestamp); user.setLastName('TestLastName'+timestamp); userService.updateUser(user); User updatedUser = userService.getUserById(2); Assert.assertEquals(user.getFirstName(), updatedUser.getFirstName()); Assert.assertEquals(user.getLastName(), updatedUser.getLastName()); }@Test public void testDeleteUser() { User user = userService.getUserById(4); userService.deleteUser(user.getUserId()); User deletedUser = userService.getUserById(4); Assert.assertNull(deletedUser);} }   Now, I will explain how to perform CRUD operations using MyBatis Annotation support without need of Queries configuration in XML mapper files.   Step#1: Create a table BLOG and a java domain Object Blog.   CREATE TABLE blog ( blog_id int(10) unsigned NOT NULL auto_increment, blog_name varchar(45) NOT NULL, created_on datetime NOT NULL, PRIMARY KEY (blog_id) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; package com.sivalabs.mybatisdemo.domain;import java.util.Date;public class Blog {private Integer blogId; private String blogName; private Date createdOn;@Override public String toString() { return 'Blog [blogId=' + blogId + ', blogName=' + blogName + ', createdOn=' + createdOn + ']'; } //Seeters and getters }   Step#2: Create UserMapper.java interface with SQL queries in Annotations.   package com.sivalabs.mybatisdemo.mappers;import java.util.List;import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Options; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update;import com.sivalabs.mybatisdemo.domain.Blog;public interface BlogMapper { @Insert('INSERT INTO BLOG(BLOG_NAME, CREATED_ON) VALUES(#{blogName}, #{createdOn})') @Options(useGeneratedKeys=true, keyProperty='blogId') public void insertBlog(Blog blog);@Select('SELECT BLOG_ID AS blogId, BLOG_NAME as blogName, CREATED_ON as createdOn FROM BLOG WHERE BLOG_ID=#{blogId}') public Blog getBlogById(Integer blogId);@Select('SELECT * FROM BLOG ') @Results({ @Result(id=true, property='blogId', column='BLOG_ID'), @Result(property='blogName', column='BLOG_NAME'), @Result(property='createdOn', column='CREATED_ON') }) public List<Blog> getAllBlogs();@Update('UPDATE BLOG SET BLOG_NAME=#{blogName}, CREATED_ON=#{createdOn} WHERE BLOG_ID=#{blogId}') public void updateBlog(Blog blog);@Delete('DELETE FROM BLOG WHERE BLOG_ID=#{blogId}') public void deleteBlog(Integer blogId);}   Step#3: Configure BlogMapper in mybatis-config.xml   <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE configuration PUBLIC '-//mybatis.org//DTD Config 3.0//EN' 'http://mybatis.org/dtd/mybatis-3-config.dtd'> <configuration> <properties resource='jdbc.properties'/> <environments default='development'> <environment id='development'> <transactionManager type='JDBC'/> <dataSource type='POOLED'> <!-- <property name='driver' value='com.mysql.jdbc.Driver'/> <property name='url' value='jdbc:mysql://localhost:3306/mybatis-demo'/> <property name='username' value='root'/> <property name='password' value='admin'/> --> <property name='driver' value='${jdbc.driverClassName}'/> <property name='url' value='${jdbc.url}'/> <property name='username' value='${jdbc.username}'/> <property name='password' value='${jdbc.password}'/> </dataSource> </environment> </environments> <mappers> <mapper class='com.sivalabs.mybatisdemo.mappers.BlogMapper'/> </mappers> </configuration>   Step#4: Create BlogService.java   package com.sivalabs.mybatisdemo.service;import java.util.List;import org.apache.ibatis.session.SqlSession;import com.sivalabs.mybatisdemo.domain.Blog; import com.sivalabs.mybatisdemo.mappers.BlogMapper;public class BlogService {public void insertBlog(Blog blog) { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); blogMapper.insertBlog(blog); sqlSession.commit(); }finally{ sqlSession.close(); } }public Blog getBlogById(Integer blogId) { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); return blogMapper.getBlogById(blogId); }finally{ sqlSession.close(); } }public List<Blog> getAllBlogs() { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); return blogMapper.getAllBlogs(); }finally{ sqlSession.close(); } }public void updateBlog(Blog blog) { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); blogMapper.updateBlog(blog); sqlSession.commit(); }finally{ sqlSession.close(); } }public void deleteBlog(Integer blogId) { SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession(); try{ BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); blogMapper.deleteBlog(blogId); sqlSession.commit(); }finally{ sqlSession.close(); }}}   Step#5: Create JUnit Test for BlogService methods   package com.sivalabs.mybatisdemo;import java.util.Date; import java.util.List;import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test;import com.sivalabs.mybatisdemo.domain.Blog; import com.sivalabs.mybatisdemo.service.BlogService;public class BlogServiceTest { private static BlogService blogService;@BeforeClass public static void setup() { blogService = new BlogService(); }@AfterClass public static void teardown() { blogService = null; }@Test public void testGetBlogById() { Blog blog = blogService.getBlogById(1); Assert.assertNotNull(blog); System.out.println(blog); }@Test public void testGetAllBlogs() { List<Blog> blogs = blogService.getAllBlogs(); Assert.assertNotNull(blogs); for (Blog blog : blogs) { System.out.println(blog); }}@Test public void testInsertBlog() { Blog blog = new Blog(); blog.setBlogName('test_blog_'+System.currentTimeMillis()); blog.setCreatedOn(new Date());blogService.insertBlog(blog); Assert.assertTrue(blog.getBlogId() != 0); Blog createdBlog = blogService.getBlogById(blog.getBlogId()); Assert.assertNotNull(createdBlog); Assert.assertEquals(blog.getBlogName(), createdBlog.getBlogName());}@Test public void testUpdateBlog() { long timestamp = System.currentTimeMillis(); Blog blog = blogService.getBlogById(2); blog.setBlogName('TestBlogName'+timestamp); blogService.updateBlog(blog); Blog updatedBlog = blogService.getBlogById(2); Assert.assertEquals(blog.getBlogName(), updatedBlog.getBlogName()); }@Test public void testDeleteBlog() { Blog blog = blogService.getBlogById(4); blogService.deleteBlog(blog.getBlogId()); Blog deletedBlog = blogService.getBlogById(4); Assert.assertNull(deletedBlog); } }   Reference: MyBatis Tutorial: Part1 – CRUD Operations from our JCG partner, MyBatis Tutorial: Part-2: CRUD operations Using Annotations from our JCG partner Siva Reddy at the My Experiments on Technology blog. ...
scala-logo

Remote actors – discovering Akka

Assume our test application became a huge success and slowly a single server is not capable of handling growing traffic. We are faced with two choices: replacing our server with a better one (scaling up) or buying a second one and building a cluster (scaling out). We’ve chosen to build a cluster as it’s easier to scale in the future. However we quickly discover that our application no longer fulfils the very first requirement: The client application should call the URL […] at most from one thread – it’s forbidden to concurrently fetch random numbers using several HTTP connections. Obviously every node in the cluster is independent, having its own, separate instance of Akka, thus a separate copy of RandomOrgClient actor. In order to fix this issue we have few options:having a global (cluster-wide!) lock (distributed monitor, semaphore, etc.) guarding multithreaded access. Ordinary synchronized is not enough. …or create a dedicated node in the cluster to communicate with random.org, used by all other nodes via some API …or create only one instance of RandomOrgClient on exactly one node and expose it via some API (RMI, JMS…) to remote clientsDo you remember how much time spent describing the different between Actor and ActorRef? Now this distinction will become obvious. In turns out our solution will be based on the last suggestion, however we don’t have to bother about API, serialization, communication or transport layer. Even better, there is no such API in Akka to handle remote actors. It’s enough to say in the configuration file: this particular actor is suppose to be created only on this node. All other nodes, instead of creating the same actor locally, will return a special proxy, which looks like a normal actor from the outside, while in reality it forwards all messages to remote actor on other node. Let’s say it again: we don’t have to change anything in our code, it’s enough to make some adjustments in the configuration file: akka { actor { provider = "akka.remote.RemoteActorRefProvider" deployment { /buffer/client { remote = "akka://RandomOrgSystem@127.0.0.1:2552" } } } remote { transport = "akka.remote.netty.NettyRemoteTransport" log-sent-messages = on netty { hostname = "127.0.0.1" } } } That’s it! Each node in the cluster is identified by the server address and port. Key part of the configuration is the declaration that /buffer/client is suppose to be created only 127.0.0.1:2552. Every other instance (working on a different server or port), instead of creating a new copy of the actor, will build a special transparent proxy, calling remote server. If you don’t remember the architecture of our solution, figure below demonstrates the message flow. As you can see each node has its own copy of RandomOrgBuffer (otherwise each access of the buffer would result in remote call, which defeats the purpose of the buffer altogether). However each node (except the middle one) has a remote reference to a RandomOrgClient actor (node in the middle accesses this actor locally):The machine in the middle (JVM 1) is executed on port 2552 and it’s the only machine that communicates with random.org. All the others (JVM 2 and 3 working on 2553 and 2554 respectively) are communicating with this server indirectly via JVM 1. BTW we can change the TCP/IP port used by each node either by using configuration file or -akka.remote.netty.port=2553 Java property. Before we announce premature success (again), we are faced with another problem. Or actually, we haven’t really passed the original obstacle yet. Since RandomOrgClient is now accessed by multiple RandomBuffer actors (distributed across the cluster), it can still initiate multiple concurrent HTTP connections to random.org, on behalf of every node in the cluster. It’s easy to imagine a situation where several RandomOrgBuffer instances are sending FetchFromRandomOrg message at the same time, beginning several concurrent HTTP connections. In order to avoid this situation we implement already known technique of queueing requests in actor if one request wasn’t yet finished: case class FetchFromRandomOrg(batchSize: Int)case class RandomOrgServerResponse(randomNumbers: List[Int])class RandomOrgClient extends Actor {val client = new AsyncHttpClient() val waitingForReply = new mutable.Queue[(ActorRef, Int)]override def postStop() { client.close() }def receive = LoggingReceive { case FetchFromRandomOrg(batchSize) => waitingForReply += (sender -> batchSize) if (waitingForReply.tail.isEmpty) { sendHttpRequest(batchSize) } case response: RandomOrgServerResponse => waitingForReply.dequeue()._1 ! response if (!waitingForReply.isEmpty) { sendHttpRequest(waitingForReply.front._2) } }private def sendHttpRequest(batchSize: Int) { val url = "https://www.random.org/integers/?num=" + batchSize + "&min=0&max=65535&col=1&base=10&format=plain&rnd=new" client.prepareGet(url).execute(new RandomOrgResponseHandler(self)) } }private class RandomOrgResponseHandler(notifyActor: ActorRef) extends AsyncCompletionHandler[Unit]() { def onCompleted(response: Response) { val numbers = response.getResponseBody.lines.map(_.toInt).toList notifyActor ! RandomOrgServerResponse(numbers) } } This time pay attention to waitingForReply queue. When a request to fetch random numbers from remote web service comes in, either we initiate new connection (if the queue doesn’t contain no-one except us). If there are other actors awaiting, we must politely put ourselves in the queue, remembering who requested how many numbers (waitingForReply += (sender -> batchSize)). When a reply arrives, we take the very first actor from the queue (who waits for the longest amount of time) and initiate another request on behalf of him. Unsurprisingly there is no multithreading or synchronization code. However it’s important not to break encapsulation by accessing its state outside of receive method. I made this mistake by reading waitingForReply queue inside onCompleted() method. Because this method is called asynchronously by HTTP client worker thread, potentially we can access our actors state from two threads at the same time (if it was handling some message in receive at the same time). That’s the reason why I decided to extract HTTP reply callback into a separate class, not having implicit access to an actor. This is much safer as access to actor’s state is guarded by the compiler itself. This is the last part of our Discovering Akka series. Remember that the complete source code is available on GitHub.   Reference: Remote actors – discovering Akka from our JCG partner Tomasz Nurkiewicz at the Java and neighbourhood blog. ...
lambdaj-logo

Avoiding FORs – Anti-If Campaign

Have you ever wondered how FORs impact your code? How they are limiting your design and more important how they are transforming your code into an amount of lines without any human meaning? In this post we are going to see how to transform a simple example of a for (provided by Francesco Cirillio – anti-if campaign), to something more readable and well designed. So let’s start with original code using FOR:       public class Department {private List<Resource> resources = new ArrayList<Resource>();public void addResource(Resource resource) { this.resources.add(resource); }public void printSlips() {for (Resource resource : resources) { if(resource.lastContract().deadline().after(new Date())) {System.out.println(resource.name()); System.out.println(resource.salary()); } } }} See printSlips method. So simple method, only 10 lines counting white lines, but violating one of the most important rule, this method is doing more than one thing inside it mixing different level of abstractions. As Robert C. Martin note in his book ‘Functions Should Do One Thing. They Should Do Well. They Should do it only […]. If a function does only steps that are one level below the stated name of the function, then the function is doing one thing […].’. So with the given definition of how a method should look, let’s recap with previous method, and see how many things are doing printSlips method? Concretely four. public void printSlips() {for (Resource resource : resources) { #Cycle if(resource.lastContract().deadline().after(new Date())) { #Selection #Media System.out.println(resource.name()); #Content System.out.println(resource.salary()); } } } The method is cycling, selecting resources, accessing to content, and accessing to media. See that each of them belongs to different level of abstraction, printing to console should be in different level of checking if a resource has not expired its contract yet. Let’s see the solution proposed by Francesco. The first thing to do is splitting main functions into three classes and two interfaces, one for iterating resources, another one to choose whatever a resource has not expired yet, and another one for printing a resource. With this approach, we are creating a solution which is designed to be extended, and improving readability too. And now it is time for the code: Predicate interface will be used for implementing if a resource meets an implemented condition. public interface Predicate {boolean is(Resource each);} For example in our case, implementation of interface will look like: public class InForcePredicate implements Predicate {public boolean is(Resource each) { return each.lastContract().deadline().after(new Date()); } } We have move conditional to InForcePredicate class. Note that if we want to create a class that checks if contract is expired we would create a new class implementing Predicate with something like return  each.lastContract().deadline().before(new Date()); Block interface will be the next interface which will implement the access to media. In this case to console: public interface Block {void evaluate(Resource resource);} And its implementation: public class PrintSlip implements Block {public void evaluate(Resource resource) { System.out.println(resource.name()); System.out.println(resource.salary()); }} Again note that changing where information is sent (console, file, network, …) it is a simply matter of implementing Block interface. And last class is the one which contains an iterator over resources, and also provides methods to call each interface created previously: public class ResourceOrderedCollection { private Collection<Resource> resources = new ArrayList<Resource>();public ResourceOrderedCollection() { super(); }public ResourceOrderedCollection(Collection<Resource> resources) { this.resources = resources; }public void add(Resource resource) { this.resources.add(resource); }public void forEachDo(Block block) { Iterator<Resource> iterator = resources.iterator();while(iterator.hasNext()) { block.evaluate(iterator.next()); }}public ResourceOrderedCollection select(Predicate predicate) {ResourceOrderedCollection resourceOrderedCollection = new ResourceOrderedCollection();Iterator<Resource> iterator = resources.iterator();while(iterator.hasNext()) { Resource resource = iterator.next(); if(predicate.is(resource)) { resourceOrderedCollection.add(resource); } }return resourceOrderedCollection; } } See next three important points:First one is that constructor receives a list of resources. Second one is that select method receives a predicate which is executed into the iterator to know if resource is choosable to be printed or not. Finally returning a new instance of ResourceOrderedCollection with resources without an expired contract. Third one forEachDo method receives a Block interface which is called by every element of resources list.And finally modified Department class using previous developed classes: public class Department {private List<Resource> resources = new ArrayList<Resource>();public void addResource(Resource resource) { this.resources.add(resource); }public void printSlips() { new ResourceOrderedCollection(this.resources).select(new InForcePredicate()).forEachDo(new PrintSlip()); }} Observe that now printSlips method contains a single readable line with the same level of abstraction. Take notice that class and interface names are taken from Francesco example, but if I should do the same I would choose more representative names. Cirillo’s approach is good, but has some minor aspects to consider. For example it has the ‘ vertical problem‘: the InForcePredicate instance from Predicate interface uses five lines of source code to encapsulate a single statement. We have explored two possible solutions of a problem, being the last one the proposed by Cirillio. Also there are many other possible and correct solutions to this problem, for example using Template Method Pattern, or mixing the use of Lambdaj with (or without) Closures (Lambdaj syntax can be a bit confusing). All of them have their pros and cons, but all of them makes your code readable and more important, all functions do one thing, they do well and they do it only. As final notes of this post, JDK 8 will provide support for closures natively, and also will provide many features that now are provided by Lambdaj. Meanwhile JDK 8 is not stable (planned for mid-final 2013) or for your legacy code (from the point of view of JDK 8), Lambdaj is a really good fellow traveler. We keep learning.   Reference: Avoiding FORs – Anti-If Campaign from our JCG partner Alex Soto at the One Jar To Rule Them All blog. ...
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