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 :)

Thursday 10 September 2015

How to mock static methods during unit testing?

Well, static mock is not implemented in Mockito, so we have to use PowerMock to achieve this:

Let's say we have the following class:

package com;

import
java.net.InetAddress;
import
java.net.UnknownHostException;

public final class
SystemUtils {

  
public static final String UNKNOWN_HOST = "Unknown";

   public static
String getHostName() {
      String hostname =
UNKNOWN_HOST;
      try
{
         InetAddress addr = InetAddress.getLocalHost()
;
        
// Get hostname
        
hostname = addr.getHostName();
     
} catch (UnknownHostException e ) {
         System.
out.println("catch UnknownHostException...");
     
}
     
return hostname;
  
}
}

and we need to test that UnknownHostException is thrown.
So our goal is to mock InetAddress.getLocalHost() and ask it to return an exception so SystemUtils.getHostName() will return 'Unknown'.

First import all needful libs:

<properties>

    <junit.version>4.11</junit.version>

    <mockito.version>1.10.19</mockito.version>

    <powermock.version>1.6.2</powermock.version>

</properties>



<dependency>
    <groupId>
junit</groupId>
    <artifactId>
junit</artifactId>
    <version>
${junit.version}</version>
    <scope>
test</scope>
</dependency>

<dependency>
    <groupId>
org.mockito</groupId>
    <artifactId>
mockito-all</artifactId>
    <version>
${mockito.version}</version>
    <scope>
test</scope>
</dependency>

<dependency>
    <groupId>
org.powermock</groupId>
    <artifactId>
powermock-api-mockito</artifactId>
    <version>
${powermock.version}</version>
    <scope>
test</scope>
</dependency>

<dependency>
    <groupId>
org.powermock</groupId>
    <artifactId>
powermock-module-junit4</artifactId>
    <version>
${powermock.version}</version>
    <scope>
test</scope>
</dependency>

<dependency>
    <groupId>
org.powermock</groupId>
    <artifactId>
powermock-module-junit4-rule</artifactId>
    <version>
${powermock.version}</version>
    <scope>
test</scope>
</dependency>

And test would look the following way:

import com.SystemUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.internal.stubbing.answers.ThrowsExceptionClass;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.net.InetAddress;
import java.net.UnknownHostException;
import static org.junit.Assert.assertEquals;


@RunWith(PowerMockRunner.class)
@PrepareForTest(SystemUtils.class)
public class SystemUtilsTest {

    @Test
    public void testGetHostName() throws UnknownHostException {
        PowerMockito.mockStatic(InetAddress.class);
        PowerMockito.when(InetAddress.getLocalHost())
                .then(new ThrowsExceptionClass(UnknownHostException.class));
        String actualValue = SystemUtils.getHostName();
        assertEquals("On exception expected unknown value", SystemUtils.UNKNOWN_HOST, actualValue);
    }
}

How to set log file with custom name in log4j2?

Sometimes having log4j2.xml file with default naming can be a problem if several projects share the same classpath. In order to change logger file at runtime the below method can be used:


public static void logAppInfo(String configFileName) {
    URL fileUrl = SLF4JHello.class.getClassLoader().getResource(configFileName);
    if (fileUrl == null) {
        throw new RuntimeException("File not found: " + configFileName);
    }
    try {
    LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
    loggerContext.setConfigLocation(fileUrl.toURI());
    loggerContext.updateLoggers();
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
}

How to enable smart import in Intellij Idea 14?

To enable auto-import and auto optimize imports go to:

Intellij Idea 14 -> Settings -> Editor -> General -> Auto Import

and check two options:

1. Optimize import on the fly
2. Add unambiguous imports on the fly

Tuesday 14 July 2015

How to set timezone in Weblogic?

1. Open file in Notepad
../{your_weblogic_folder}/user_projects/domains/{your_domain_name}/bin/setDomainEnv.cmd

2. Add to the property %JAVA_PROPERTIES% -Duser.timezone=GMT.
Line should look the following way:
set JAVA_PROPERTIES=%JAVA_PROPERTIES% %EXTRA_JAVA_PROPERTIES% -Duser.timezone=GMT

Friday 3 July 2015

How to write / read BLOB to / from Oracle database?

WRITE:

To transform String value into blob just execute your_string.getBytes();

String blobValue = "long blob";
bytes[] bytes = blobValue.getBytes();
int rows = getJdbcTemplate().update("update MY_TABLE set BLOB_COLUMN = ? where ROWID = '1'", bytes);

READ:

we can either read blob from database in Blob class or transform into String. To transform it into String we will need additional custom method:

public static String sqlBlobToString(Blob blob) {

StringBuilder stringBuilder = new StringBuilder();

try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(blob.getBinaryStream())) {
       while ((string = bufferedReader.readLine()) != null) {
              stringBuilder.append(string);
       }
 } catch (IOException e) {
       throw new RuntimeException(e);
}
return stringBuilder;
}


Querying from database:

String s = sqlBlobToString(getJdbcTemplate().queryForObject("select BLOB_COLUMN from MY_TABLE where ROWID = '1'", Blob.class));

Note: I am using java.sql.Blob

How to write / read CLOB to / from Oracle database?

WRITE:

there is no problems with clob saving into db - just keep it in String value and regularly save it:

String clobValue = "long clob";
int rows = getJdbcTemplate().update("update MY_TABLE set CLOB_COLUMN = ? where ROWID = '1'", clobValue);

READ:

we can either read clob from database in Clob class or transform into String. To transform it into String we will need additional custom method:

public static String sqlClobToString(Clob clob) {

StringBuilder stringBuilder = new StringBuilder();

try(BufferedReader bufferedReader = new BufferedReader(clob.getCharacterStream()) {
       while ((string = bufferedReader.readLine()) != null) {
              stringBuilder.append(string);
       }
 } catch (IOException e) {
       throw new RuntimeException(e);
}
return stringBuilder;
}

Querying from database:

String s = sqlClobToString(getJdbcTemplate().queryForObject("select CLOB_COLUMN from MY_TABLE where ROWID = '1'", Clob.class));

Note: I am using java.sql.Clob

Thursday 2 July 2015

How to switch to debug mode without application re-deploy in Intellij Idea for Weblogic?

1. Open file in Notepad
../{your_weblogic_folder}/user_projects/domains/{your_domain_name}/bin/setDomainEnv.cmd

2. Set the following value for JAVA_DEBUG variable, line will look this way:
set JAVA_DEBUG=-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=50000,server=y,suspend=n

where 50000 is any port number you wish to use for debug.

3. In Intellij Idea Run -> Edit Configuration ->click + and add 'Remote' configuration.

4. Configure Remote configuration: add 'Name', set 'Port' number, the same you have indicated in point 2.

Run application in regular mode and when needed switch to debug.

Wednesday 1 July 2015

How to start / stop weblogic manually?

START: Run ../user_projects/domains/your_domain_name/startWeblogic.cmd
or ../user_projects/domains/your_domain_name/bin/startWeblogic.cmd

STOP: Run ../user_projects/domains/your_domain_name/bin/stopWeblogic.cmd

How to create domain in weblogic?

1. Run ../oracle_common/common/bin/config.cmd
2. Configuration Wizard will open
3. CREATE DOMAIN: Choose "Create new domain" option and specify desired domain location with domain name in the end.
(Ex: C:\Users\arina\user_projects\domains\base_domain, where base_domain is our new domain name)
4. TEMPLATES: Leave as it is and click Next.
5. ADMINISTRATOR ACCOUNT: Enter administrator credentials and click Next
6. DOMAIN MODE and JDK: I choose Development for Domain Mode, and leave embedded Weblogic JDK, and click Next
7. ADVANCED CONFIGURATIONS: Mostly I usually need only Administration Server, chose it and click Next
8. ADMINISTRATION SERVER: Usually I leave Server Name as is "AdminServer" but it's optional. Listen port: specify which port you want weblogic to use, let's say 7171, 9191 or any you like, and click Next.
9. CONFIGURATION SUMMARY: review your configurations and click Create
10. After progress bar reached 100% and Next button activated, click Next.
11. Review Domain Location, Admin Server URL, if you need to start Start Admin Server right away select appropriate checkbox and click Finish.

How to clone specific branch in git?

If git repository is too big and you can't clone (or don't want to) all of it, you can clone specific branch:
git clone -b [branch_name] --single-branch http://arina.git

Monday 22 June 2015

How to personalize file header in Intellij Idea?

1. Press Ctrl+Alt+S
2. Look for File and Code templates
3. In Includes tab chose File Header
4. Add:

/**
* @author Arina Ielchiieva
* Date: ${DATE}
* Time: ${TIME}
*/

Friday 19 June 2015

Class < ? > vs Class usage

Class          // An unknown class (raw type)
Class<?>       // An unknown class (generic version)
Class<String>  // The String class

Since Java 1.5 you should use the generic form wherever possible. Class<?> clearly states that you mean "an unknown class".

Class<?> shows that you're intentionally writing Java 5-level code that doesn't know or care what class you are dealing with. Leaving out the makes it look like old code or code written by someone who hasn't learned generics yet.

How to view detailed information about Intellij Idea warnings?

Press Alt+Ctrl+S
Search for "Java Compiler"
In "Additional command line parameters:" type the following:-Xlint:unchecked
and recompile class again.

How To Acсess Target Object Behind a Spring Proxy?

If you have @Autowired spring bean but for some reason (preferably for unit testing purposes in order to stub something) you want to get target object behind Spring proxy:

((Advised)yourAutowiredBean).getTargetSource().getTarget();

AopUtils.isJdkDynamicProxy(yourAutowiredBean) - can confirm you got proxied object if you have any doubts.

Wednesday 17 June 2015

Which pid is using your port?

Show which pid uses your port:
netstat -a -n -o | find "your_port [ex: 9191]"

To kill pid from console: taskkill /pid pid_number

Good DataSource

DriverManagerDataSource by Spring can act weird sometimes, so the best choice to use Apache data source: BasicDataSource.

Configuration:
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl(JDBC_URL);
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
dataSource.setDriverClassName(DRIVER_CLASS_NAME);
}

Maven:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1</version>
</dependency>


How to match any enum?

Matchers.any(MyEnum.class):

when(serviceMock.preview(anyString(), any(DataSourceEnum.class)).thenReturn(anyMapOf(String.class, Collection.class)