JDK9 REPL

I have been building and quickly exploring various JDK 9 features during this past weekend.
There is a new REPL now among other gems. I will update this post as I explore it further.

Mohans-MacBook-Pro:openjdk radhakrishnan$ java -version
java version “1.9.0-ea”
Java(TM) SE Runtime Environment (build 1.9.0-ea-b61)
Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b61, mixed mode)
Mohans-MacBook-Pro:openjdk radhakrishnan$ java -jar kulla-0.508-20150510054454.jar
| Welcome to JShell — Version 0.508
| Type /help for help

->

-> String s = “__mainn__”.replaceAll(“[^a-z\\s]”, “”);
| Added variable s of type String with initial value “mainn”

-> System.out.println(s);

-> mainn

-> final Map count = s.chars().map(Character::toLowerCase).collect(TreeMap::new, (m, c) -> m.merge((char) c, 1, Integer::sum), Map::putAll);
| Warning:
| Modifier ‘final’ not permitted in top-level declarations, ignored
| final Map count = s.chars().map(Character::toLowerCase).collect(TreeMap::new, (m, c) -> m.merge((char) c, 1, Integer::sum), Map::putAll);
| ^—^
| Added variable count of type Map with initial value {a=1, i=1, m=1, n=2}

-> int x = 26;
| Added variable x of type int with initial value 26

-> count.entrySet().stream().sorted((l, r) -> r.getValue().compareTo(l.getValue())).forEach(e -> count.merge(e.getKey(), x–, Math::multiplyExact));

-> System.out.println(count.entrySet().stream());
java.util.
-> stream.ReferencePipeline$Head@548a9f61

-> System.out.println(count.entrySet().stream().mapToDouble(e -> e.getValue()).sum());
124.0

Everything can be changed in the REPL. Nothing is final and it is ignored. That is what kulla-dev@openjdk.java.net told me.

Resolution for MacOS issue related to freetype

A new pull request is submitted.

git clone http://github.com/mohanr/adoptopenjdk-getting-started-kit.git

cd adoptopenjdk-getting-started-kit

git remote add upstream https://github.com/neomatrix369/adoptopenjdk-getting-started-kit.git

git fetch upstream

From https://github.com/neomatrix369/adoptopenjdk-getting-started-kit
* [new branch] Nashorn -> upstream/Nashorn
* [new branch] master -> upstream/master
Mohans-MacBook-Pro:adoptopenjdk-getting-started-kit radhakrishnan$ ls
LANGS.md cover.jpg cover_small.jpg en pt
Mohans-MacBook-Pro:adoptopenjdk-getting-started-kit radhakrishnan$ cd pt
Mohans-MacBook-Pro:pt radhakrishnan$ ls
AdoptOpenJDKLogo-100×100.png feedback.md
README.md handy-scripts-for-OpenJDK-developers.md
SUMMARY.md intermediate-steps
adopt-openjdk-getting-started known-issues
adoptopenjdk-projects openjdk-mailing-lists.md
advanced-steps openjdk-projects
binaries preparations.md
contribute.md source-code
contributors.md thanks_and_support.md
cover.jpg virtual-machines
Mohans-MacBook-Pro:pt radhakrishnan$ cd known-issues/
Mohans-MacBook-Pro:known-issues radhakrishnan$ ls
known_issues.md known_issues_sonarqube.md
known_issues_linuxunix.md known_issues_virtual_machine.md
known_issues_macos.md known_issues_windows.md
known_issues_mercurial.md
Mohans-MacBook-Pro:known-issues radhakrishnan$ cat known_issues_macos.md
# MacOS

The configuration fails because it does not find **freetype

configure: error: Could not find freetype!
configure exiting with result code 1

Check if **freetype** is installed

$ brew install freetype
Error: freetype-2.5.3_1 already installed
To install this version, first `brew unlink freetype’

Since it is already installed we configure like this.

$ bash configure –with-freetype-include=/usr/X11/include/freetype2 –with-freetype-lib=/usr/X11/lib
A new configuration has been successfully created in
/Users/radhakrishnan/OpenJDK/jdk9/build/macosx-x86_64-normal-server-release
using configure arguments ‘–with-freetype-include=/usr/X11/include/freetype2 –with-freetype-lib=/usr/X11/lib’.
Mohans-MacBook-Pro:known-issues radhakrishnan$ git commit -m “Resolution for MacOS issue related to freetype” known_issues_macos.md
[master 9173bc0] Resolution for MacOS issue related to freetype
1 file changed, 18 insertions(+)
Mohans-MacBook-Pro:known-issues radhakrishnan$ git push origin master
Counting objects: 10, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 786 bytes | 0 bytes/s, done.
Total 5 (delta 3), reused 0 (delta 0)
To http://github.com/mohanr/adoptopenjdk-getting-started-kit.git
6f1c9e0..9173bc0 master -> master

Build OpenJDK 9

The build was delayed by this error.

configure: error: Could not find freetype!
configure exiting with result code 1

It is already installed !!

localhost:jdk9 radhakrishnan$ brew install freetype

Error: freetype-2.5.3_1 already installed

To install this version, first `brew unlink freetype’

This helped.

Mohans-MacBook-Pro:jdk9 radhakrishnan$ bash configure –with-freetype-include=/usr/X11/include/freetype2 –with-freetype-lib=/usr/X11/lib

A new configuration has been successfully created in

/Users/radhakrishnan/OpenJDK/jdk9/build/macosx-x86_64-normal-server-release

using configure arguments ‘–with-freetype-include=/usr/X11/include/freetype2 –with-freetype-lib=/usr/X11/lib’.

Configuration summary:

* Debug level: release

* HS debug level: product

* JDK variant: normal

* JVM variants: server

* OpenJDK target: OS: macosx, CPU architecture: x86, address length: 64

Tools summary:

* Boot JDK: java version “1.8.0_45” Java(TM) SE Runtime Environment (build 1.8.0_45-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode) (at /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home)

* Toolchain: clang (clang/LLVM)

* C Compiler: Version Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn) Target: x86_64-apple-darwin13.4.0 Thread model: posix (at /usr/bin/clang)

* C++ Compiler: Version Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn) Target: x86_64-apple-darwin13.4.0 Thread model: posix (at /usr/bin/clang++)

—– Build times ——-
Start 2015-04-26 08:23:02
End 2015-04-26 08:45:01
00:05:54 verify-modules
00:21:59 TOTAL
————————-
/bin/bash /Users/radhakrishnan/OpenJDK/jdk9/common/bin/logger.sh /Users/radhakrishnan/OpenJDK/jdk9/build/macosx-x86_64-normal-server-release/build.log /usr/bin/printf “Finished building targets ‘clean images’ in configuration ‘macosx-x86_64-normal-server-release’\n”
Finished building targets ‘clean images’ in configuration ‘macosx-x86_64-normal-server-release’

Deployment on Heroku

 

Screen Shot 2014-12-05 at 12.50.10 PM I recently pushed my AngularJS/Spring Boot/Rest application to Heroku.

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-release" }
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.8.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
mainClassName = "rest.controller.Application"

jar {
    baseName = 'Angular-Boot-Rest'
    version =  '0.1.0'
}

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "http://repo.spring.io/libs-release" }
}



tasks.withType(Copy) {
        eachFile { println it.file }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    testCompile("junit:junit")
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}
task stage(dependsOn: ["build"]){}

I added a new task stage and mainClassName.

It allots a free port on which Tomcat binds. If one specified one’s own port then the application does not bind to it within 60 seconds which is the time limit allowed.

Heroku needs this file too.

Procfile

web: java $JAVA_OPTS -jar target/Angular-Boot-Rest.jar

This is the screenshot. Note the URL which is allotted too.

Screen Shot 2014-12-05 at 1.02.05 PM

Web application stack

resthub
RestHUB

jhipster
JHipster

I really need to keep up with these new stacks.

Python vs Java Streams and lambda

I ported the first facebook Qualification Round Solution to Java 8.

The main idea is to count the frequency of each letter, then assign the value 26 to the most frequent letter, 25 to the next, etc. If two letters are tied for most frequent, it doesn’t matter which of them gets which value, since the sum will be the same. The python code below explains the solution pretty well.

I haven’t thoroughly checked for bugs but this is almost as beautiful as Python. Java is more verbose though.
I haven’t tested it thoroughly though.

import java.util.Map;
import java.util.TreeMap;
import java.util.stream.IntStream;

public class WordCount {
	
	public int x = 26;

	public static void main(String... argv){
		
		WordCount wc = new WordCount();
		wc.count();
	}

	private void count() {

		String s  = "__mainn__".replaceAll("[^a-z\\s]", "");

		System.out.println(s);
		

        final Map<Character, Integer> count = s.chars().
        		map(Character::toLowerCase).
                collect(TreeMap::new, (m, c) -> m.merge((char) c, 1, Integer::sum), Map::putAll);
        
             
        count.entrySet().stream().
        	sorted((l, r) -> r.getValue().compareTo(l.getValue())).
        		forEach(e -> count.merge(e.getKey(), x--, Math::multiplyExact));
                //Stop when x == 0.Not tested
        
        System.out.println(count.entrySet().stream().mapToDouble(e -> e.getValue()).sum());
	//Treating these numbers as double to sum them. Doesn't seem to matter.	
	}
}
mainn
a-1
i-1
m-1
n-2
{a=25, i=24, m=23, n=52}
124.0

Streams

I tried to use lambdas to swap elements in the char[] array. Does this mean that I am trying to change the stream while it is streaming ? This code is from http://www.cs.uofs.edu/~mccloske/courses/cmps144/invariants_lec.html but this question is unrelated to those concepts.

If that is a problem then a new stream will do. How should this be done ? I am not looking for a Comparator. I would like to work with this code as it is without using any API but lambdas.

I am printing using lambdas in this code now.

public class DutchNationalFlag {

    private static final int N = 10;

    private static char[] flags = new char[]{'R','B','B','R','R','B','B','R','R','B'};

    public static void main( String... argv){

        new String(flags).chars().mapToObj(i -> (char)i).forEach(System.out::println);

        int m = 0,  k = 0;
        while (m != N)  {
            if (flags[m] == 'B') { }
            else {
                swap(flags,k,m); 
                k = k+1;
            }
            m = m+1;
        } 
        new String(flags).chars().mapToObj(i -> (char)i).forEach(System.out::println);
    }

    private static void swap(char[] flags, int k, int m) {

        char temp = flags[k];
        flags[k] = flags[m];
        flags[m] =  temp;

    }

}

Possible Solution 1:

This doesn’t do exactly what the original code does. It doesn’t swap and doesn’t advance k which is the boundary between ‘B’ and ‘R’.But it produces the result.

    Stream<Character> stream1 = 
    IntStream.range(0, flags.length).mapToObj(i -> (char)flags[i]);

    Stream<Character> stream2 = 
    IntStream.range(0, flags.length).mapToObj(i -> (char)flags[i]);


    Stream.concat(stream2.filter(x-> (x == 'B')), stream1.filter( y->(y == 'R')  )).forEach(System.out::println);