Archive for the ‘Java’ Category

provided and runtime scopes in maven

Wednesday, February 7th, 2018

maven runtime and provided scopes are sometimes sources of confusion. When do we need to use them?

compile: This is what you want to use most of the time and is also the default scope. If you use this scope, maven will also handle transitive dependencies and dependency resolution for you automatically

provided: If you specify a dependency as provided, it is used only for compiling. At runtime, your container (usually an application server such as tomcat) is expected to supply the required jar. The common usecase for this scope is those situations when you need certain classes for your code to compile, but at runtime you want to delegate the dependency to a container or JDK. This scope is not transitive

runtime: In this case, the dependency is NOT available in the compile path. At runtime, you have to make the dependency available in the runtime classpath. The common usecase is when you want to make sure that your code does not make any usage of the classes in the dependency which should be dynamically available only at runtime. Usually this is the case with specific JDBC implementations which are loaded using Class.forname. Unlike provided, dependencies are included transitively!

Both runtime and provided hint about requiring something dynamically, but in fact they are to be used for entirely different purposes. If you make a dependency compile where only a runtime would have sufficed, nothing per se will break neither at compile time nor at runtime. But on the other hand, if you make a dependency provided, you have to make sure that at runtime the required dependencies are available. Otherwise you will most likely get a java.lang.ClassNotFoundException

 

 

Questions to ask before choosing a Collection implementation in Java

Wednesday, May 25th, 2016

In any non-trivial software application, developers are faced with having to deal with a collection of objects. Java Collections framework provides a rich set of options, but quite often I have seen people choosing one of the popular options such as an ArrayList or a HashSet without thinking through the consequences of their choice. On the other hand, some choose “performance” as the foremost criteria even though the scalability requirements are hard to predict beforehand.

My rule of thumb in choosing the right implementation of the Collection or Map interface is as follows:

Thread safety

In my opinion, thread safety requirements are a good start for narrowing down your options. Do I need thread safety or not? Most of the Collection implementations do not provide thread safety by default due to performance reasons. If you need your code to be thread-safe, then either you have to use a thread-safe implementation or be willing to wrap your collection using Collections.synchronized

Duplicates

Next critical criteria in choosing a good implementation are whether you have to store duplicate elements or not. Many collection implementations do permit duplicates, though this may not be desirable depending upon your requirements. This applies to duplicate elements in case of Lists or Queues and duplicate keys in case of a key-value pair structure such as Map.

Order

Does the ordering of elements in the collection matter? If yes, what type of ordering — natural ordering or the insertion order?

Null

Do we have to store nulls or not is another factor which could influence your choice.

Performance

This should be in my opinion the last criteria for most of the applications. The performance of different implementations varies, depending upon the type of implementation and also depending upon the thread-safety. ArrayList provides very fast insertion and retrieval, making it a good candidate for collections which require fast access to random elements. But if you want to remove elements frequently, then LinkedList is a better candidate. But in practice for most cases, you may not know in advance how much scalability is needed. Also, performance differences will start to show up only for very large datasets, so better to avoid premature optimization.

[table caption=”Quick look” width=”500″ colwidth=”20|100|50″ colalign=”left|left|center|left|right”]

Type, Implementation, Thread-safe, Ordered, Duplicates, Allows null, Insertion, Retrieval, Removal

List, ArrayList, No, Yes, Yes, Yes, O(1), O(1), O(n)

List, LinkedList, No, Yes, Yes, Yes, O(1), O(n), O(1)

List, CopyOnArrayList, Yes, Yes, Yes, Yes, O(n), O(1), O(n)

Set, HashSet, No, No, No, Yes, O(1), na, O(1)

Set, LinkedHashSet, No, Yes, No, Yes, O(1), na, O(1)

Set, TreeSet, No, Yes, No, Yes, O(logn), na, O(logn)

Set, ConcurrentSkipListSet, Yes, Yes, No, No, O(logn), O(logn), O(logn)

Queue, ArrayBlockingQueue, Yes, Yes, No, No, O(1), O(1), O(1)

Queue, PriorityQueue, No, Yes, No, No, O(logn), O(1), O(logn)

Queue, LinkedBlockingQueue, Yes, Yes, No, No, O(1), O(1), O(1)
[/table]

Summary

Choosing the right Collection implementation is often tricky, but you can’t make serious mistakes if you keep in mind some of the above rules of thumb. Thread-safety and ordering requirements should primarily dictate the choice of any implementation and only when you are faced with unusual scalability requirements, start looking at performance as major decision criteria.

 

Microservices – μService architecture

Sunday, October 19th, 2014

Microservices are the hottest topic in enterprise software development nowadays. It is an application architecture pattern or a trend that has emerged over last 2 to 4 years based on several enabling factors such as polyglot development, cloud deployment and increased deployment automation.

Breaking up a legacy, monolithic, portal-server based application into more service oriented, independently deployable and easily maintainable multiple services based around business capabilities could be an interesting and daunting challenge

Articles

Martin Fowler’s defining article

Presentation by James Lewis of Thoughtworks

Cracking Microservices practices

μService not a free lunch

Microservices: Decomposing Applications for Deployability and Scalability

Agile coding in enterprise IT: Code small and local

 12 factor apps

Microservice in practice

Karma Inc.

Failing at Microservices

 

Implementation

http://blog.xebia.com/2014/10/27/dropwizard/

 

Tags

https://twitter.com/hashtag/microservice

Java 8 to be released today

Tuesday, March 18th, 2014

Today (18.03.2014) is the official release date for Java 8 and the download page from Oracle now lists Java 8 as the latest release. I have been trying out various new features of Java 8 for more than 6 months now. I had downloaded the early access build and have been using it with intellij 12.1.6.

Support for Java 8 in intellij is reasonable so far, even though there have been some minor issues, one of them which I had reported and got fixed. This involved “Error suggestion” for checked exceptions inside a lambda expression containing a wrong suggestion to add the exception to the method definition which results in a non compilable code. Just like an anonymous inner class must catch all its checked exceptions, a lambda must also catch them all within the lambda block.  Also the code completion using custom templates inside the lambda block does not seem to work as well.

There are many examples to be found in the internet that explains very well what a lambda expression is and how they could make the life easier for Java developers in certain cases. Oracle’s tutorial is worth checking out as it also explains the necessity of lambda by starting with a pre Java 8 code and transforming it step by step using lambda expression.

Why lambda? A mature language facing a mid-life crisis

At 18, Java platform is not a novelty anymore. Since its first release in 1995, the platform and the language has grown to achieve unprecedented success, immense popularity and widespread adoption in almost all walks of software development. According to Oracle’s own claim, 3 billion devices run on Java and that include Computers, Printers, Routers, Mobile devices, Tablets and a wide range of other networked appliances (to me it sounds like one of those claims which will never be verified!)

java3billion

 

Though it might seem like things have never been better for Java, there are skeptics who believe that both the platform and the language have seen their best times already – those who regard Java as a cluttered, poorly designed and overreached language that is slow or incapable to adapt to the latest challenges in the industry. This doubt comes at a time when Java is facing increasing competition from dynamic languages like Ruby and functional languages like Scala and Clojure.

Competition from Ruby and Scala

While Ruby was first developed at around the same time when the first ever Jdk was released, it never grew to be as popular as Java as a programming language. Though highly expressive with its concise and some say beautiful syntax, Ruby’s dynamic typing system kept it largely away from the big scale enterprise projects where the static typing of Java was highly valued for maintenance reasons. But the embrace of Ruby on Rails by many companies in the middle of the last decade gave the language a fresh new life. Ruby on Rails or Rails as it is popularly known was adopted by many web based start-ups who valued its productivity and shorter time-to-market. In the following years, it has made its way into one of the top programming languages used for web development and scripting. Twitter was developed almost entirely using Ruby and Rails and ran on it until very recently when it switched to Scala.

Lately Scala has also emerged as a serious alternative to Java. It has some of the treasured qualities of Java such as a static type system and object oriented programming style, but at the same time it boasts many other powerful features that comes with a functional style programming. Its syntax is more concise and code less cluttered when compared to Java as the designers of Scala took care to avoid the boiler-plate mess that Java is known for. Twitter and LinkedIn are some of the most well known adopters of Scala. Also Akka and Play! – two increasingly popular frameworks are written for Scala though they support Java as well. Scala has the advantage that it runs on JVM and mixes seamlessly with Java (one can import JDK libraries in Scala code).

Here comes the closure

Many popular languages support closures, but Java was not one of them until Java 8. In order to get around with this limitation, Java developers had to depend upon a helper interface and an anonymous instance of this interface which would implement the behavior for the interface. This resulted in quite a bit of boilerplate code that comes up with anonymous inner class in the client code. But with Java 8, this should be eased a bit.

What could be written using anonymous inner class in Java 7 could be expressed as an anonymous function in Java 8

Java 7:
public class HelloInnerWorld {

public static void main(String[] args) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello World");
        }
      }).start();
    }
}
Java 8:
public class HelloLambdaWorld {
    public static void main(String[] args) {
        new Thread(() -> System.out.println("Hello World")).start();
    }
}

How the above code will change in a way that again results in boilerplate code when the code in the closure throws a checked exception, I will explain in another post.