2017-09-29 6 views
5

Dans ma classe, je @Configuration dépendances fonctionnelles comme les suivantes:printemps: injection @Resource a cessé de travailler sous JDK9

@Configuration 
public class MyConfig { 
    @Resource(name = "firstDataSource") 
    private DataSource firstDataSource; 

    // more code 
} 

L'injection de dépendance a travaillé dans le JDK Oracle 8: champ firstDataSource a été injecté avec succès avec une valeur non nulle .

Maintenant j'ai essayé de lancer l'application (sans modification) à 9. Le résultat JDK est que @Resource ne déclenche pas plus l'injection de dépendance: tout annotée avec cette annotation reste null.

Quelle pourrait être la raison pour que @Resource cesse de fonctionner?

Le ressort 4.0.9 est utilisé dans le projet.

Voici un projet de test démontrant le problème: https://github.com/rpuch/test-spring-injection-jdk9

Il contient un seul test: MainTest que je dirige de mon IDE. Lorsque j'utilise 8 JDK, il émet

сен 29, 2017 10:45:13 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh 
INFO: Refreshing org.spring[email protected]5f8ed237: startup date [Fri Sep 29 22:45:13 SAMT 2017]; root of context hierarchy 
OK 

Mais sous 9 JDK, il lance une exception lors du démarrage qui est causée par ce qui suit:

Caused by: java.lang.IllegalStateException: bean1 is not injected 
    at Bean2.<init>(Bean2.java:7) 
    at Config2.bean2(Config2.java:16) 

qui se produit lorsque la dépendance n'est pas injecté.

+0

À quel paquet appartient '@ Resource'? Est-ce que [votre code a été compilé avec succès] (https://stackoverflow.com/questions/46352120/incompatible-types-equality-constraints-and-method-not-found-during-java-9-migr)? Existe-t-il une instance reproductible pour tester cela? – nullpointer

+0

C'est 'javax.annotation.Resource'. Oui, tout compile correctement. Je vais essayer de créer un projet de test pour reproduire cela. –

+0

Et comment importez-vous/ajoutez-vous ce paquet dans votre module de projet? – nullpointer

Répondre

5

Le java.xml.ws.annotation étant déprécié dans jdk9 est probablement la cause de ce que vous faites face. Depuis l'annotation @Resource est du paquet javax.annotation exporté par le même module.

Vous pourriez vouloir fournir javatm-common-annotations comme un module de mise à niveau pour java.xml.ws.annotation qui exporte le javax.annotation.

Cette version autonome de Java (TM) utilise Annotations communes une plate-forme Java System Module Nom du module "automatique" de java.annotation, pour correspondre au nom du module utilisé dans JDK 9.

Le recherche sur central suggests, vous pouvez utiliser: -

<dependency> 
    <groupId>javax.annotation</groupId> 
    <artifactId>javax.annotation-api</artifactId> 
    <version>1.3.1</version> 
</dependency> 

Cela fonctionne très bien sur ma machine avec votre code partagé.


De plus, une note sur le code que vous avez partagé. Puisque vous migrez à l'aide JDK9, vous devez migrer d'utiliser la plus récente springframework dépendances released as on 28-9-2017: -

<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-context</artifactId> 
    <version>5.0.0.RELEASE</version> 
</dependency> 

Modifier: Ne jetez un oeil à Roman's answer pour un autre à utiliser au cas où vous --add-modules ne prévoient pas de migrer vers le module explosé javaee pour le moment.

4

Ajout de quelques détails manquants.

Spring @Resource - l'injection forcée ne fonctionne que lorsque javax.annotation.Resource est disponible au moment de l'exécution. Le printemps fait un chèque:

private static final boolean jsr250Present = 
     ClassUtils.isPresent("javax.annotation.Resource", AnnotationConfigUtils.class.getClassLoader()); 

et utilise ensuite cette variable jsr250Present pour voir si @Resource injection à base (et fonctionnalité @PostConstruct/@PreDestroy) doivent être activés.

Dans mon cas, sous 9 JDK, cette classe n'était pas disponible en temps d'exécution, car il appartient à un module séparé java.ws.xml.annotation (séparé du module java.base de base contenant java.lang et d'autres paquets qui est toujours disponible). Pour résoudre le problème, l'une des approches suivantes peuvent être prises:

  1. Ajouter javax.annotation-api bibliothèque à mon classpath d'application, comme @AlanBateman et @nullpointer suggéré.
  2. En variante, java peut être chargé d'ajouter le module à l'aide d'un commutateur de ligne de commande: --add-modules java.xml.ws.annotation. Cela laisse le code intact.