Saturday, May 30, 2015

`java.util.Random` is thread-safe?

`java.util.Random` is thread-safe.

But based on Javadoc, contention will cause poor performance.

So you'd better use a thread-local `Random` as follows:

  private static final ThreadLocal<Random> RANDOM = new ThreadLocal<Random>() {
    @Override
    protected Random initialValue() {
      return new Random();
    }
  };

RANDOM.get().nextInt(100);

If you use JDK 1.7 or greater,

you can use `java.util.concurrent.ThreadLocalRandom` as follows:

ThreadLocalRandom.current().nextInt(100);

See content in a gzipped file in Linux

In Linux, to see content in a gzipped file,

you can use `zcat` as follows:

zcat some.gz | head > some.sample.log

Friday, May 29, 2015

JMX across firewall

If your application is in firewall,

you might think you could circumvent it by using the following system property:

com.sun.management.jmxremote.port=10000

But you can't.

It's for RMI registry, not for RMI server.

A port for RMI server is randomly chosen unless you customize RMISocketFactory.

In order words, you can't make JMX work across firewall without programming.

For details, see the reference.

Reference:
http://www.javacodegeeks.com/2013/11/two-things-to-remember-when-using-java-rmi.html

Tuesday, May 19, 2015

@Value("#{systemProperties.xxx}") with default value in Spring

If you run the following code with null:

  @Value("#{systemProperties.someResourceLocation}")
  private String someResourceLocation;

you will get the following exception:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 17): Property or field 'someResourceLocation' cannot be found on object of type 'java.util.Properties' - maybe not public?

You can use the following code instead:

  @Value("${someResourceLocation:" + DEFAULT_SOME_RESOURCE_LOCATION + "}")
  private String someResourceLocation;

Reference:
http://javavirtuoso.blogspot.kr/2012/11/autowiring-optional-properties-with.html

Monday, May 18, 2015

Don't use Mockito in production code.

Use it in test code only.

I suffered from memory leak caused by it

because of the following objects:

1,132,932,960 (45.97%) [24] 1 org/mockito/internal/verification/DefaultRegisteredInvocations 0x84c0fcc0

How to exclude a transitive dependency in a dependency in Gradle

In Gradle, to exclude a transitive dependency in a dependency,

do the following:

    compile("com.izeye.test:test-common:1.0.0") {
        exclude module: 'spring-boot-starter-security'
    }

Reference:
https://gradle.org/docs/current/userguide/dependency_management.html

Sunday, May 17, 2015

How to get aggregated (grouped) entities in Spring Data JPA

For example, if you want to get aggregated entities (`PerformanceTestResult`s),

you need a new entity type (`AggregatedPerformanceTestResult`)

and you can do the following:

public interface PerformanceTestResultRepository extends JpaRepository<PerformanceTestResult, Long> {

  @Query("select new AggregatedPerformanceTestResult("
      + "min(p.id), p.testCaseId, sum(p.activeWorkerCount), p.timestamp, min(p.collectedTime), "
      + "sum(p.requestCount), sum(p.timeoutCount), sum(p.totalResponseTime)) "
      + "from PerformanceTestResult p "
      + "where p.testCaseId = :testCaseId group by p.timestamp order by p.timestamp asc")
  List<AggregatedPerformanceTestResult> getAggregatedTestResultsByTestCaseId
      (@Param("testCaseId") long testCaseId);

}

Any better way?

Reference:
https://weblogs.java.net/blog/2007/04/25/java-persistence-query-return-types

Saturday, May 16, 2015

How to add mappings from URLs to view names by Java Config in Spring

In Spring, to add mappings from URLs to view names by Java Config,

do the following:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{

  @Override
  public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("index");
  }

}

Reference:
http://stackoverflow.com/questions/17049032/spring-bean-configuration-equivalent-to-mvcview-controller-path

How to convert a YAML file to a Java object using SnakeYAML

To convert a YAML file to a Java object using SnakeYAML,

if you have `src/main/resources/scenario/test_http.yaml` as follows:

name: test_http
testTarget: HTTP_SERVER
testCases:
  - id: 1
    timeoutInMillis: 100
    initialWorkerCount: 10
    rampUpStep: 1
    durationInSeconds: 300
  - id: 2
    timeoutInMillis: 100
    initialWorkerCount: 10
    rampUpStep: 10
    durationInSeconds: 300

you can convert the file to a Java object as follows:

  @Test
  public void test() throws FileNotFoundException {
    File file = ResourceUtils.getFile("classpath:scenario/test_http.yml");
    Yaml yaml = new Yaml(new Constructor(PerformanceTestScenario.class));
    PerformanceTestScenario testScenario
        = (PerformanceTestScenario) yaml.load(new FileReader(file));
    System.out.println(testScenario);
  }

Reference:
https://code.google.com/p/snakeyaml/wiki/Documentation

Thursday, May 14, 2015

How to use a random port for Spring Boot Actuator with @WebIntegrationTest

When Spring Boot Actuator is enabled with a different port,

if you run multiple tests with `@WebIntegrationTest(randomPort = true)`,

you will get the following exception:

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.IllegalStateException: Tomcat connector in failed state
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:157)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:288)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration.createChildManagementContext(EndpointWebMvcAutoConfiguration.java:219)
at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration.afterSingletonsInstantiated(EndpointWebMvcAutoConfiguration.java:141)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:101)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
... 36 more

`randomPort` works only for `server.port` not for `management.port`

so you have to use as follows:

@WebIntegrationTest({"server.port=0", "management.port=0"})

Reference:
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

Tuesday, May 12, 2015

How to use Java 8 Stream API's map() function with a function having more than 2 parameters



To use Java 8 Stream API's map() function

with a function having more than 2 parameters,

you can do as follows:

  public List<Banana> apples2Bananas(List<Apple> apples, AdditionalInfo additionalInfo) {
    Function<Apple, Banana> apple2BananaFunction = new Function<Apple, Banana>() {
      @Override
      public Banana apply(Apple apple) {
        return apple2Banana(apple, additionalInfo);
      }
    };
    return apples.stream().map(apple2BananaFunction).collect(Collectors.toList());
  }

  private Banana apple2Banana(Apple apple, AdditionalInfo additionalInfo) {
    ...
  }

It's sort of currying. Is there any better way to do this?

FIX:

Oops! I found a better way as follows:

  public List<Banana> apples2Bananas(List<Apple> apples, AdditionalInfo additionalInfo) {
    return apples.stream()
        .map(apple -> apple2Banana(apple, additionalInfo))
        .collect(Collectors.toList());
  }

Reference:
http://en.wikipedia.org/wiki/Currying

Monday, May 11, 2015

How to access fields in an underlying object in java.lang.reflect.Proxy, especially org.springframework.aop.framework.JdkDynamicAopProxy

To access fields in an underlying object in java.lang.reflect.Proxy,

especially org.springframework.aop.framework.JdkDynamicAopProxy,

you can use the following code:

    DirectFieldAccessor directFieldAccessor = new DirectFieldAccessor(someRepository);
    Object h = directFieldAccessor.getPropertyValue("h");
    directFieldAccessor = new DirectFieldAccessor(h);
    Object advised = directFieldAccessor.getPropertyValue("advised");
    directFieldAccessor = new DirectFieldAccessor(advised);
    Object targetSource = directFieldAccessor.getPropertyValue("targetSource");
    directFieldAccessor = new DirectFieldAccessor(targetSource);
    Object target = directFieldAccessor.getPropertyValue("target");
    directFieldAccessor = new DirectFieldAccessor(target);
    directFieldAccessor.setPropertyValue("sqlSessionSelector", sqlSessionSelector);

How to list all tables that a account has privileges in Oracle

In Oracle, to list all tables that a account, say 'TEST', has privileges,

use the following SQL:

SELECT * FROM ALL_TAB_PRIVS WHERE GRANTEE = 'TEST';

Saturday, May 9, 2015

ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails

You can encounter the following error in MariaDB (or MySQL):

MariaDB [db_test]> drop table application;
ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
MariaDB [db_test]>

If you want to disable foreign key checking, just do as follows:

MariaDB [db_test]> set foreign_key_checks=0;
Query OK, 0 rows affected (0.00 sec)

MariaDB [db_test]> drop table application;
Query OK, 0 rows affected (0.00 sec)

MariaDB [db_test]> set foreign_key_checks=1;
Query OK, 0 rows affected (0.00 sec)

MariaDB [db_test]>

Refernce:
http://stackoverflow.com/questions/3334619/cannot-delete-or-update-a-parent-row-a-foreign-key-constraint-fails

Friday, May 8, 2015

Spring Data JPA JPQL Sample

The following code is Spring Data JPA JPQL sample:

public interface ServerRepository extends JpaRepository<Server, Long> {

  @Query("SELECT application FROM Application application WHERE application.server = :server")
  List<Application> getAllApplications(@Param("server") Server server);

}

and the following code tests it:

  @Autowired
  ServerRepository serverRepository;

  @Test
  public void testGetAllApplications() {
    Server server = serverRepository.findOne(1L);
    serverRepository.getAllApplications(server).stream().forEach(System.out::println);
  }

Reference:
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.named-parameters

Wednesday, May 6, 2015

How to create `git.properties` file for Spring Boot Actuator's `info` endpoint in Gradle

In Gradle, to create `git.properties` file for Spring Boot Actuator's `info` endpoint,

add the following to `build.gradle`:

import org.ajoberstar.grgit.operation.OpenOp

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }

    dependencies {
        classpath("org.ajoberstar:gradle-git:1.1.0")
    }
}

task generateGitProperties {
    doLast {
        def openOp = new OpenOp()
        openOp.setDir('.')

        def repo = openOp.call()
        def headCommit = repo.head()
        ext.gitBranch = repo.branch.current.name
        ext.gitCommitId = headCommit.abbreviatedId
        ext.gitCommitTime = new Date(headCommit.time * 1000L).format("yyyy-MM-dd'T'HH:mm:ssZ")
       
        File resourcesMainDir = new File(project.buildDir, 'resources/main')
        File gitPropertiesFile = new File(resourcesMainDir, 'git.properties')
        gitPropertiesFile.text = """git.branch=${gitBranch}
git.commit.id=${gitCommitId}
git.commit.time=${gitCommitTime}
"""
    }
}

project.tasks.jar.dependsOn('generateGitProperties')

References:
https://github.com/ajoberstar/gradle-git/wiki/Grgit%20Usage
https://jdpgrailsdev.github.io/blog/2014/10/14/spring_boot_gradle_git_info.html

JMX client sample

This is a JMX client sample:

public class JmxTests {

  /**
   * Run with the following VM options:
   * -Dcom.sun.management.jmxremote.port=9999
   * -Dcom.sun.management.jmxremote.authenticate=false
   * -Dcom.sun.management.jmxremote.ssl=false
   *
   * @throws IOException
   */
  @Test
  public void test() throws IOException, MalformedObjectNameException, InstanceNotFoundException, MBeanException, AttributeNotFoundException, ReflectionException {
    echo("\nCreate an RMI connector client and "
        + "connect it to the RMI connector server");
//    JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
    JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://10.99.99.35:30001/jmxrmi");
    JMXConnector jmxc = JMXConnectorFactory.connect(url, null);

    MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

    echo("\nDomains:");
    String domains[] = mbsc.getDomains();
    Arrays.sort(domains);
    for (String domain : domains) {
      echo("\tDomain = " + domain);
    }

    echo("\nMBeanServer default domain = " + mbsc.getDefaultDomain());

    echo("\nMBean count = " +  mbsc.getMBeanCount());
    echo("\nQuery MBeanServer MBeans:");
    Set<ObjectName> names = new TreeSet<ObjectName>(mbsc.queryNames(null, null));
    for (ObjectName name : names) {
      echo("\tObjectName = " + name);
    }

    ObjectName objectName = new ObjectName("java.lang:type=OperatingSystem");
    double systemLoadAverage = (double) mbsc.getAttribute(objectName, "SystemLoadAverage");
    System.out.println(systemLoadAverage);

    jmxc.close();
  }

  private void echo(String message) {
    System.out.println(message);
  }

}

References:
https://docs.oracle.com/javase/tutorial/jmx/remote/custom.html
http://docs.oracle.com/cd/E19226-01/821-0031/gcitw/index.html