java

Java: Add lib folder to classpath

Adding non standard, non-maven, custom jars in a maven project is a common issue. And this SO post is usually the first googled result. But here is another easier way: Use addjars-maven-plugin. Its easier, no need to run any script, no installing of jars manually, or use the dreaded system scope. Using this also means, the shaded uber jar that gets created will contain the custom jars.

How to use?

Add the jars to a lib folder directly inside the project directory (the project directory now contains lib, src and other usual stuff). Now add this to the pom:

<build>
    <plugins>
        <plugin>
            <groupId>com.googlecode.addjars-maven-plugin</groupId>
            <artifactId>addjars-maven-plugin</artifactId>
            <version>1.0.5</version>
            <executions>
                <execution>
                    <goals>
                        <goal>add-jars</goal>
                    </goals>
                    <configuration>
                        <resources>
                            <resource>
                                <directory>${project.basedir}/lib</directory>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

This may not be recognised by the IDE (my Intellij didn’t), but it will work via CLI. So no worries! Very useful in those rare cases, where you have a dozen of custom jars!

Advertisements

Jackson JSON and Dynamic JSON creation

FasterXML Jackson is a great tool for converting objects to/from POJOs.

Its a great tool when we know the structure of JSON beforehand. But what if we don’t know that? In that case we can use a Map<String, Object> to store the unknown objects. Below two links provide useful info:

http://stackoverflow.com/questions/18043587/why-im-not-able-to-unwrapp-and-serialize-java-map-using-jackson-java-library

http://www.cowtowncoder.com/blog/archives/2011/07/entry_458.html

Happy Coding 🙂

Creating collection of Spring Beans

Some times there might arise situations where you want to create a number of Spring Beans, but you don’t know how many beans are there at coding time.

Usually, you create a Spring bean as follows:

But what if you want to create 50 such beans which differ only in the argument supplied to the constructor? Or a similar case arise where the number of beans to be created cannot be determined at coding time?
In such cases, we can create the bean definitions and add the beans to Spring container at runtime using BeanFactoryPostProcessor.

Implement BeanFactoryPostProcessor in either a @Configuration file or a @Component bean(make sure this bean gets scanned and created).

If there are more than one constructor arguments, the call can be chained as follows:

All this works fine when you have to create a bean using constructor. But 😦 I haven’t figured out how to do this when we use a chain of factory methods to create a bean as follows:

Happy Coding! 🙂

Tryst with Java 8!

Java 8 – it has been making headlines as the version which brings dramatic changes to Java. And I believe its true. I have been using Java 8 for the last few months and using Java 8 features has really brought changes in the way I write code and sometimes even the way I think about code!

Most of the changes is in the way we deal with Collections. And most of our daily life as a programmer revolves around manipulating or using Java Collections. Java 8 has brought in functional programming and Lambda expressions. There are many examples out there in the WWW which go to the intricacies of Lambda expressions and Java 8 features. Here I’ll jot down some notes which I found to be useful. Its no way an introduction or tutorial, its just some notes I have made which’ll help in understanding Java 8 features.

Functional Interfaces

Any interface with just one non-default method.
-Even though not necessary, we can enforce this constraint by annotating an interface with @FunctionalInterface

Default Methods

An interface method with modifier ‘default‘. Should have method implementation.

Lambdas

Short-cut way to implement anonymous inner classes for functional interfaces.
Syntax:
parameter || (parameters) || () -> expression || statement || { statements }

  • Can reference external variables which are effectively final in the lambda body
  • ‘parameters’ – parameters for the functional interface method. Datatype is not required. Eg: (String s1, int i), (s1, i)
  • a single ‘expression’ can be used if the lambda body is just a return statement

Method Reference

Syntax:
ClassName::methodName
To refer constructors: ClassName::new

  • Can be used anywhere where a lambda or functional interface implementation is expected.
  • The referred method should be having same signature as of the functional interface method

 

Functions like foreach(), stream(), filter(), map(), findFirst() along with Consumer, Function and Predicate make life a hell lot of easy in dealing with Java Collections. Java 8 also brings functional programming to Java world with its lambdas. That means we can now pass a function to a function and return a function from a function! That brings a lot of changes in which we write Java programs. Java 8 also brings a new Date/Time API as well as some utils like Base64 encoding in the default library set.

Happy coding 🙂

Creating a Maven Spring-REST project

Open Eclipse. Make sure it is a recent version with m2e integration. I am using Kepler version of Eclipse.
Now go to File > New > Maven Project.
rest1

Click Next. Select maven-archetype-webapp.
rest2
Click Next. Enter GroupID (group ID is the name that refers to a group of projects. It should be unique. A name like ‘com.companyname.yourname’ would be suffice) and Artifact ID (Artifact ID is the project name. It should be unique within a groupID).

There can be several projects under the same GroupID, but ArtifactID should be different for each project. I have given GroupID as ‘me.sinu.jugaad’ and ArtifactID as ‘rest’.
rest3
Click Finish to create the project.

The webapp archetype would have created the necessary folder structure and a web.xml for you. This web.xml might be for older Servlets without support for Servlet v.3, it doesn’t matter as we’ll overwrite it later.
You might examine pom.xml now, it may contain a single dependency of jUnit(even if you won’t find it its fine 🙂 )

Now lets examine the dependencies we might require for our simple project:

  • We are building REST services, so we need REST api (javax.ws.rs-api) and an implentation for it. We’ll use Apache CXF implementation (cxf-bundle-jaxrs).
  • We’ll use Spring to wire the beans and for dependency injection. So we need a bunch of Spring libraries (spring-web and spring-context should be enough for our skeleton project. spring-context is needed for ContextLoaderListener which loads the beans by scanning some Spring context xml configuration files)
  • We’ll use a JSON provider which helps in converting object to/from JSON. It is not needed for this skeleton project, but its usually handy in almost all REST projects. So we’ll add one such provider (jackson-jaxrs-json-provider) just in case we need it in future.

Here is the pom.xml:

Now create a java folder under src/main. Create a package (me.sinu.jugaad.rest) and a class file inside it(HelloWorld.java).
We’ll just tell a simple “Hello REST!” from our REST service. Here is the class:

Now we’ll create a Spring configuration file under WEB-INF folder, say rest-context.xml:

In this we just defined our helloWorld bean and hooked it up with our JAXRS servlet. We also provided our JSON provider to it to automatically do any marshalling/unmarshalling. You may provide your own providers, which will be necessary as the app grows. Providers can contain Filters or other interceptors.

Now lets define our webapp’s web.xml:

We specify ‘contextConfigLocation‘ for the Spring’s ‘ContextLoaderListener‘ to pick it up as the webapp is loaded. The contextConfigLocation can be given as exact file names or using wild cards.
Since we are using CXF implementation, a CXF servlet is used. The address for our servlet is “/services” and that for our ‘helloREST‘ JAX RS server is “/greet“.
So “WAR_FILE/services/greet” will take us to the JAXRS server. Our simple GET function is annotated with @Path(“/hello”), so to access this we should give as follows: “WAR_FILE/services/greet/hello“.
Now run the project – right-click the project > Run As > Run on server. You might choose a server like Tomcat server v.7. Now in a browser go to “http://localhost:8080/rest/services/greet/hello” (here ‘rest‘ is the WAR file name).

If you see “Hello REST!” everything is fine, else, Dr.Watson, we have a problem 😉

Maven config for SLF4J and Logback

To use SLF4J and logback together, add the following to pom.xml:

<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 <version>1.7.5</version>
 </dependency>
 <dependency>
 <groupId>ch.qos.logback</groupId>
 <artifactId>logback-classic</artifactId>
 <version>1.0.13</version>
 <scope>runtime</scope>
 </dependency>

<dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>3.8.1</version>
 <scope>test</scope>
 </dependency>

Now SLF4J’s logger can be used:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
....
private final Logger logger =  LoggerFactory.getLogger(MyClass.class);
...
logger.debug("Mandatory fields are missing");

If while running this in Eclipse or in console, it complains of some missing configuration, add thisto pom.xml:

<build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                        <lifecycleMappingMetadata>
                            <pluginExecutions>
                                <pluginExecution>
                                    <pluginExecutionFilter>
                                        <groupId>org.codehaus.mojo</groupId>
                                        <artifactId>properties-maven-plugin</artifactId>
                                        <versionRange>[1.0-alpha-2,)</versionRange>
                                        <goals>
                                            <goal>set-system-properties</goal>
                                        </goals>
                                    </pluginExecutionFilter>
                                    <action>
                                        <ignore />
                                    </action>
                                </pluginExecution>
                            </pluginExecutions>
                        </lifecycleMappingMetadata>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>properties-maven-plugin</artifactId>
                <version>1.0-alpha-2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>set-system-properties</goal>
                        </goals>
                        <configuration>
                            <properties>
                                <property>
                                    <name>logback.configurationFile</name>
                                    <value>src/main/resources/logback.xml</value>
                                </property>
                            </properties>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Here “src/main/resources/logback.xml” has the logback configuration. Even if it is not present output may be sent to console