[Java] Comment résoudre un bogue dans le compilateur JDK

Probablement celui qui a marché

[JDK-8143647] Javac compiles method reference that allows results in an IllegalAccessError

~~ * Comme cela sera décrit plus tard, c'est un événement qui s'est produit dans ** Oracle JDK ** au lieu d'OpenJDK, il est donc honnêtement subtil de savoir s'il s'agit du même bogue. .. .. ~~

Postscript

La base de données de bogues Oracle JDK avait le même problème. https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8143647

Qu'est-il arrivé

Les classes compilées avec ** Oracle JDK 8u92 ** sous Solaris plantent d'une manière ou d'une autre à l'exécution avec ʻIllegalAccessError`.

Une classe compilée avec Eclipse Mars 2 (4.5.2) sur Windows 7 (x64) fonctionne correctement avec la même source. .. ..

Si vous regardez dans le code d'octet avec javap -c, l'endroit où la ** référence de méthode ** est utilisée n'est pas une classe concrète dans le code source, mais sa classe parente, une abstraction invisible ( package private). Il a été remplacé par une classe.

La procédure pour reproduire le problème ci-dessus est la suivante.

1) Create default-scoped abstract class with concrete method
2) Create a concrete public class extending the above class in the same package
3) Use a method reference to this inherited method in a class outside of the package 

D'autre part, la source qui simplifie la classe problématique et la classe à laquelle la méthode est référencée est

simplification


package inner;
abstract class AbstractHoge {
    public String getSomething() {
        ...
    }
}

package inner;
public class Hoge extends AbstractHoge {
}

package outer;
import inner.Hoge;
...
public class Fuga {
    public void doSomething(List<Hoge> list) {
        Map<String, List<Hoge>> map = 
            list.stream().collect(Collectors.groupingBy(Hoge::getSomething));
        ...
    }
}

Avec une telle sensation, les conditions d'activation ont été brillamment satisfaites. .. ..

Solution

Dans le problème ci-dessus, il semble qu'il a été rétroporté autour de 8u102 ou 8u111, alors mettez à jour vers une version plus récente d'Oracle JDK. ⇒ En fait, le problème a été résolu dans la classe compilée avec ** Oracle JDK 8u161 **.

Recommended Posts

[Java] Comment résoudre un bogue dans le compilateur JDK
Installation de Java Open JDK 8 sur CentOS 7
Créer un environnement de développement Java sur Mac
noyau Java: le compilateur HotSpot plante sur SIGSEGV
JDK8 est un gros problème sur MacOS
Déployer des applications Web Java sur Heroku
Jdk d'installation Java
Une histoire sur le JDK à l'ère de Java 11
Créer un environnement d'exécution Java sur Sakura VPS
J'ai essayé d'exécuter Java dans un terminal Mac
Créez un environnement de développement Java à l'aide de jenv sur votre Mac
J'ai essayé d'utiliser Log4j2 sur un serveur Java EE
[Java] Comment exécuter des tâches régulièrement
Procédure d'installation du Java SE Development Kit (JDK) sous Windows
Création d'un environnement Java léger qui s'exécute sur Docker
Questions et réponses sur JDK
Installez Java sur Mac
[Java] Créer un filtre
Exécutez PostgreSQL sur Java
java construire un triangle
Brainfuck-> Compilateur de code d'octet Java
Exécuter R à partir d'un processus Java optimisé par Tomcat sur Amazon Linux
Comment déployer une application kotlin (java) sur AWS Fargate
Fonctionnalité du langage Java et comment elle a produit un bogue subtil
Essayez Hello World en utilisant Java brut sur le conteneur Docker