jClouds + OpenStack:(NoSuchElementException)密钥 [openstack-neutron] 不在提供者或 api 列表中

jClouds + OpenStack: (NoSuchElementException) key [openstack-neutron] not in the list of providers or apis

我正在尝试将 Apache jClouds 集成到一个 Java 项目中,以便我可以访问 OpenStack API。以下代码失败:

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

出现以下错误消息:

Java.util.NoSuchElementException:密钥 [openstack-neutron] 不在提供者或 api 列表中:{providers=[ultradns-ws],apis=[swift,swift-梯形校正]}

这显然是一个常见的问题,但是suggestions offered in jClouds troubleshooting don't resolve it. There's another Whosebug discussion关于这个问题却没有一个公认的答案。

几个有用的要点:

如果有任何想法或建议,我将不胜感激!

这里有一些例子:

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

他们使用 maven,但它们是比较的良好起点 code/dependencies。

此外,也许您可​​以使用类似的方法来管理 jclouds 依赖项作为替代方案? https://maven.apache.org/ant-tasks/

你也可以尝试从maven下载jclouds-neutron,而不是编译它:

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

您在使用 ant 指令时遇到了什么问题?

当您将 provider/api id 作为字符串传递给 ContextBuilder 时,java ServiceLoader 将用于加载 api classes。它将扫描 class 路径中的 META-INF/services 文件夹并查找 ApiMetadataProviderMetadata.

的实现

您能否确认在您的环境中不存在 class 可能阻止 ServiceLoader 正常运行的加载问题?

作为替代方案,您可以绕过 ServiceLoader 查找并直接提供具体的 ApiMetadata 实现。在你的情况下,它会是这样的:

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

如果您的 classpath 中有 openstack-neutron jar,这应该可以。如果是这样,也表明您的项目中有某些东西正在阻止 ServiceLoader 正常运行。它不会影响 jclouds,因为它只在创建上下文时使用它,但它是您可能想要修复的东西。

如果您使用的是 maven,则应添加以下依赖项:

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

然后,从命令行打包:

mvn clean package

并添加依赖项:

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

并执行:

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