IntersectionType

I came across this code that uses a cast to assign a Lambda expression to a marker interface in Angelika Langer’s explanation.

Serializable f2
= (BiPredicate<String,String> & Serializable)
(s,t) -> s.equalsIgnoreCase(t);

As I was curious about this I tried to detect an intersection type (T extends String & @IntersectionType.TypeUse(value = 2) Serializable) and print the annotation applied on one of its bounds.

The result is

Annotation [] [com.test.IntersectionType.Test]
Annotation [[]] [java.lang.String]
Annotation [[]] [java.io.Serializable]

This could be a JDK 8 bug at this time. I am getting nothing.

I am using

java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b123)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b65, mixed mode)

I presumed there is a javax.lang.model.type.IntersectionType that will match T extends String & Serializable. So I though there is a TypeMirror that I can check for that type. But it does not seem so.

I will update later when I get a proper result.

Update : The method is updated and it works partly. I am getting the intersection type. But I think one cannot get the annotation type of the intersection type directly because the annotation is applied on each of the bounds separately. So the old code(see the comments below) is sufficient but now the returned array is empty which could mean that this is a bug in itself.


Annotation [] [com.test.IntersectionType.Test]
Annotation [[]] [java.lang.String&java.io.Serializable]
Annotation [[]] [java.lang.String]
Annotation [[]] [java.io.Serializable]


public class IntersectionType {

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_USE)
    public @interface TypeUses {
        TypeUse[] value();
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_USE)
    @Repeatable(TypeUses.class)
    protected @interface  TypeUse {
        int value();
    }

    //Intersection type
    class Test<T extends String & @IntersectionType.TypeUse(value = 2) Serializable>{

    }
}

Processor method


    private void processClassTypeParameters(Element e) {


        for (TypeParameterElement typeParameterElement : ((TypeElement) e).getTypeParameters()) {

            for( AnnotationMirror am  : typeParameterElement.getAnnotationMirrors() ){

                System.out.println( "Annotation [" + am + "] [" + typeParameterElement  + "]");


            }
            //Get the intersection type
            TypeVariable tv = (TypeVariable)typeParameterElement.asType();

            TypeMirror tm = tv.getUpperBound();
            //This may not return anything.(See explanation above)
            System.out.println( "Annotation [" + Arrays.asList( tm.getAnnotationsByType(com.test.IntersectionType.TypeUse.class)) + "] [" + tm  + "]");

            for (TypeMirror typeMirror : typeParameterElement.getBounds()) {
                //Commented section is not the right way
                //if( typeMirror instanceof javax.lang.model.type.IntersectionType) {

                //The following line returns an empty array most probably due to a different bug.
                    System.out.println( "Annotation [" + Arrays.asList(typeMirror.getAnnotationsByType(com.test.IntersectionType.TypeUse.class)) + "] [" + typeMirror  + "]");

                //}
            }
        }
    }

Garbage collection book

download

I have started reading this but there is no plan to complete it at this time. I will try.

I will try to write about key research topics in the book if I understand it well. I know that is hard for a run-of-the-mill software developer like me.

In fact I started reading the earlier version more than 5 years back but never completed it.

Porting Python BoxPlot code to “R”

My previous two entries explained how I am attempting to port the Python code used to create the graph in the DZone article to “R”.

The author of that article published the data that he used to generate the graph. The data consists of several files. I have taken one file and tried to create boxplots from it. I will improve this by combining all the files, parsing them and generating a combined boxplot. But first I coded this “R” script to parse one file and generate a boxplot.

The data from one of the files looks like this.


timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,Latency
1346999466187,32,Home page - anon,200,OK,Anonymous Browsing 1-2,text,true,31
1346999466182,37,Login form,200,OK,Node save 3-1,text,true,36
1346999466184,35,Home page - anon,200,OK,Anonymous Browsing 1-11,text,true,32
1346999466182,37,Home page - anon,200,OK,Anonymous Browsing 1-1,text,true,34
1346999466189,30,Home page - anon,200,OK,Anonymous Browsing 1-4,text,true,27
1346999466185,46,Home page - anon,200,OK,Anonymous Browsing 1-5,text,true,34
1346999466185,44,Search,200,OK,Search 4-1,text,true,35
1346999466188,28,Home page - anon,200,OK,Anonymous Browsing 1-3,text,true,26
1346999466182,33,Home page - anon,200,OK,Anonymous Browsing 1-7,text,true,32
1346999466182,36,Login Form,200,OK,Perform Login/View Account 5-1,text,true,35
1346999466182,35,Home page - anon,200,OK,Anonymous Browsing 1-10,text,true,33
1346999466182,34,Login Form,200,OK,Authenticated Browsing 2-1,text,true,32
1346999466184,33,Home page - anon,200,OK,Anonymous Browsing 1-6,text,true,31
1346999466182,37,Home page - anon,200,OK,Anonymous Browsing 1-9,text,true,35

It is very easy to parse this and create a “R” data frame.


# TODO: Box Plots
# 
# Author: radhakrishnan
###############################################################################


library(plyr)

options("scipen"=100, "digits"=4)

data <- read.table("~/Documents/Learn R Statistics/R/jmeter_results/4-overall-summary.csv",sep=",",header=T)

head(data)

#I don't think I need 'ddply' here but it serves the purpose.
#It groups the data based on the 'label' and returns the two relevant columns
data <- ddply( data , .variables = "label" , .fun = function(x) x[,c("label","elapsed")])

uniquelables <- as.character(unique(data$label))
lists <- replicate( length(uniquelables),list())

j = 1


for (i in uniquelables ){
  lists[j] = as.list(as.data.frame(data[data$label %in% i,'elapsed']))
  j = j + 1
}

boxplot(lists)

BoxPlot from one file

boxplot

Eclipse StatET-R environment

My Eclipse R environment is ready.

Screen Shot 2014-01-08 at 1.05.46 PM

matplotlib

logo2

I wanted to generate the boxplot graphs in this DZone article using ‘R’. I think this is one of the best graphs I have seen. It shows data in a really useful manner that could help our Capacity Planners. I am quite proficient with basic ‘R’ data analysis and plots.

So I started to look at matplotlib,a powerful Python plotting library. So as a first step I coded this Python program using matplotlib.

  1. I am using PyDev plugin for eclipse.
  2. I am also using Enthought Canopy as by Python interpreter. This package has all the libraries I need.

    I strugged for some time to configure the Python packages so that Pydev can use them properly instead of the default Python in my Mac machine.

    All is well in the end. I have coded Python in the past but my skills are rudimentary but still this code was simple. It has many similarities to ‘R’.

    '''
    Sample
    '''
    import numpy as np
    import matplotlib
    import matplotlib.pyplot as plt
    
    x = []
    y = []
    
    data = [[ 6.2, 18, 0.3444444  ],
            [ 1.0,  11, 0.3636364 ],
            [ 2.0,  11, 0.3636364 ],
            [ 3.3,  9, 0.3666667  ],
            [ 4.2,  12, 0.3500000 ],
            [ 3.2,  12, 0.3500000 ],
            [ 5.2,  12, 0.3500000 ],
            [ 6.3,  12, 0.3500000 ],
            [ 7.2,  12, 0.3500000]]
    
    for list in data:
        for number in list[:1]:
            x.append(number)        
    
    for list in data:
        for number in list[2:3]:
            y.append(number)        
             
    x.sort()
    
    print(x)
    print(y)
    
    plt.xlim( (0, 8) )
    
    plt.plot(x,y)
    
    plt.show()
    

    figure_1

Repeatable Annotations

It looks like the annotations can repeat according to Repeating Annotations.

I am still using

java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b113)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b55, mixed mode)

This code has a problem.

  1. Arrays.asList(typeMirror.getAnnotationsByType(RepeatableAnnotation.TypeUse.class))

    This does not print anything. There are two annotations.

This could be a problem with the particular JDK 8 build. The latest is b120. I have to try the latest build.

Update: This is most likely a code problem because even b120 does not help.

Update 1: This is not a code problem but b120 has some bugs according to the type-annotations-dev list.

The result is this.


Annotation [@com.test.RepeatableAnnotation.TypeUses({@com.test.RepeatableAnnotation.TypeUse(0), @com.test.RepeatableAnnotation.TypeUse(1)})] [com.test.RepeatableAnnotation.Test1]
[value()][{@com.test.RepeatableAnnotation.TypeUse(0), @com.test.RepeatableAnnotation.TypeUse(1)}]
Annotation [[]] [java.lang.Integer]

I am not able to get the annotations applied on the bound Integer

package com.test;

import java.lang.annotation.*;

public class RepeatableAnnotation {

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_USE)
    public @interface TypeUses {
        TypeUse[] value();
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_USE)
    @Repeatable(value = TypeUses.class)
    protected @interface  TypeUse {
        int value();
    }

    @TypeUse(value = 0) @TypeUse(value = 1)class Test1< T extends @TypeUse(value = 2) @TypeUse(value = 3) Integer> {

        /**
         * A type annotation is permitted in front of a constructor declaration, where declaration annotations are already
         permitted.
         */
        @TypeUse(value = 0) <S> Test1(String s){

        }
    }

}

Annotation Processor


package com.test;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.SimpleTypeVisitor8;
import java.util.*;

import static javax.lang.model.util.ElementFilter.typesIn;

@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class RepeatableAnnotationFinder extends AbstractProcessor{


    public RepeatableAnnotationFinder(){
        super();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {

        TypeElement tye = null;

        if( !roundEnv.processingOver()){

            Iterator<? extends Element> te = annotations.iterator();

            for (TypeElement element : typesIn(roundEnv.getRootElements()) ) {

                processEnclosedElements(element.getEnclosedElements(),
                                        roundEnv);

            }
        }
        return false;
    }

    private void processEnclosedElements(List<? extends Element> enclosedElements,
                                         RoundEnvironment roundEnv) {

        for( Element e : enclosedElements ){

            if (e.getKind() == ElementKind.CLASS){

                System.out.println( "Annotation [" + e.getAnnotationMirrors() + "] [" + e  + "]");

                processClassTypeParameters(e);
            }
        }
    }

    private void processClassTypeParameters(Element e) {

        for (TypeParameterElement typeParameterElement : ((TypeElement) e).getTypeParameters()) {

            for( AnnotationMirror am  : typeParameterElement.getAnnotationMirrors() ){

                System.out.println( "Annotation [" + am + "] [" + typeParameterElement  + "]");

                for(Map.Entry< ? extends ExecutableElement, ? extends AnnotationValue> m : am.getElementValues().entrySet()){

                    System.out.println( "[" + m.getKey() +"][" + m.getValue() + "]");

                }

            }

            for (TypeMirror typeMirror : typeParameterElement.getBounds()) {

                System.out.println( "Annotation [" + Arrays.asList(typeMirror.getAnnotationsByType(RepeatableAnnotation.TypeUse.class)) + "] [" + typeMirror  + "]");

            }
        }
    }
}

So I will wait for a newer build before trying this again.

Annotation Processors

Lambdas are very popular now. But I realized I haven’t used the annotation processor API since JSE 5. None of the projects I came across has even used good generics. So even JSE 5 is not properly used.

I just compiled and executed this. It is not complete because I am trying to print all the annotations actually used in the code shown(Test.java) in my previous blog entry.

I am using

java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b113)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b55, mixed mode)

Now it is printing this.

Annotation [com.test.Test.TypeUse] [[com.test.Test.Test1]]
Annotation [com.test.Test.TypeParameter] [[T, S]]
Annotation [com.test.Test.TestTypeParameter] [[T, S]]
Annotation [@com.test.Test.TypeUse] [com.test.Test.Test1]
Annotation [] [java.lang.Integer]
Annotation [@com.test.Test.NonNull] [argv]

I will update the code later once I manage to fix it.

Update : Now it is printing this. Code is updated. I will explain the changes.

Annotation [com.test.Test.TypeParameter] [[T, S]]
Annotation [com.test.Test.TestTypeParameter] [[T, S]]
Annotation [@com.test.TypeUse] [com.test.Test.Test1]
Annotation [[Lcom.test.TypeUse;@2a5ca609] [java.lang.Integer]
Annotation [@com.test.Test.NonNull] [argv]
-> (java.lang.String[])void

Change 1

This method which I used earlier turns the TypeMirror back to a DeclaredType. That is not required.

    private void processClassTypeParameters(Element e) {
        for (TypeParameterElement typeParameterElement : ((TypeElement) e).getTypeParameters()) {
            //System.out.println( &quot;Annotation [&quot; + typeParameterElement.getAnnotationMirrors() + &quot;] [&quot; + typeParameterElement  + &quot;]&quot;);
            for (TypeMirror typeMirror : typeParameterElement.getBounds()) {
                System.out.println( &quot;Annotation [&quot; + ((DeclaredType)typeMirror).getAnnotationMirrors() + &quot;] [&quot; + typeMirror  + &quot;]&quot;);
            }
        }
    }

This method is replaced with the new method in Test.java shown below. typeMirror.getAnnotationsByType(TypeUse.class) is sufficient to get the annotation on Integer

Change 2

I introduced a new method to get the annotations inside a method and source on which they are applied. But that is not possible. Alex Buckley, the JSR 308 spec. lead replied that

There is no access to annotations in a method body from the Language Model API (or the Core Reflection API).

Actually I introduced this method and called it like this e.asType().accept(visitor(),null); to try to get the annotations from inside the method. This is the method that is printing

    -> (java.lang.String[])void

    private TypeVisitor<Boolean, Void> visitor() {
        return new SimpleTypeVisitor<Boolean, Void>() {
            public Boolean visitExecutable(ExecutableType t, Void v) {
                System.out.println("-> " + t);
                return true;
            }
        };
    }


AnnotationFinder.java

package com.test;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleTypeVisitor6;
import javax.lang.model.util.SimpleTypeVisitor8;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import static javax.lang.model.util.ElementFilter.typesIn;

@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class AnnotationFinder extends AbstractProcessor{


    public AnnotationFinder(){
        super();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {

        TypeElement tye = null;

        if( !roundEnv.processingOver()){

            Iterator<? extends Element> te = annotations.iterator();

            for (TypeElement element : typesIn(roundEnv.getRootElements()) ) {

                processEnclosedElements(element.getEnclosedElements(),
                                        roundEnv);

            }
        }
        return false;
    }

    private void processEnclosedElements(List<? extends Element> enclosedElements,
                                         RoundEnvironment roundEnv) {

        for( Element e : enclosedElements ){

            if( e.getKind() == ElementKind.ANNOTATION_TYPE &&

                    !roundEnv.getElementsAnnotatedWith((TypeElement) e).isEmpty()){

                System.out.println( "Annotation [" + e + "] [" +
                        roundEnv.getElementsAnnotatedWith((TypeElement) e) + "]");

            }else if( e.getKind() == ElementKind.METHOD ){

                for (VariableElement variableElement : ((ExecutableElement) e).getParameters()) {

                    System.out.println("Annotation [" + variableElement.getAnnotationMirrors() + "] [" +

                                                                                         variableElement + "]");
                    e.asType().accept(visitor(),null);

                }

            }else if (e.getKind() == ElementKind.CLASS){

                System.out.println( "Annotation [" + e.getAnnotationMirrors() + "] [" + e  + "]");

                processClassTypeParameters(e);
            }
        }
    }

    private TypeVisitor<Boolean, Void> visitor() {

        return new SimpleTypeVisitor8<Boolean, Void>() {

            public Boolean visitExecutable(ExecutableType t, Void v) {

                System.out.println("-> " + t);

                return true;
            }
        };
    }

    private void processClassTypeParameters(Element e) {

        for (TypeParameterElement typeParameterElement : ((TypeElement) e).getTypeParameters()) {

            //System.out.println( "Annotation [" + typeParameterElement.getAnnotationMirrors() + "] [" + typeParameterElement  + "]");

            for (TypeMirror typeMirror : typeParameterElement.getBounds()) {

                System.out.println( "Annotation [" + typeMirror.getAnnotationsByType(Test.TypeUse.class) + "] [" + typeMirror  + "]");

            }
        }
    }
}

JSR 308

The annotation system has been extended. I realized that there are more annotation types and more source locations where they are permitted.

I compiled a simple example. The specification is here

java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b113)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b55, mixed mode)


package com.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


public class Test {

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_USE)
    @interface  TypeUse {}

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_PARAMETER)
    @interface  TypeParameter {}

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_PARAMETER)
    @interface  TestTypeParameter {}

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.PARAMETER)
    @interface NonNull {}


    /**
             * ElementType.TYPE PARAMETER stands for a type parameter — that is, the declaration of a type variable. Examples
             are in generic class declarations class MyClass<T> {...}, generic method declarations <T> foo(...) {...}, and
             wildcards List<?>, which declare an anonymous type variable.
             * @param <T>
             */
    @TypeUse class Test1<@TypeParameter @TestTypeParameter T extends @TypeUse Integer> {

        /**
         * A type annotation is permitted in front of a constructor declaration, where declaration annotations are already
         permitted.
         */
        @TypeUse <@TypeParameter @TestTypeParameter S> Test1(String s){

        }
    }


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

        Object o = ( @TypeUse String ) new String( "Test" );

        if( o instanceof @TypeUse String ){

        }
        try{

        }catch( @NonNull Exception e){

        }

    }
}
        List list1 = list.
                       stream().
                        map(p::matcher).
                          filter(Matcher::find).map(matcher -> matcher.group()).
                              collect(Collectors.toCollection(@ NonNull ArrayList::new));

Area between curves

This is what I like about ‘R’. This one line is enough to apply a shade of color
to the area between two curves. Apart from the functional programming aspects(
http://adv-r.had.co.nz/), I am interested in its powerful API’s used to visualize and parse data.

polygon( c(data$Time, rev(data$Time)),
         c(as.numeric(data$Used), rev(as.numeric(data$Committed))),
         col = "antiquewhite1",
		 border = NA )

code-cache

Error bars using ‘R’

I believe our measurements are uncertain and we need to show the errors in our capacity measurement plots. I suspect that we are making fundamental mistakes in our attempts to gather performance statistics and drawing graphs. All the more reason for showing these uncertainties. Our management and clients should not be mislead by the lack of skills of our Capacity planners.

This code and the graph are used to learn one aspect of showing such errors. I am yet to investigate the type of errors and their statistical significance.

If there is a mistake I will make corrections to this blog entry.

Updated : Code and graph.

 this.dir <- dirname(parent.frame(2)$ofile) 
setwd(this.dir)
 #Reference values plotted on x-axis. These are constant.
 #These values could be time of day. So every day at the same
 #time we could collect other measurements
 referenceset <- data.frame(c(5,10,15,20,25,30,35,40,50,60))
 colnames( referenceset) <- c("reference")

 #These are the sets of measurements. So every day at the same
 #time we could collect several samples. This is simulated now.
 sampleset <- data.frame( matrix(sample(1:2, c(20000), replace = TRUE), ncol = 2000) )
 
 sampleset <- cbind( sampleset, referenceset )
 
 #Calculate mean
 sampleset$mean <- apply(sampleset[,1:10],2,mean)
 
 #Calculate Standard Deviation
 sampleset$sd <- apply(sampleset[,c(1:10)],2,sd)
 
 #Calculate Standard Error
 sampleset$se <- sampleset$sd / sqrt(10)
 
 #print(sampleset)

	png(
	"errorbars.png",
	width =500, height = 510)
 
 plot( sampleset$reference,
       sampleset$mean,
	   las=1,
	   ylab="Mean of 'y' values",
	   xlab="x",
      ylim=c(0,3),
	  type="l",
	  lwd=1,
	   col="blue"
      );
	  
arrows(sampleset$reference,
       sampleset$mean-sampleset$se,
	   sampleset$reference,
	   sampleset$mean+sampleset$se,
	   code = 3,
	   angle=90,
	   length=0.2)

dev.off()


errorbars