jClouds + OpenStack: (NoSuchElementException) ключ [openstack-нейтрон] отсутствует в списке провайдеров или API

Я пытаюсь интегрировать 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-нейтрон] отсутствует в списке провайдеров или API: {провайдеры = [ultradns-ws], apis = [swift, swift-keystone]}

Это, по-видимому, распространенная проблема, однако предложения, предлагаемые в разделе устранения неполадок jClouds, не решают ее. . Есть еще одно обсуждение StackOverflow по этой проблеме, но не есть принятый ответ.

Несколько полезных моментов:

  • Наш проект Java использует Ant, тогда как jClouds основан на Maven. Руководство по установке jClouds предоставляет инструкции по установке с помощью Ant, но ни один из них не работает правильно. Вместо этого я скомпилировал jClouds из исходного кода (https://github.com/jclouds/jclouds) и скопировал файлы .jar в папку на моем пути к классам. Теперь я могу получить доступ к объектам jClouds в моем коде.
  • Источник jclouds по умолчанию не включает объекты OpenStack Neutron. В конце концов я нашел их в исходном коде OpenStack Labs (https://github.com/jclouds/jclouds-labs-openstack). Скомпилировано из исходников, скопирован файл openstack-Neutron-1.9.1.jar в папку classpath, теперь я могу получить доступ к объектам Neutron.
  • Все интернет-источники предполагают, что это проблема пути к классам / зависимости. Я проверил, что библиотека openstack-нейтрон-1.9.1.jar доступна как в моих файлах .classpath, так и в build.xml. Нет разрешения.

Буду признателен за любые идеи или предложения!


person markcoatsworth    schedule 10.11.2015    source источник


Ответы (3)


Когда вы передаете идентификатор provider / api в виде строки в ContextBuilder, java ServiceLoader будет использоваться для загрузки классов API. Он просканирует папку META-INF/services в пути к классам и найдет реализации ApiMetadata и ProviderMetadata.

Можете ли вы убедиться, что в вашей среде нет проблем с загрузкой классов, которые могут помешать нормальной работе ServiceLoader?

В качестве альтернативы вы можете обойти поиск ServiceLoader и напрямую предоставить конкретную реализацию ApiMetadata. В вашем случае это будет примерно так:

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

Если в вашем пути к классам есть openstack-нейтронная банка, это должно сработать. И если это так, это также указывает на то, что в вашем проекте есть что-то, что мешает правильной работе ServiceLoader. Это не повлияет на jclouds, поскольку он использует его только при создании контекста, но это то, что вы можете исправить.

person Ignasi Barrera    schedule 10.11.2015
comment
Спасибо! Вызов реализации NeutronApiMetadata() исправил это. У этого проекта даже нет папки META-INF/services в пути к классам, поэтому, вероятно, поэтому он раньше не работал. Ценю вашу помощь! - person markcoatsworth; 11.11.2015
comment
Каждый jclouds api jar предоставляет эту папку с соответствующей реализацией. Ящик openstack-нейтронов имеет свой собственный, и ServiceLoader должен уметь его забрать. - person Ignasi Barrera; 11.11.2015

Вот несколько примеров:

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

Они используют maven, но являются хорошей отправной точкой для сравнения кода / зависимостей.

Кроме того, может быть, вы можете использовать что-то подобное для управления зависимостями jclouds в качестве альтернативы? https://maven.apache.org/ant-tasks/

Вы также можете попробовать загрузить jclouds-нейтрон из maven вместо его компиляции:

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

С какими проблемами вы сталкиваетесь с инструкциями для муравьев?

person zacksh    schedule 10.11.2015

Если вы используете 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
person Maroun    schedule 18.05.2017