Archive

Archive for the ‘Programming / tutorials’ Category

How to log incomplete request in apache tomcat

May 11th, 2017 No comments

We had been looking into  options on how to identify requests which are not logged in access logs because they could not be completed for any reason. So for those of you who are unaware,  access log only logs the request which are complete. Let us say users requests a page and for some reason the request never gets completed (Server crash, out of memory), you will never see that in access logs.

But more often than not you will need that request to identify what caused the crash

There are 3 potential options

Option 1:

Use Apache as a reverse proxy in front of Tomcat  and enabled mod_log_forensic to log all request

How does it work ?

Apache comes with a module mod_log_forensic

http://httpd.apache.org/docs/current/mod/mod_log_forensic.html

In this each request is logged two times

The first line logs the forensic ID, the request line and all received headers, separated by pipe characters (|).  A sample line looks like the following (all on one line):

+yQtJf8CoAB4AAFNXBIEAAAAA|GET /manual/de/images/down.gif HTTP/1.1|Host:localhost%3a8080|User-Agent:Mozilla/5.0 (X11; U; Linux i686; en-US; rv%3a1.6) Gecko/20040216 Firefox/0.8|Accept:image/png, etc…

The plus character at the beginning indicates that this is the first log line of this request. The second line just contains a minus character and the ID again:

Then next line would be , which signifies that request has been completed.

-yQtJf8CoAB4AAFNXBIEAAAAA

 

Advantage : Least invasive with very little noise. No code change in application.

Disadvantage : Apache is not a part of our deployment. So this requires IT to modify the infrastructure.

 

Option 2:

Development team does code changes to log incomplete request.

Advantage : Can control what to log and when to log.

Disadvantage : Code changes. Testing. Patch required for earlier versions of applications.

 

 Option 3:

Enable Request Dumper Filter in tomcat.

Tomcat comes with a  request dumper filter which logs all incoming and outgoing request.

https://tomcat.apache.org/tomcat-7.0-doc/config/filter.html

 

Advantage : Changes required in application’s web.xml  and server’s logging.properties. Technically this is code change but we can do directly on the application server.

Disadvantage : Very verbose. Logs everything in request.

From tomcat docs

WARNING: Using this filter has side-effects. The output from this filter includes any parameters included with the request. The parameters will be decoded using the default platform encoding. Any subsequent calls to request.setCharacterEncoding() within the web application will have no effect.

 

This is the output from one request with dumper filter enabled on webservice.

 

10-Apr-2017 11:49:27.409 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1 START TIME        =10-Apr-2017 11:49:27

10-Apr-2017 11:49:27.409 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1         requestURI=/cdpImport

10-Apr-2017 11:49:27.409 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1           authType=null

10-Apr-2017 11:49:27.410 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1  characterEncoding=utf-8

10-Apr-2017 11:49:27.410 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1      contentLength=45

10-Apr-2017 11:49:27.410 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1        contentType=text/plain; charset=utf-8

10-Apr-2017 11:49:27.410 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1        contextPath=

10-Apr-2017 11:49:27.410 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1             cookie=dummyCookie=make-sure-there-is-always-a-cookie

10-Apr-2017 11:49:27.420 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1         remoteAddr=127.0.0.1

10-Apr-2017 11:49:27.421 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1         remoteHost=127.0.0.1

10-Apr-2017 11:49:27.421 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1         remoteUser=null

10-Apr-2017 11:49:27.421 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1 requestedSessionId=null

10-Apr-2017 11:49:27.421 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1             scheme=http

10-Apr-2017 11:49:27.421 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1         serverName=localhost

10-Apr-2017 11:49:27.422 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1         serverPort=8085

10-Apr-2017 11:49:27.422 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1        servletPath=

10-Apr-2017 11:49:27.422 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1           isSecure=false

10-Apr-2017 11:51:07.619 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1           authType=null

10-Apr-2017 11:51:07.619 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1        contentType=text/plain;charset=ISO-8859-1

10-Apr-2017 11:51:07.620 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1             header=Content-Type=text/plain;charset=ISO-8859-1

10-Apr-2017 11:51:07.620 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1             header=Content-Length=211

10-Apr-2017 11:51:07.620 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1             header=Date=Mon, 10 Apr 2017 15:51:07 GMT

10-Apr-2017 11:51:07.620 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1         remoteUser=null

10-Apr-2017 11:51:07.620 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1             status=202

10-Apr-2017 11:51:07.621 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1 END TIME          =10-Apr-2017 11:51:07

10-Apr-2017 11:51:07.621 INFO [http-nio-8085-exec-1] org.apache.catalina.filters.RequestDumperFilter.doLog http-nio-8085-exec-1 ===============================================================

This is what you add in web.xml of your application

</pre>
<filter>
 <filter-name>requestdumper</filter-name>
 <filter-class>
 org.apache.catalina.filters.RequestDumperFilter
 </filter-class>
 </filter>
 <filter-mapping>
 <filter-name>requestdumper</filter-name>
 <url-pattern>*</url-pattern>
 </filter-mapping>

Categories: Programming / tutorials Tags:

What is default Connector in Tomcat 8

May 23rd, 2016 No comments

What is the default connector option in Tomcat 8 if you do not define explicitly ?

Given this configuration in server.xml

<Connector port="8080" protocol="HTTP/1.1" enableLookups="false" compression="on"

maxThreads="200" acceptCount="100" maxKeepAliveRequests="1" URIEncoding="UTF-8" />

what do you think will be default connector ?

Answer :  NIO(Non blocking connector)

This is the screen shot from Jconsole

default-protocol-tomcat8

From Tomcat documentation

Sets the protocol to handle incoming traffic. The default value is HTTP/1.1 which uses an auto-switching mechanism to
select either a non blocking Java NIO based connector or an APR/native based connector.
If thePATH (Windows) or LD_LIBRARY_PATH (on most unix systems) environment variables contain the Tomcat native library,
the APR/native connector will be used. If the native library cannot be found, the non blocking Java based connector will be used.
Note that the APR/native connector has different settings for HTTPS than the Java connectors.

So even though you have not explicitly defined a connector, tomcat 7, tomcat 8 and above will be using NIO Connector

Now I change the server.xml connector to


<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
 maxThreads="5000" SSLEnabled="false" scheme="https" secure="true"
 socket.appReadBufSize="1024"
 socket.appWriteBufSize="1024"
 clientAuth="false" sslProtocol="TLS"
 enableLookups="false" />

tomcat-connector-protocol

The data is available through JConsole

Categories: Programming / tutorials Tags:

Using @Scheduled annotation in spring

August 12th, 2015 No comments

If you are looking to scheduled task and are using spring framework, there are couple of alternatives

a) Quartz : Spring has support for quartz

b) @Scheduler annotation : Simple and easy.

Here is the code sample


public class SchedulerManager {

 @Scheduled(fixedRate = 10000)
 public void testMyScheduler(){

System.out.println(" I am the scheduler >>>>>>");
}
}

10000 is in milliseconds so you would see output after 10 seconds .

If you want to start after some delay and not at application start up


public class SchedulerManager {

@Scheduled(initialDelay=2000, fixedRate = 10000)
public void testMyScheduler(){

System.out.println(" I am the scheduler >>>>>>");
}
}

The method gets executed after delay of 2 seconds.

And if you want to use cron expression


public class SchedulerManager {

@Scheduled(cron="0 0/1 * * * ?")
public void testMyScheduler(){

System.out.println(" I am the cron scheduler >>>>>>");
}
}

The above method executes after 1 minute.

Remember spring calls it a cron expression but in fact it is not a true cron expression. If you use the actual cron expression , you would see some exception like

Caused by: java.lang.IllegalStateException: Encountered invalid @Scheduled method ‘testMySchedulerWithQuartz': Cron expression must consist of 6 fields (found 7 in “0 0/1 * * * ? *”)

And here is the simple applicationContext.xml file


 <task:annotation-driven />
 <bean id="scheduleManager" class="com.skg.demo.scheduler.SchedulerManager" />

The output after 10 seconds will be


I am the scheduler >>>>>>

I am the scheduler >>>>>>

I am the scheduler >>>>>>

You do not need any other configuration setup

Spring has complete documentation on various strategies

How do you dynamically change the log4j level

March 18th, 2015 1 comment

One of the common feature requested in most production application is to reload of log4j properties or lo4j xml file at runtime without retstarting of tomcat. Very helpful when you are debugging production level issues and would only like to turn on logging for a short period of time but also do not want any downtime.

I will show you a brief example on how to dynamically change the log4j level on a Tomcat server. This is a programmatic change

Set up includes

1. Jdk 1.7 and above2.

2. Apache-tomcat-7.0.57

3. Assumption your application is running on spring framework (I am on 3.2.2)

This is my java file. This configurer file  is required to reload the updated settings.


public class OptionalLog4jConfigurer extends Log4jConfigurer implements
 InitializingBean {

public static final Long DEFAULT_REFRESH = 30000L;
 private static final Log LOG = LogFactory
 .getLog(OptionalLog4jConfigurer.class);

private String configLocation;
 private Long refreshInterval;

public OptionalLog4jConfigurer(final String configLocation,
 final Long refreshInterval) {
 this.configLocation = configLocation;

if (refreshInterval == null) {
 this.refreshInterval = DEFAULT_REFRESH;
 }
 else {
 this.refreshInterval = refreshInterval;
 }
 }

/**
 * Will only customize if a configLocation has been specified.
 *
 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
 */
 public void afterPropertiesSet() throws Exception {
 if (!StringUtils.isEmpty(this.configLocation)) {
 LOG.info("Log4J configuration is being customized.");

this.initLoggingInternal();
 }
 else {
 LOG
 .info("Using default Log4J configuration. No customization requested");
 }
 }

public String getConfigLocation() {
 return this.configLocation;
 }

public Long getRefreshInterval() {
 return this.refreshInterval;
 }

}

Changes to application-Context.xml


 <bean id="optionalLog4jInitialization"  class="com.skg.jetm.OptionalLog4jConfigurer">
<constructor-arg index="0" type="java.lang.String"  value="${log4j.configuration}" />
<constructor-arg index="1" type="java.lang.Long" value="100" />
 </bean>

${log4j.configuration} is the path to your log4j file.

For local testing on my eclipse, I passed this value in jdk environment variables


-Dlog4j.configuration=file:\C:\Myfolder\log4j.properties -Dlog4j.debug

log4 in tomcat at runtime

When running with tomcat, you need to set up this in tomcat configuration


APPLICATION_OPTS="-Dlog4j.configuration=file:/C:/Myfolder/log4j.properties \
-Dlog4j.debug=true"

When I start tomcat,  the messages will be displayed as below


INFO: Deploying web application archive C:\devsoftware\apache-tomcat-7.0.57\webapps\myweb-0.0.1-SNAPSHOT.war
log4j: Using URL [file:/C:/apps44/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/C:/apps44/log4j.properties
log4j: Parsing for [root] with value=[error, stdout].
log4j: Level token is [error].
log4j: Category root set to ERROR
log4j: Parsing appender named "stdout".
log4j: Parsing layout options for "stdout".
log4j: End of parsing for "stdout".
log4j: Setting property [target] to [System.out].
log4j: Parsed "stdout" options.
log4j: Parsing for [com.skg] with value=[info].
log4j: Level token is [info].
log4j: Category com.skg set to INFO
log4j: Handling log4j.additivity.com.skg=[null]
log4j: Parsing for [com.crunchtime.util] with value=[error].
log4j: Level token is [error].
log4j: Category com.crunchtime.util set to ERROR
log4j: Handling log4j.additivity.com.crunchtime.util=[null]
log4j: Parsing for [org.springframework.web.context.ContextLoader] with value=[error].
log4j: Level token is [error].
log4j: Category org.springframework.web.context.ContextLoader set to ERROR
log4j: Handling log4j.additivity.org.springframework.web.context.ContextLoader=[null]
log4j: Finished configuring.
Feb 23, 2015 10:18:25 AM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deployment of web application archive C:\devsoftware\apache-tomcat-7.0.57\webapps\myweb-0.0.1-SNAPSHOT.war has finished in 2,434 ms

Change any settings in log4j file and you should see the context reload in tomcat server console


log4j: Parsing for [root] with value=[info, stdout].
log4j: Level token is [info].
log4j: Category root set to INFO
log4j: Parsing appender named "stdout".
log4j: Parsing layout options for "stdout".
log4j: End of parsing for "stdout".
log4j: Setting property [target] to [System.out].
log4j: Parsed "stdout" options.
log4j: Parsing for [com.skg] with value=[error].
log4j: Level token is [error].
log4j: Category com.skg set to ERROR
log4j: Handling log4j.additivity.com.skg=[null]
log4j: Parsing for [com.crunchtime.util] with value=[error].
log4j: Level token is [error].
log4j: Category com.crunchtime.util set to ERROR
log4j: Handling log4j.additivity.com.crunchtime.util=[null]
log4j: Parsing for [org.springframework.web.context.ContextLoader] with value=[error].
log4j: Level token is [error].
log4j: Category org.springframework.web.context.ContextLoader set to ERROR
log4j: Handling log4j.additivity.org.springframework.web.context.ContextLoader=[null]
log4j: Finished configuring.

Project at Github : Coming soon

Categories: Programming / tutorials Tags:

How to create a simple web app project with maven and eclipse and push to git

February 13th, 2015 No comments

here are normally 2 ways to build a simple web app project with maven and eclipse.

1. Using Maven Command line tool to  simple web app project
2. Use Eclipse to build simple  maven web project

Using Maven Command line tool to  simple web app project

Before we dive into details, let us understand what is archetype which we will be talking about in this blog ?

Archetype is a Maven project templating toolkit. An archetype is defined as an original pattern or model from which all other things of the same kind are made

Using Maven Command line tool to  simple web app project

To generate a simple maven web app project do this but the simple approach which I would advice is use command prompt

$ mvn archetype:generate -DgroupId=com.skg
-DartifactId=MyWebApp
-DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

Use Eclipse to build simple  maven web project

Select

File–>New–>Project

Chose Maven Project

use this archetype

ma

Will create a simple web project in eclipse for you

 

To build a simple project (non web based) and push to it

 

mvn archetype:generate -DgroupId=com.skg.social -DartifactId=socialIntegration -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

git eclipse:eclipse

Steps
1. Create a eclipse project using command line
2. go to directory of your porject for eg helloSpring
3. git init
4. git add * (adds all files recursively in directory to git)
5. git commit -m “first message”
6. Create a repo on git through their UI or command line
7. git remote add origin https://<url>/<username>/<project-name>.git
8. git push -u origin –all # pushes up the repo and its refs for the first time

This displays the remote url which is configured
git config remote.origin.url

git push origin local-name:remote-name

 

How to enable Load Time Weaving of Aspects in Spring

February 9th, 2015 No comments

We will talk about weaving in general and how to enable weaving in your spring application. You would have heard of weaving mostly with AOP programming and normally with Spring, but before we dive into Spring AOP, let us understand weaving.

What is weaving in programming ?

Weaving in general is a programmatic transformation which essentially means processing of a code to produce a desired output.

In Spring AOP makes it possible to modularize and separate logging, transaction like services and apply them declaratively to the components Hence programmer can focus on specific concerns. Aspects are wired into objects in the spring XML file in the way as JavaBean. This is also known as ‘Weaving’.

There are three types of weaving

  • Compile time
  • Post compile time
  • Run time

We can have source level weaving as in C++ using pre processors. In Java we can have byte code in which you add code at run time around your existing code.

The AspectJ weaver takes class files as input and produces class files as output. The weaving process itself can take place at one of three different times: compile-time, post-compile time, and load-time. The class files produced by the weaving process (and hence the run-time behaviour of an application) are the same regardless of the approach chosen.

  • Compile-time weaving is the simplest approach. When you have the source code for an application, ajc will compile from source and produce woven class files as output. The invocation of the weaver is integral to the ajc compilation process. The aspects themselves may be in source or binary form. If the aspects are required for the affected classes to compile, then you must weave at compile-time. Aspects are required, e.g., when they add members to a class and other classes being compiled reference the added members.
  • Post-compile weaving (also sometimes called binary weaving) is used to weave existing class files and JAR files. As with compile-time weaving, the aspects used for weaving may be in source or binary form, and may themselves be woven by aspects.
  • Load-time weaving (LTW) is simply binary weaving defered until the point that a class loader loads a class file and defines the class to the JVM. To support this, one or more “weaving class loaders”, either provided explicitly by the run-time environment or enabled through a “weaving agent” are required.

You may also hear the term “run-time weaving”. We define this as the weaving of classes that have already been defined to the JVM (without reloading those classes). AspectJ 5 does not provide explicit support for run-time weaving although simple coding patterns can support dynamically enabling and disabling advice in aspects.

We are going to show compile time weaving in the application. A preprocessor and aspect weaver are used to transform the original non-aspect code into a woven code. Thus, the original code is altered only once at compile-time.

Why did we use compile time weaving ? Because it leads to quicker startup time in your application. Drawback is that anytime the aspect gets modified, all code segments which are weaved by this aspect, must get recompiled.

Steps to enable Load Time Weaving of Aspects in your application

Step 1:

Add the following to your application context to inform Spring to activate the AOP injection.

</pre>
<div>
<pre><context:spring-configured/>

Step 2:
Add the @Configurable annotation to your entity. Use @Autowired annotation to inject dependencies

</pre>
<div>
<pre>@Configurable
public class MyClass{
...
@Autowired
Private transient MyRepository

}

Step 3:
To tell Spring/AspectJ which domain objects are going to be “woven”. Create a new directory “META-INF” in a directory which is included on the classpath. Add inside this directory a new file called “aop.xml”.

NOTE: Use the most restrictive packages possible. The smaller the code base inspected and instrumented, the faster startup time will be and the less runtime overhead

Add the following to that file:


<!DOCTYPE aspectj PUBLIC
"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver options="-Xreweavable -showWeaveInfo  -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler">
<exclude within="*..*CGLIB*" />
<exclude within="*..*javassist*" />
<include within="com..*.mypackage..*"/>
</weaver>
<aspects>
<aspect name="org.springframework.beans.factory.aspectj.AbstractInterfaceDrivenDependencyInjectionAspect"/>
</aspects>
</aspectj>

This adds the @Configurable support to those beans included in any sub package of the “com…*.mypackage” package and excludes files from CGLIB or javaassist packages and resolves weird errors related to cglib proxy class or javaassist. Step 4: Finally, you must tell the JVM to use the AspectJ “Java Agent”. This is needed for AspectJ to intercept method calls.This can be enabled when starting the JVM using the following argument:

</pre>
<div>
<pre>-javaagent:c:/devtk/LAS/lib/spring-instrument.jar

Why should you use Google Guava Libraries in your next project

January 27th, 2015 No comments

We have used google guava libraries heavily in our project and here are some core reasons why you should use guava libraries. Guava is open source library in java written by google. These are used by google so you can pretty much rely on them in your projects.

Why you should use Google Guava

An easy to use , out of the box libraries used by google engineers. Come with a lot of standard features which are missing in java. Since they have been used at google, you can be rest assured that they have thought about performance. I really like the useful functions they have build around collections like having mutable / immutable collections, supporting multikey map, static constructors.

Google calls the guava libraries as  productivity multiplier and I agree with that.

What we have used in Google Guava

Static Constructors

before JDK 7 , we would create a new constructor like

<br /><br />List cityList = new ArrayList();<br /><br />

After jdk7 , this has changed to

<br /><br />List cityList = new ArrayList&lt;&gt;();<br /><br />

Still I do not want to use new word. So in Guava, you can create using static constructor

List cityList = Lists.newArrayList();

Predicate

Determines a true or false value for a given input. More on predicate here Using predicates

Iterables

Look at this example on how you can iterate , and use predicate  to find out what

Set<>{

for (Target target : Iterables.filter(targets,
Predicates.not(new ConflictTargetPredicate()))) {
//do something
}

Multimap

Multimap in guava is similar to a Map, but you can associate multiple values with a single key. If you call put (K,V) twice, with the same key but different values, the multimap contains mappings from the key to both values.  So when you do a get(K),  A Collection<V) is returned.

Collections2

Renamed as Collections2  so that it does not conflict with java collections. Some of the major features in collections2 are

Immutable Collections

Immutable objects have many advantages, including:

  • Safe for use by untrusted libraries.
  • Thread-safe: can be used by many threads with no risk of race conditions.
  • Doesn’t need to support mutation, and can make time and space savings with that assumption. All immutable collection implementations are more memory-efficient than their mutable siblings (analysis)
  • Can be used as a constant, with the expectation that it will remain fixed

Making immutable copies of objects is a good defensive programming technique. Guava provides simple, easy-to-use immutable versions of each standard Collection type, including Guava’s own Collection variations.

JDK also provides collections to be immutable with Collections.unmodifiableXXX methods. Guava mentions that this is not good because

  • unwieldy and verbose; unpleasant to use everywhere you want to make defensive copies
  • unsafe: the returned collections are only truly immutable if nobody holds a reference to the original collection
  • inefficient: the data structures still have all the overhead of mutable collections, including concurrent modification checks, extra space in hash tables, etc.

When you don’t expect to modify a collection, or expect a collection to remain constant, it’s a good practice to defensively copy it into an immutable collection.

Sets.newHashSet() : Creates a mutable empty hashSet instance

Lists.newArrayList() : Creates a mutable arraylist

Convert Set to a List

Handy to convert  set to list without declaring a new object.

</pre>
<code>Lists.newArrayList([yourSet])</code>

Functional style programming

</pre>
Collection<?> myNotNullsCollection = filter(myCollection, notNull());

This will remove elements which are null and return a new copy. Remember this will not modify the existing copy. A really handy feature.

Caches

A very useful feature to store data for short term. helps in improve performance at expense of some memory. A use case is let say you have to calculate interest rates for all days in a  year and you need to do that 200 times.

 

How to Use Predicate

November 15th, 2014 No comments

Predicate

Predicate is interface from google guava which determines a true or false value for a given input.

How do you use Predicate ? Below is an example on how you can use predicate to find element from collection based on Id . It is assumed that the object which is a subclass or of type IDObject.


import java.util.Collection;
import java.util.Set;
import com.google.common.base.Predicate;

public class FindByIdPredicate implements
		Predicate<IDObject> {

	private Long entityId;

	public FindByIdPredicate(final Long entityId) {
		this.entityId = entityId;

	}

	@Override
	public boolean apply(final IDObject input) {
		return input.getId().equals(this.entityId);
	}

	/**
	 * @param Collection
	 * @return IdObject if present or null
	 */
	public IDObject getEntity(final Collection<? extends IDObject> collection) {

		for (IDObject idObject : collection) {
			if (this.apply(idObject)) {
				return idObject;
			}
		}
		return null;

	}

	/**
	 * @param Set
	 * @return IdObject if present or null
	 */
	@SuppressWarnings("unchecked")
	public <T> T getEntity(final Set<? extends IDObject> set) {

		for (IDObject idObject : set) {
			if (this.apply(idObject)) {
				return (T) idObject;
			}
		}
		return null;

	}
}

As you can see , it makes is super easy and quick to find an object from collection using predicate which other wise you would have to iteration and check for each object