Why do I get this problem at runtime with the jre websphere instead with a normal jre 1.7 working properly?

Liviu :

I am working with JPA and I have a table that repeats on n scheme. The query is written with jpql and I need to specify a different scheme based on the need to avoid creating duplicate code. More precisely I want to change the value of nameOfSchema of the annotation @Table (name = "nameofTable", schema = "nameofSchema") at runtime and then execute the query. In this regard I wrote the following method. While running with a normal JRE 1.7 it works correctly but when I run the method with websphere JRE 1.7 I get a runtime error.

`public void changeTableSchema(final String schema,Class<?> entityWithTable) throws Exception {
    try {
        final String ANNOTATIONS = "annotations";
        Table anntotationToChange = entityWithTable.getAnnotation(Table.class);
        final Table anntotationToChangeCopy = anntotationToChange;
        anntotationToChange = new Table() {
            @Override
            public Class<? extends Annotation> annotationType() {
                return anntotationToChangeCopy.annotationType();
            }

            @Override
            public UniqueConstraint[] uniqueConstraints() {
                return anntotationToChangeCopy.uniqueConstraints();
            }

            @Override
            public String schema() {
                return schema;
            }

            @Override
            public String name() {
                return anntotationToChangeCopy.name();
            }

            @Override
            public String catalog() {
                return anntotationToChangeCopy.catalog();
            }
        };
        Field annotations = Class.class.getDeclaredField(ANNOTATIONS);
        annotations.setAccessible(true);
        Map<Class<? extends Annotation>, Annotation> map = (Map<Class<? extends Annotation>, Annotation>) annotations
                .get(entityWithTable.class);
        map.put(Table.class, anntotationToChange);
    } catch (Exception e) {
        e.printStackTrace();
    }
} `

The error is:
java.lang.NoSuchFieldException: annotations at java.lang.Class.getDeclaredFieldImpl(Native Method) at java.lang.Class.getDeclaredField(Class.java:720) at it.solarisistemi.awondo.be.web.Prova.changeTableSchema(Prova.java:106) at it.solarisistemi.awondo.be.web.Prova.main(Prova.java:23)

Andy Guibert :

The reason for this error is because you are hacking into a non-visible field in the implementation of java.lang.Class, and the implementations of Java classes may differ based on different JDK distributions (e.g. Oracle vs. IBM JDK vs. OpenJDK).

More importantly, these internal fields may be changed or disappear between JDK versions of the same vendor (e.g. IBM JDK 7 to IBM JDK 8) without notice, since they were never intended to be publicly accessible.

I would recommend one of the following solutions instead of hacking into annotation values:

  1. set up a table alias on the DB side
  2. re-compile the necessary application classes with new values for @Table.name()

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=151235&siteId=1