Tuesday, 17 May 2016

How JMockit mocks static methods?

Dependency:
* Using old version

    <!-- jmockit should be before Junit -->
    <dependency>
      <groupId>com.googlecode.jmockit</groupId>
      <artifactId>jmockit</artifactId>
      <version>1.7</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

Code:

import mockit.Mocked;
import mockit.NonStrictExpectations;
import org.junit.Before;
import org.junit.Test;

import static mockit.Deencapsulation.invoke;
import static org.junit.Assert.assertEquals;

public class JMockitStaticMethod {

  @Mocked({"getenv"})
  private System system;

  @Before
  public void init()
  {
    // allow to return mock value any number of times
    new NonStrictExpectations(system)
    {
      {
        invoke(System.class, "getenv", "MOCKED_VALUE");
        returns("MOCKED");
      }
    };
  }

  @Test
  public void testJMockitStatic() {
    assertEquals("MOCKED", System.getenv("MOCKED_VALUE"));
  }

}


Dependency:
* Using new version:

  <!-- jmockit should be before Junit -->
    <dependency>
      <groupId>org.jmockit</groupId>
      <artifactId>jmockit</artifactId>
      <version>1.23</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>


Code (mocks easier):

import mockit.Expectations;

import org.junit.Before;
import org.junit.Test;

import static mockit.Deencapsulation.invoke;
import static org.junit.Assert.assertEquals;

public class JMockitStaticMethod {


  @Before
  public void init()
  {
    new Expectations(System.class)
    {
      {
        invoke(System.class, "getenv", "MOCKED_VALUE");
// returns("MOCKED")
        result = new ClassCastException();
      }
    };
  }

  @Test(expected = ClassCastException.class)
  public void testJMockitStatic() {
    assertEquals("MOCKED", System.getenv("MOCKED_VALUE"));
  }

}

How to add jar into classpath at runtime?

  // pathToJar -> /path/to/jar/MyJarName.jar

  public void addToClassPath(String pathToJar) throws Exception {
    File file = new File(pathToJar);
    Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
    method.setAccessible(true);
    method.invoke(ClassLoader.getSystemClassLoader(), file.toURI().toURL());
  }

TemporaryFolder in Junit

Dependencies:

    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>19.0</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

Code:
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;

public class TestTempFolder {

  // create temporary folder using Junit, it will be deleted automatically upon test success or failure
  // restriction: cannot be static
 // should be public
  @Rule
  public TemporaryFolder testFolder = new TemporaryFolder();

  @Test
  public void testTempFolder() throws Exception {
    // create file inside of temporary folder
    File mainFile = testFolder.newFile("main.csv");
    // write data into newly created file using guava lib
    Files.write("main data", mainFile, Charsets.UTF_8);
    // create folder inside of temporary folder
    File nestedFolder = testFolder.newFolder("nested");
    // create file inside of nested folder
    File nestedFile = new File(nestedFolder, "nested.csv");
    // write data into newly created file using guava lib
    Files.write("nested data", nestedFile, Charsets.UTF_8);
  }

}

Monday, 16 May 2016

3 ways to get file name without extension

Using apache commons
import org.apache.commons.io.FilenameUtils;

String fileNameWithoutExt = FilenameUtils.getBaseName(fileName);

                           OR

String fileNameWithOutExt = FilenameUtils.removeExtension(fileName);
Using Google Guava (If u already using it)
import com.google.common.io.Files;
String fileNameWithOutExt = Files.getNameWithoutExtension(fileName);
Or using Core Java
String fileName = file.getName();
int pos = fileName.lastIndexOf(".");
if (pos > 0) {
    fileName = fileName.substring(0, pos);
}

Thursday, 19 November 2015

How to implement Spring Cache?

To use simple Spring Cache based on Map logic we need to do two things:

1. Add cacheManager in our application context:

<cache:annotation-driven cache-manager="cacheManager"/>

<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
p:name="sourceSystemsCache/>
// add more caches
</set>
</property>
</bean>

2. In bean add annotation above method:

@Cacheable("cacheName") // in our case sourceSystemsCache
public int doSomething(int i) {..}

Note: besides cache name, you can indicate which values not to cache (usually using spring spel) etc.

Also useful is to reset cache which can be done using fake method or method that deletes date from db and we in out case delete it from our cache.

@CacheEvict(value = "cacheName", beforeInvocation = true)
public void deleteCacheName() { //do nothing }

@CacheEvict(value = "userCache", beforeInvocation = true)
public void deleteUserName(User user) { dao.delete(user); }

I had a task to reset all cache using rest, so I wrote service where I have autowired SimpleCacheManager and took its all cacheNames it contained and just cleared them:

public class CacheServiceImpl implements CacheService {

@Autowired
private SimpleCacheManager manager;

@Override
public boolean resetCache() {
    for (String cacheName : manager.getCaheNames()) {
         manager.getCache(cacheName).clear();
}
}

}

Monday, 16 November 2015

Why yoda time?



Original - https://mestachs.wordpress.com/tag/jodatime/

Don’t use java built-in classes, use jodatime and enforce this rule with sonar !

Don’t use java built-in classes

How many bugs in 5 lines of code ?
Date date = new Date(2007, 12, 13, 16, 40);
TimeZone zone = TimeZone.getInstance("Europe/Bruxelles");
Calendar cal = new GregorianCalendar(date, zone);
DateFormat fm = new SimpleDateFormat("HH:mm Z");
String str = fm.format(cal);
Just 6 bugs !
int year = 2007 - 1900;
int month = 12 - 1;
Date date = new Date(year, month, 13, 16, 40);
TimeZone zone = TimeZone.getInstance("Europe/Brussels");
Calendar cal = new GregorianCalendar(zone);
cal.setTime(date);
DateFormat fm = new SimpleDateFormat("HH:mm Z");
fm.setTimeZone(zone);
Date calDate = cal.getTime();
String str = fm.format(calDate);
If you want deeper explanations see this [presentation]

java.util.Date issues

  • From JDK1.0
  • Uses two digit years (from 1900)
  • January is 0, December is 11
  • Should have been immutable
  • Most methods deprecated in JDK1.1
  • Uses milliseconds from 1970 representation

java.util.Calendar issues

  • From JDK1.1
  • Uses subclasses for different calendar systems
  • January is 0, December is 11
  • Should have been immutable
  • Uses dual representation internally
    • value for each field
    • milliseconds from 1970 representation
  • Odd performance and bugs

java.util.DateFormat issues

  • Pattern based date formatting
  • “dd MMM yyyy”
  • Requires Date object
  • Not thread-safe : see rule findbugs : Multithreaded correctness – Call to static DateFormat
  • Not especially fast
  • Sun RFE to make thread-safe ignored

SQL – java.util.sql.Date, Time, Timestamp issues

Subclass java.util.Date
  • Date extends Date (!)
  • Time extends Date (!)
  • Override superclass to block methods (throws Exception)
  • Timestamp adds nanoseconds
  • equals() broken
  • All the problems of java.util.Date and more
  • timezone problem new Time(long)

Avoid millis manipulation and let’s use Jodatime !

when playing with java.util.Date you end up doing calculation in millis
int days = 40;
Date now = new Date();
long nowMillis = now.getTime();
Timestamp nowTimestamp = new Timestamp(nowMillis);
long future = 3600 24 * days * 1000;
Timestamp expiryTimestamp = new Timestamp(nowMillis + future);
System.out.println("nowTimestamp " + nowTimestamp);
System.out.println("expiryTimestamp " + expiryTimestamp);
this last code sample contains a bug… int vs long for days !
see this explaination the expiryTimestamp is before the nowTimestamp for “large days count”
nowTimestamp  2011-02-04 12:45:40.381
expiryTimestamp 2011-01-25 19:42:53.085
now let’s write the same code with joda time
DateTime nowTimestamp2 = new DateTime();
System.out.println("nowTimestamp    " + nowTimestamp2);
System.out.println("expiryTimestamp " + nowTimestamp2.plusDays(days));
it’s more readable… and most important it return the correct value ;)
nowTimestamp  2011-02-04T12:45:40.443+01:00
expiryTimestamp 2011-03-16T12:45:40.443+01:00

Sonar to the rescue

sonar can detect these issues :
  • Multithreaded correctness – Call to static Calendar
  • Multithreaded correctness – Call to static DateFormat
to fix them with jodatime let’s use the DateTimeFormat.
fmt=DateTimeFormat.forPattern("MMMM, yyyy");
DateTime datetime = fmt.parseDateTime(duedate);
this one is threadsafe and can be static and final field. or use the toString
datetime.toString("dd:MM:yy");
but the step further is to banish jdk date from your code base !
To do so, let’s define sonar architectural constraint like
  • Arch : avoid java.util.GregorianCalendar
  • Arch : avoid java.util.Date
  • Arch : avoid java.text.SimpleDateFormat
  • Arch : avoid java.sql.Timestamp
  • Arch : avoid java.sql.Date
to banish jdk dates from your model, you may implement hibernate usertype, jaxb adapter,…

Tuesday, 6 October 2015

Why we need serialVersionUID and how to generate it?

Why?

The best answer is from Java doc for java.io.Serializable

In two words:
1. helps to check if class version during deserialization is the same;
2. should be private;
3. is better than generated as the last one can cause errors.

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in anInvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members.

How to generate it?

Basically any number but Intellij Idea can generate it for you:

File -> Settings ->Inspections -> Java -> Serialization issues:
check Serializable class without 'serialVersionUID'

Once changes are applied, Intellij Idea will warn you that your class without serialVersionUID and suggest to generate it for you :)