Friday, December 15, 2017

Example code to connect node.js REST service with Eureka discovery service

Eureka is Spring based discovery service developed by Netflix.

To know how Eureka is used at Netflix visit: https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance#how-is-eureka-used-at-netflix


Use 'eureka-js-client' node.js based library to connect to Eureka: https://www.npmjs.com/package/eureka-js-client


Installation Steps:

  1. Download and install Eureka discovery service. To setup Eureka with Spring Boot visit the link: https://spring.io/guides/gs/client-side-load-balancing/
  2. install node.js (link: https://nodejs.org/en/)
  3. npm init -y (creates package.json. This step is optional)
  4. npm i eureka-js-client --save (https://www.npmjs.com/package/eureka-js-client)


Below code will help you register node.js based REST service with Eureka.

Code:

'use strict';

// Or, if you're not using a transpiler:
const Eureka = require('eureka-js-client').Eureka;

// example configuration
const client = new Eureka({
  // application instance information
  instance: {
    app: 'jqservice',
    hostName: 'localhost',
    ipAddr: '127.0.0.1',
    port: {
      '$': 8080,
      '@enabled': 'true',
    },
    vipAddress: 'jq.test.something.com',
    statusPageUrl: 'http://localhost:8080/info',
    dataCenterInfo: {
    '@class': 'com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo',
      name: 'MyOwn',
    },
  },
  eureka: {
    // eureka server host / port
    host: '127.0.0.1',
    port: 8761,
    servicePath: '/eureka/apps/'
  },
});

function connectToEureka() {              
    client.logger.level('debug');  
    client.start(function(error) {
    console.log('########################################################');
    console.log(JSON.stringify(error) || 'Eureka registration complete');   }); }

 connectToEureka();

If above installation steps are complete then open node.js command prompt and execute command:

node eureka-connect-sample.js


Note: Above code is saved within eureka-connect-sample.js file.

Output:

registered with eureka:  jqservice/localhost
retrieved registry successfully
########################################################


Issues faced:

Issues 1: Error starting the Eureka Client Error: eureka registration FAILED: status: 404 body: undefined

    at D:\training\micro-services\eureka\node_modules\eureka-js-client\lib\EurekaClient.js:278:23
    at D:\training\micro-services\eureka\node_modules\eureka-js-client\lib\EurekaClient.js:633:7
    at D:\training\micro-services\eureka\node_modules\async\dist\async.js:473:16

Solution: 

You might be missing statusPageUrl: 'http://localhost:8080/info' //see above code

 

Issue 2: Error starting the Eureka Client Error: eureka registration FAILED: status: 400 body: [object Object]

    at D:\training\micro-services\eureka\node_modules\eureka-js-client\lib\EurekaClient.js:278:23
    at D:\training\micro-services\eureka\node_modules\eureka-js-client\lib\EurekaClient.js:633:7
    at D:\training\micro-services\eureka\node_modules\async\dist\async.js:473:16

Solution: 

//See above code
dataCenterInfo: {
    '@class': 'com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo',
      name: 'MyOwn',
    },

For Amazon datacenters (and the newer eureka JSON format), I think you'll need to pass a different value for @class. Try using: com.netflix.appinfo.AmazonInfo. For more information visit link: https://stackoverflow.com/questions/40425787/400-from-eureka-js-client-with-amazon


Friday, November 24, 2017

Java 9: JLink tool to assemble & optimize module dependencies into custom runtime

  • Jlink tool is used to assemble and optimize a set of modules & their dependencies into a custom runtime image.
  • It links a set of modules, along with their transitive dependencies, to create a custom runtime image.

Jlink Example

Command: jlink --module-path "C:/Program Files/Java/jdk-9/jmods";mlib;mods --add-modules com.greetings --output greetingsapp

com.greetings can be any Java 9 module.

Output builds custom java runtime in greetingsapp folder.

Switch to folder: greetingsapp\bin

Execute command: java --list-modules

Output:

com.greetings
java.base@9-ea
com.messaging
com.messaging.factory

Result shows modules required for com.greetings. Rest all JRE modules are skipped.

It creates light weight runtime. It can reduce your WAR/JAR size which in term reduce server or docker foot print.

Note:

  • Developers are responsible for updating their custom runtime images.
  • Custom runtime images don’t have built-in support for automatic updates.

References:

JLink: https://docs.oracle.com/javase/9/tools/jlink.htm

Friday, October 27, 2017

Java 8: jdeps a command-line static dependency checker tool

jdeps is a command-line Static Dependency Checker introduced in JDK 8.

  • It is a "Java [static] class dependency analyzer" that is useful for quickly identifying "static dependencies of [developers'] applications and libraries.
  • jdeps that takes a look at your non-modular code and tells you about its dependencies. Run it to find out if your application and libraries depend on any JDK's internal APIs.
  • It is a static analysis tool on the given class files and dynamic class dependencies (Class.forName or loading of service providers etc) are not reported.
  • jdeps.exe can be find in your JDK's bin folder. In Windows OS it can be found at location: C:\Program Files\Java\jdk1.8.0_102\bin along with other tools like javac and jps.  
  • It analyzes the immediate dependencies of a specific class in a given classpath. If dependencies are missing from classpath then you will get "not found" message for those artifacts as it is highlighted below in RED.

Jdeps Example

Command: jdeps mods/com.messaging/org/messaging/World.class

Output: 

    World.class -> java.base
    World.class -> not found
       com.messaging                                     -> java.lang                                          java.base
       com.messaging                                     -> com.messaging.factory                   not found

Command: jdeps "C:\Program Files\Java\jdk1.8.0_102\lib\jconsole.jar“

Output:

    split package: com.sun.tools.jconsole [jrt:/jdk.jconsole, C:\Program Files\Java\jdk1.8.0_102\lib\jconsole.jar]
    split package: sun.tools.jconsole [jrt:/jdk.jconsole, C:\Program Files\Java\jdk1.8.0_102\lib\jconsole.jar]
    split package: sun.tools.jconsole.inspector [jrt:/jdk.jconsole, C:\Program Files\Java\jdk1.8.0_102\lib\jconsole.jar]
    jconsole.jar -> JDK removed internal API
    jconsole.jar -> java.base
    jconsole.jar -> java.desktop
    jconsole.jar -> java.logging
    jconsole.jar -> java.management
    jconsole.jar -> java.management.rmi
    jconsole.jar -> java.rmi
    jconsole.jar -> jdk.attach
    jconsole.jar -> jdk.internal.jvmstat
    jconsole.jar -> jdk.management
    com.sun.tools.jconsole                             -> java.beans                                         java.desktop

Thursday, October 26, 2017

Java 9: Jdeprscan tool introduction

Java SE 9 provides a tool jdeprscan that scans a aggregation of class for uses of deprecated API elements from Java SE. 

heavy breathing
  • This tool can help you check if your application is Java 9 ready or not.
  • It will be useful for applications that use libraries already been compiled and the user of that library has no idea as to what deprecated APIs he/she is using.
  • jdeprscan is a static analysis tool scans a jar file (or some other aggregation of class files) for uses of deprecated API elements.
  • jdeprscan scans each argument for usages of deprecated APIs. The arguments can be a:
        dir: Directory
        jar: JAR file
        class: Class name or class file
     
  • The deprecated APIs identified by the jdeprscan are only those that are defined by Java SE. Deprecated APIs defined by third party libraries aren’t reported.
  • jdeprscan.exe (for e.g. Windows) is available within JDK 9. It can be found in your installed JDK bin (e.g. C:\Program Files\Java\<JDK9-Location>\bin) folder along with other tools like javac.exe and jsp.exe.

Jdeprscan Example

Command: jdeprscan "C:\Program Files\Java\jdk1.8.0_102\lib\jconsole.jar"

Output:

Jar file C:\Program Files\Java\jdk1.8.0_102\lib\jconsole.jar:
error: cannot find class sun/misc/Version
class sun/tools/jconsole/inspector/Utils$CopyKeyAdapter uses deprecated method java/awt/event/InputEvent::getModifiers()I
class sun/tools/jconsole/inspector/Utils uses deprecated method java/lang/Character::<init>(C)V
error: cannot find class sun/management/ConnectorAddressLink
class sun/tools/jconsole/MemoryPoolProxy uses deprecated method java/lang/Long::<init>(J)V
class sun/tools/jconsole/VMPanel$1 uses deprecated method java/awt/event/InputEvent::getModifiers()I

Tuesday, October 24, 2017

Java 9: What does the future hold for sun.misc.Unsafe?

Unsafe provided access to low-level features that aided in the development of many tools:

  • The Oracle position – “Unsafe must die in a fire
  • Unsafe library was not in fact meant to be accessible to anyone outside the internal development team in the first place.
  • Many developers were fearful that same features don’t have any alternatives outside of the internal JVM library.
  • To address all concerns for now Unsafe is made accessible in JDK 9 under jdk.unsupported module.
  • Possibly getting deprecated in next JDK version.
  • Critical internal APIs for which replacements are introduced in JDK 9 will be deprecated in JDK 9 and either encapsulated or removed in JDK 10. 

Will removal of sun.misc.Unsafe break Spring, Hibernate in Java 9?

  • The references are not in the core of Spring or Hibernate but some other libraries listed below may break:
  1. Guava
  2. GWT
  3. Netty
  4. Jersey-Common
  5. Infinispan
  6. Jboss-Modules

Example demonstrates how we we can use sun.misc.Unsafe in Java 9:

Module declaration for jdk.unsupported:
 

module jdk.unsupported {
    exports sun.misc;
    exports sun.reflect;
    exports com.sun.nio.file;
    opens sun.misc;
    opens sun.reflect;
}
To use Unsafe add jdk.unsupported in code’s module declaration:

module java9unsafe {   
 requires jdk.unsupported;
}
 

Friday, October 14, 2016

Java 8 lambda expression & method reference made easy

Lambda expression facilitates functional programming in Java. 

  • Lambda expression is a function which can be created without belonging to any class. Lambda expression can be passed around as if it was an object and executed on demand as method reference.
  • Lambda expressions are used primarily to define inline implementation of a functional interface, i.e., an interface with a single method only. Following demonstrates serious ways of using lamda expression.

Method reference:

A method reference is the shorter more concise syntax for a lambda expression that executes just ONE method.

There are four types of method references:
  • A method reference to a static method.
  • A method reference to an instance method of an object of a particular type.
  • A method reference to an instance method of an existing object.
  • A method reference to a constructor.

Sample program:

// Functional interfaces are heart of lambda expression
@FunctionalInterface
interface FuncIface {
    public void referenceDemo(); //Only one abstract method is allowed in functional interface
}

//Example class
class LambdaExample {
    private static int i;
    public static void commonMethod() {
        System.out.println("This method is already defined." + ++i);//can i use static method as lambda method reference?
    }
   
    public LambdaExample() {
        System.out.println("LambdaExample constructor called");
    }

    public static void main(String[] args) {

        // Anonymous class
        FuncIface demoOne = new FuncIface() {
            @Override
            public void referenceDemo() {
                LambdaExample.commonMethod();
                System.out.println("LambdaExample -> " + this);//What will this print?
            }
        };
        demoOne.referenceDemo();

        // Lambda implementation
        FuncIface demo = () -> LambdaExample.commonMethod();
        demo.referenceDemo();

        // Static method can be used as method reference
        FuncIface demoTwo = LambdaExample::commonMethod;
        demoTwo.referenceDemo();
       
        // Instance method reference
        LambdaExample o = new LambdaExample();
        FuncIface demoThree = o::m1;
        demoThree.referenceDemo();
       
        // Method reference.
        FuncIface demoFour = () -> {
            LambdaExample.commonMethod();
            System.out.println(++i);
        };
        demoFour.referenceDemo();
               
        // Constructor can be used as method reference using ::new
        FuncIface demo4 = LambdaExample::new; //LambdaExample constructor used as method reference
        FuncIface demo5 = String::new;//String constructor used as method reference
       
    }
   
    public void m1() {
        System.out.println("m1() called");
    }

}


Output:

This method is already defined.1
LambdaExample -> LambdaExample$1@15db9742
This method is already defined.2
This method is already defined.3
LambdaExample constructor called
m1() called
This method is already defined.4
5


References:

Friday, August 17, 2012

Performance comparison of Executor framework vs Fork/Join framework’s RecursiveTask feature in java or JDK7

I was testing new RecursiveTask feature of ForkJoin framework introduced in JDK7 or Java 1.7.

There are two types of ForkJoinTask specializations:
  1. Instances of RecursiveAction represent executions that do not yield a return value.
  2. In contrast, instances of RecursiveTask yield return values.
I have already posted an example of RecursiveAction in previous post. To know more about theoretic details and RecursiveAction sample code, you can visit the link: How to use Fork-Join Framework features in JDK7?


In this post I will do comparison of Executor Framework Vs ForkJoin framework's RecursiveTask feature. Following example fills primitive long array of size 100000000 with values from 0 to 10000000.

I use executor framework to calculate the sum of whole array  then I perform same logic using ForkJoin framework's RecursiveTask feature. To setup the example, I will first show the code which uses executor framework and its result then I will show ForkJoin framework's RecursiveTask feature implementing same logic and its result. Array sum logic in both samples was executed 10 times to get the average output and performance difference.

Update 1: Anonymous commenter advised to split the executor pool in even size (4 = number of available processors in my case) to maximize the through put. Advise well taken and updated blog as well. There is defiantly improvement in performance.

Executor framework code sample:

import static java.util.Arrays.asList;

import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ExecutorSum {
    Random random = new Random();

    // Fill array with its own index value
    public void fillArray(long[] array) {
        for (int i = 0; i < array.length; i++) {
            array[i] = i;
        }
    }

    public static void main(String[] args) throws InterruptedException,
            ExecutionException {
        ExecutorSum sum = new ExecutorSum();
        long[] array = new long[10_00_00_000];
        sum.fillArray(array);

        for (int i = 0; i < 10; i++) {
            int processors = Runtime.getRuntime().availableProcessors();
            ExecutorService executor = Executors.newFixedThreadPool(processors);
            List<Future<Long>> results;
            long start = System.currentTimeMillis();
          
            // array size/No. of processors
            int splitCount = array.length / processors;
          
            //Split pool size into even size for maximum through put
            results = executor.invokeAll(asList(new ArraySum(array, 0,
                    splitCount), new ArraySum(array, splitCount + 1,
                    splitCount * 2), new ArraySum(array, (splitCount * 2) + 1,
                    splitCount * 3), new ArraySum(array, (splitCount * 3) + 1,
                    array.length)

            ));

            executor.shutdown();

            // Calculating final result sum
            long count = 0;
            for (Future<Long> result : results) {
                count = count + result.get();
            }

            System.out.println("result: " + count);
            System.out.println("Sequential processing time: "
                    + (System.currentTimeMillis() - start) + " ms");
        }
    }
}

class ArraySum implements Callable<Long> {
    private final long from;
    private final long to;
    private long[] array;

    ArraySum(long[] array, long from, long to) {
        this.from = from;
        this.to = to;
        this.array = array;
    }

    @Override
    public Long call() throws Exception {
        long count = 0L;
        // Calculating sum of the given array range
        for (int i = (int) from; i < to; i++) {
            count = count + array[i];
        }

        return count;
    }
}

Output:

result: 4999999800000000
Sequential processing time: 113 ms
result: 4999999800000000
Sequential processing time: 108 ms
result: 4999999800000000
Sequential processing time: 113 ms
result: 4999999800000000
Sequential processing time: 124 ms
result: 4999999800000000
Sequential processing time: 122 ms
result: 4999999800000000
Sequential processing time: 107 ms
result: 4999999800000000
Sequential processing time: 123 ms
result: 4999999800000000
Sequential processing time: 134 ms
result: 4999999800000000
Sequential processing time: 122 ms
result: 4999999800000000
Sequential processing time: 109 ms

Fork/Join framework code sample:

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class ForkJoinSumTask {
   
    public void fillArray(long[] array) {
        for (int i=0; i<array.length; i++) {
            array[i] = i;
        }
    }

    public static void main(String[] args) {
        ForkJoinSumTask sum = new ForkJoinSumTask();
        long[] array = new long[10_00_00_000];
        sum.fillArray(array);
       
        System.out.println("Number of processors available: " + Runtime.getRuntime().availableProcessors());
       
        ForkJoinPool fjpool = new ForkJoinPool(32); //Default parallelism level = Runtime.getRuntime().availableProcessors()
       
        for (int i=0; i<10; i ++) {
            RecursiveSumTask task = new RecursiveSumTask(array, 0, array.length);
            long start = System.currentTimeMillis();
            System.out.println("Result: " + fjpool.invoke(task));
            System.out.println("Parallel processing time: "    + (System.currentTimeMillis() - start)+ " ms");
        }
       
        System.out.println("Number of steals: " + fjpool.getStealCount() + "\n");
    }
}

class RecursiveSumTask extends RecursiveTask<Long> {
    private static final long serialVersionUID = 1L;
    private final long from;
    private final long to;
    private long[] array;
    final int splitSize = 10_00_0000; //Some threshold size to spit the task

    RecursiveSumTask(long[] array, long from, long to) {
        this.from = from;
        this.to = to;
        this.array = array;
    }

    @Override
    protected Long compute() {
        long count = 0L;
        List<RecursiveTask<Long>> forks = new LinkedList<>();
       
        if ( to - from > splitSize) {
            // task is huge so divide in half
            long mid = (from + to) >>> 1;
           
            //Divided the given task into task1 and task2
            RecursiveSumTask task1 = new RecursiveSumTask(array, from, mid);
            forks.add(task1);
            task1.fork();
           
            RecursiveSumTask task2 = new RecursiveSumTask(array, mid, to);
            forks.add(task2);
            task2.fork();
        } else {
            //Calculating sum of the given array range
            for (int i = (int) from; i < to; i++) {
                count = count + array[i];
            }
        }
       
        //Waiting for the result
        for (RecursiveTask<Long> task : forks) {
            count = count + task.join();
        }
       
        return count;
    }
}

Output:

Number of processors available: 4
Result: 4999999950000000
Parallel processing time: 135 ms
Result: 4999999950000000
Parallel processing time: 123 ms
Result: 4999999950000000
Parallel processing time: 105 ms
Result: 4999999950000000
Parallel processing time: 115 ms
Result: 4999999950000000
Parallel processing time: 111 ms
Result: 4999999950000000
Parallel processing time: 114 ms
Result: 4999999950000000
Parallel processing time: 114 ms
Result: 4999999950000000
Parallel processing time: 109 ms
Result: 4999999950000000
Parallel processing time: 126 ms
Result: 4999999950000000
Parallel processing time: 128 ms
Number of steals: 301

Conclusion:

Both code samples calculate array sum 10 times to warmup HotSpot JVM and get average result. As you can see from both outputs, there is no visible improvement in the performance using RecursiveTask. May be my sum logic is small and not so complex. If the logic is more complex then performance difference will be lot more.

References:
  1. How to use Fork-Join Framework features in JDK7?  
  2. Fork and Join: Java Can Excel at Painless Parallel Programming 
  3. JDK 7 Adoption Guide

Example code to connect node.js REST service with Eureka discovery service

Eureka is Spring based discovery service developed by Netflix. To know how Eureka is used at Netflix visit: https://github.com/Netflix/e...