Tech

20150218

WHY Caused by: java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy


I have been working on some some J2EE 7 fun projects, and suddenly I run into some problems during deployments on my project with NetBeans 8.0.2 and glassfish 4. As you can see below, the server writes some reflect output stack trace:


Caused by: java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
at java.lang.reflect.Executable.declaredAnnotations(Executable.java:546)
at java.lang.reflect.Executable.getAnnotation(Executable.java:520)
at java.lang.reflect.Method.getAnnotation(Method.java:607)



This ArrayStoreException came wrapped in another exceptions, by reading the stack and taking consideration the moment in which the Exception actually happens we can get some thoughts of what might be going on:


  1. The server does not deploy the application, could be due to missing libs or bad configuration.
  2. The ArrayStoreException with the TypeNotPresentExceptionProxy, tells me that something is missing, but since there is no java.lang.NoClassDefFoundError, it means is not a classpath's path.
  3. The java.lang.reflect.Method.getAnnotation() method, it tells is something to do with annotations.

Its time to look at the Exception wrapper. So it may give some clues where to look for more information:

Severe:   sun.reflect.annotation.TypeNotPresentExceptionProxy
Severe:   Exception while deploying the app [ProjectEulerAnswers]
Severe:   Exception during lifecycle processing
java.lang.IllegalStateException: sun.reflect.annotation.TypeNotPresentExceptionProxy. Related annotation information: annotation [@javax.ejb.Stateless(name=, description=, mappedName=)] on annotated element [class com.euler._25Beans.q11UPBean] of type [TYPE]

The log provided by GlassFish is very clear and confirms all I have learned so far ,and actually prints the name  project ProjectEulerAnswer, the culprit for  failing deployment and provides the name of a bad Bean (q11UPBean). 

On the bean q11UPBean, has the following annotations: 

/**
+ This EJBeuler.jar module is being locally injected from my PorjectEulerAnswers.war Web module
**/
@Stateless
@LocalBean
public class q11UPBean extends prop11Gen{

@javax.interceptor.Interceptors(LoggingInterceptor.class) //this annotation is from a external module EJBintercept.jar**
    private Map<String, String[]> walkingleft(String[] lineArray) {
//some code here
}

//some code here
}

As we can notice, it's the usual Stateless local EJB declaration, which we could call EJBeuler, in which should not give any trouble. Then there is an interceptor's annotation, and in this case this Interceptor is living on a different EJB module, we could call EJBintercept. Checking the Libraries on NetBeans and as expected my my EJBeuler does have reference to my EJBintercept, if there weren't it would give me a compile exception.

But accordingly is the  ProjectEulerAnswers the one failing, which means the Web Project possible needs the library reference to EJBintercept. Which proven to be true and the solution to my ArrayStoreExcpeiton; Which means that at compile time the container is not capable to check all the second hand annotations references, and throws some Exceptions which is very hard to identify the real issue. 

Therefore, when programing with annotation from different modules, we must check if the following example is true: 

EJBeuler ---- uses compiles Libraries ----> EJBintercep; 
ProjectEulerAnswers ---- uses compiles Libraries ----> EJBintercep; 
ProjectEulerAnswers ---- uses compiles Libraries ----> EJBeuler; 





20141127

Java's parametrize Lambda;

Lambda is a new feature on the java se - JDK 8; yeat not implemented on the java EE specs. This now tool provides a lot more flexibility for the java programmers to code reuse, but also can generate unnecessary complexity;

All you really need is an interface with a single method. The annotation @FunctionalInterface (java.lang.annotation.FunctionalInterface - JDK 8), only enforces that the interface must have one and only one abstract method, but you could live without it.  To me, is just to tell others programmers not to declare anything else;

Example:
@FunctionalInterfaceinterface Calculator{    double calculate(int x , int y); }
or
interface Calculator{    double calculate(int x , int y); }
Both Works the same, and a consequence it limits other Object Oriented aspect as method overloading; 

Bad Example: 
interface Calculator{    double calculate(int x , int y);     double calculate(Long x , int y); }
Wrapping also seems not to have problems with Lambda expressions:

package lambda.expression;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

//Lambda primitive type
@java.lang.FunctionalInterface
interface Calculator {
    double calculate(long x, int y);
}

//lambda generic Object
@java.lang.FunctionalInterface
interface ObjectImpl<E> {
    E doOString(E obj1, E obj2);
}

public class Test {
    public static void main(String[] argv) {
        //This is a very simple example; with declaration type and passing the expression;
        Calculator calc = (long x, int y) -> Math.min(x, y);
        System.out.printf("%6.2f\n", calc.calculate(255, 7));
       
        //A little more complex, is the use of collection;
        List<Calculator> listCalc = new ArrayList<>();
        listCalc.add((x, y) -> x + y);
        listCalc.add((x, y) -> x - y);
        listCalc.add((x, y) -> x / y);
        listCalc.add((x, y) -> x % y);
        listCalc.add((x, y) -> Math.hypot(x, y));
        Iterator<Calculator> interate = listCalc.iterator();
        while (interate.hasNext()) {
            Calculator calculator = interate.next();
            System.out.printf("%6.2f\n", calculator.calculate(255, 7));
        }
        //to make your day, Generics is here to add some more complexity;
        ObjectImpl<String> objectImpls = (obj1, obj2) -> obj1 + obj2;
        String result = objectImpls.doOString("Hello ", "World!!");
        System.out.println(result);
        //Adding with Integer Object and wrappers;
        ObjectImpl<Integer> objectImplsNum = (obj1, obj2) -> obj1 + obj2;
        Integer resultint = objectImplsNum.doOString(new Integer(2),3);
        System.out.println(resultint);
       
    }
}

The results: 

run:
  7.00
262.00
248.00
 36.00
  3.00
255.10
Hello World!!
5
BUILD SUCCESSFUL (total time: 2 seconds)

Lambda like break, continue, label and other features, can turn your code more complex; but its here to stay, and we should understand how it works and use it with precaution;