2015-11-10 2 views
1

J'essaie d'intégrer Apache jClouds dans un projet Java pour pouvoir accéder à l'API OpenStack. Le code suivant échoue:jClouds + OpenStack: (NoSuchElementException) key [openstack-neutron] ne figure pas dans la liste des fournisseurs ou des API

neutronApi = ContextBuilder.newBuilder("openstack-neutron") 
        .credentials(USERNAME, API_KEY) 
        .endpoint(AUTH_URL) 
        .modules(modules) 
        .buildApi(NeutronApi.class); 

Avec le message d'erreur suivant:

java.util.NoSuchElementException: touche [OpenStack-neutrons] pas dans la liste des fournisseurs ou apis: {fournisseurs = [ultradns- ws], apis = [swift, swift-keystone]}

Ceci est apparemment un problème courant, mais le suggestions offered in jClouds troubleshooting ne le résout pas. Il y a another StackOverflow discussion à propos de ce problème mais n'a pas de réponse acceptée.

Quelques points utiles:

  • Notre projet Java utilise Ant, alors que jclouds est basé sur Maven. Le Guide d'installation de jClouds provides directions to install using Ant, mais aucun d'entre eux ne fonctionne correctement. Au lieu de cela, j'ai compilé jClouds à partir de la source (https://github.com/jclouds/jclouds) et copié les fichiers .jar dans un dossier sur mon classpath. Maintenant, je peux accéder aux objets jClouds dans mon code.
  • La source jclouds par défaut n'inclut pas les objets OpenStack Neutron. J'ai finalement trouvé ceux-ci dans la source OpenStack Labs (https://github.com/jclouds/jclouds-labs-openstack). Compilé à partir de la source, copié le fichier openstack-neutron-1.9.1.jar dans le dossier classpath, maintenant je peux accéder aux objets Neutron.
  • Toutes les sources en ligne suggèrent qu'il s'agit d'un problème de chemin de classe/dépendance. J'ai vérifié que la bibliothèque openstack-neutron-1.9.1.jar est disponible dans mes fichiers .classpath et build.xml. Pas de résolution

J'apprécierais des idées ou des suggestions!

Répondre

2

Lorsque vous transmettez un identificateur de fournisseur/API en tant que chaîne au ContextBuilder, le java ServiceLoader sera utilisé pour charger les classes d'API. Il va scanner le dossier META-INF/services dans le classpath et rechercher les implémentations de ApiMetadata et ProviderMetadata.

Pouvez-vous vérifier que dans votre environnement, il n'y a aucun problème de chargement de classe qui pourrait empêcher le ServiceLoader de fonctionner normalement?En alternative, vous pouvez contourner la recherche ServiceLoader et fournir directement l'implémentation concrète d'ApiMetadata. Dans votre cas, il serait quelque chose comme:

NeutronApi neutron = ContextBuilder.newBuilder(new NeutronApiMetadata()) 
    .credentials(USERNAME, API_KEY) 
    .endpoint(AUTH_URL) 
    .modules(modules) 
    .buildApi(NeutronApi.class); 

Si vous avez le pot-OpenStack neutrons dans votre classpath cela devrait fonctionner. Et si c'est le cas, cela indique également qu'il y a quelque chose dans votre projet qui empêche le ServiceLoader de fonctionner correctement. Cela n'affectera pas jclouds, car il ne l'utilise que lors de la création du contexte, mais c'est quelque chose que vous voudrez peut-être corriger.

+0

Merci beaucoup! L'appel de l'implémentation 'NeutronApiMetadata()' l'a corrigé. Ce projet n'a même pas de dossier 'META-INF/services' dans le classpath, ce qui explique probablement pourquoi il ne fonctionnait pas auparavant. Apprécier ton aide! – markcoatsworth

+0

Chaque fichier jigouds api jar fournit ce dossier avec l'implémentation correspondante. Le pot openstack-neutron a le sien et le ServiceLoader devrait être capable de le prendre. –

0

Il y a quelques exemples ici:

https://github.com/jclouds/jclouds-examples/blob/master/rackspace/src/main/java/org/jclouds/examples/rackspace/cloudnetworks/CreateNetwork.java

Ils utilisent Maven, mais ils sont un bon point de départ pour comparer le code/dépendances.

Aussi, peut-être que vous pouvez utiliser quelque chose comme ça pour gérer les dépendances de jclouds comme alternative? https://maven.apache.org/ant-tasks/

Vous pouvez également télécharger jclouds-neutrons de Maven, au lieu de le compiler:

https://search.maven.org/#artifactdetails%7Corg.apache.jclouds.labs%7Copenstack-neutron%7C1.9.1%7Cbundle

Quels sont les problèmes que vous frappez avec les instructions de fourmis?

0

Si vous utilisez Maven, vous devez ajouter la dépendance suivante:

<dependency> 
    <groupId>org.apache.jclouds.provider</groupId> 
    <artifactId>aws-ec2</artifactId> 
    <version>${jclouds.version}</version> 
</dependency> 

puis, package à partir de la ligne de commande:

mvn clean package 

et ajoutez les dépendances:

mvn dependency:copy-dependencies -DoutputDirectory="./lib" 

et d'exécuter:

java -cp "target/jar-with-dependencies.jar:lib/*" YourClass