2016-09-21 2 views
3

Я пытаюсь интегрировать Apache Jclouds в приложение Spring Boot, над которым я работаю, чтобы я мог загружать файлы в Rackspace Cloud Files (Великобритания).Apache jclouds java.lang.NoSuchMethodError при использовании Rackspace в приложении Spring Boot

Я создал класс, который я создаю как боб;

import com.google.common.io.ByteSource; 
import com.google.common.io.Files; 
import org.jclouds.ContextBuilder; 
import org.jclouds.io.Payload; 
import org.jclouds.io.Payloads; 
import org.jclouds.openstack.swift.v1.features.ObjectApi; 
import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApi; 
import org.springframework.web.multipart.MultipartFile; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 

/** 
* Class WebStorage 
* 
*/ 
public class WebStorage { 

    private final String region = "lon"; 
    private final String provider = "rackspace-cloudfiles-uk"; 

    private String username; 
    private String apiKey; 
    private String container; 
    private String url; 

    private CloudFilesApi cloudFilesApi; 

    public WebStorage(String username, String apiKey, String container, String url) { 
     this.username = username; 
     this.apiKey = apiKey; 
     this.container = container; 
     this.url = url; 

     cloudFilesApi = ContextBuilder.newBuilder(provider) 
       .credentials(this.username, this.apiKey) 
       .buildApi(CloudFilesApi.class); 
    } 

    /** 
    * Accepts a MultipartFile and returns it as a File 
    * @param multipartFile the MultiPartFile to convert 
    * @return a new File 
    */ 
    public static File createFileFromMultipart(MultipartFile multipartFile) { 
     File file = new File(multipartFile.getOriginalFilename()); 

     try { 
      file.createNewFile(); 
      FileOutputStream fos = new FileOutputStream(file); 
      fos.write(multipartFile.getBytes()); 
      fos.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return file; 
    } 

    /** 
    * Send the file to the CDN and return it's full URL 
    * @param name the path/name of the file on the CDN 
    * @param theFile the file to upload to the CDN 
    * @return the full URL to the uploaded file on the CDN 
    */ 
    public String put(String name, File theFile) { 
     ObjectApi objectApi = cloudFilesApi.getObjectApi(region, this.container); 

     /* Upload the file */ 
     ByteSource byteSource = Files.asByteSource(theFile); 
     Payload filePayload = Payloads.newByteSourcePayload(byteSource); 
     objectApi.put(name, filePayload); 

     return this.url + name; 
    } 

} 

я объявляю фасоль в том же месте, я объявляю все другие бобы (которые работают нормально);

@Bean 
    public WebStorage storage() { 
     return new WebStorage(
       env.getProperty("voila.cdn.username"), 
       env.getProperty("voila.cdn.apikey"), 
       env.getProperty("voila.cdn.container"), 
       env.getProperty("voila.cdn.url") 
     ); 
    } 

Но каждый раз, когда я запустить приложение, фасоль не загружается как класс не найден ошибка возникает при попытке создать компонент.

2016-09-21 12:19:06.847 ERROR 14911 --- [ restartedMain] o.s.boot.SpringApplication    : Application startup failed 

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'storage': Error creating bean with name 'storage' defined in class path resource [com/appapi/config/AppConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.appapi.helpers.WebStorage]: Factory method 'storage' threw exception; nested exception is java.lang.NoSuchMethodError: com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.<init>(Lcom/google/gson/internal/ConstructorConstructor;Lcom/google/gson/FieldNamingStrategy;Lcom/google/gson/internal/Excluder;)V; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'storage' defined in class path resource [com/appapi/config/AppConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.appapi.helpers.WebStorage]: Factory method 'storage' threw exception; nested exception is java.lang.NoSuchMethodError: com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.<init>(Lcom/google/gson/internal/ConstructorConstructor;Lcom/google/gson/FieldNamingStrategy;Lcom/google/gson/internal/Excluder;)V 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:349) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:776) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:313) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] 
    at com.appapi.VoilaApplication.main(VoilaApplication.java:12) [classes/:na] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25] 
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25] 
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.4.0.RELEASE.jar:1.4.0.RELEASE] 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'storage' defined in class path resource [com/appapi/config/AppConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.appapi.helpers.WebStorage]: Factory method 'storage' threw exception; nested exception is java.lang.NoSuchMethodError: com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.<init>(Lcom/google/gson/internal/ConstructorConstructor;Lcom/google/gson/FieldNamingStrategy;Lcom/google/gson/internal/Excluder;)V 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1214) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1019) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:566) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    ... 24 common frames omitted 
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.appapi.helpers.WebStorage]: Factory method 'storage' threw exception; nested exception is java.lang.NoSuchMethodError: com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.<init>(Lcom/google/gson/internal/ConstructorConstructor;Lcom/google/gson/FieldNamingStrategy;Lcom/google/gson/internal/Excluder;)V 
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    ... 37 common frames omitted 
Caused by: java.lang.NoSuchMethodError: com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.<init>(Lcom/google/gson/internal/ConstructorConstructor;Lcom/google/gson/FieldNamingStrategy;Lcom/google/gson/internal/Excluder;)V 
    at org.jclouds.json.internal.DeserializationConstructorAndReflectiveTypeAdapterFactory.<init>(DeserializationConstructorAndReflectiveTypeAdapterFactory.java:116) ~[jclouds-core-1.9.2.jar:1.9.2] 
    at org.jclouds.json.config.GsonModule.provideGson(GsonModule.java:129) ~[jclouds-core-1.9.2.jar:1.9.2] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25] 
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25] 
    at com.google.inject.internal.ProviderMethod.get(ProviderMethod.java:104) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) ~[guice-3.0.jar:na] 
    at com.google.inject.Scopes$1$1.get(Scopes.java:65) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:84) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) ~[guice-3.0.jar:na] 
    at com.google.inject.Scopes$1$1.get(Scopes.java:65) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:54) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:204) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:198) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:198) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:179) ~[guice-3.0.jar:na] 
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:109) ~[guice-3.0.jar:na] 
    at com.google.inject.Guice.createInjector(Guice.java:95) ~[guice-3.0.jar:na] 
    at org.jclouds.ContextBuilder.buildInjector(ContextBuilder.java:402) ~[jclouds-core-1.9.2.jar:1.9.2] 
    at org.jclouds.ContextBuilder.buildInjector(ContextBuilder.java:326) ~[jclouds-core-1.9.2.jar:1.9.2] 
    at org.jclouds.ContextBuilder.buildApi(ContextBuilder.java:644) ~[jclouds-core-1.9.2.jar:1.9.2] 
    at org.jclouds.ContextBuilder.buildApi(ContextBuilder.java:636) ~[jclouds-core-1.9.2.jar:1.9.2] 
    at com.appapi.helpers.WebStorage.<init>(WebStorage.java:49) ~[classes/:na] 
    at com.appapi.config.AppConfiguration.storage(AppConfiguration.java:41) ~[classes/:na] 
    at com.appapi.config.AppConfiguration$$EnhancerBySpringCGLIB$$d004a038.CGLIB$storage$2(<generated>) ~[classes/:na] 
    at com.appapi.config.AppConfiguration$$EnhancerBySpringCGLIB$$d004a038$$FastClassBySpringCGLIB$$59b0bc24.invoke(<generated>) ~[classes/:na] 
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    at com.appapi.config.AppConfiguration$$EnhancerBySpringCGLIB$$d004a038.storage(<generated>) ~[classes/:na] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25] 
    at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25] 
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE] 
    ... 38 common frames omitted 

Я включил версию 1.9.2 jclouds в мой файл pom;

<dependency> 
      <groupId>org.apache.jclouds</groupId> 
      <artifactId>jclouds-all</artifactId> 
      <version>1.9.2</version> 
     </dependency> 

Возможно ли кто-нибудь сообщить мне, почему я получаю класс, не найденный ошибка? Я не включаю какие-либо зависимостей Google в свой POM, поэтому любые доступные из них включены в одну из моих зависимостей.

+0

Можете ли вы поделиться ссылкой «mvn dependency: tree» –

ответ

3

Это известная проблема в jclouds. См. JCLOUDS-1160 и JCLOUDS-1166. Пока эти проблемы не будут исправлены, вы не сможете использовать jclouds с Spring Boot, если вы не можете заставить версию Gson < = 2.5.

Другой вариант - использовать maven-shade-plugin, чтобы затенять зависимости jclouds и расслоение Gson в нем. Таким образом, вы должны иметь возможность использовать версию Gson, необходимую вашей среде, в то время как jclouds использует затененную.

+0

Спасибо за комментарий. Как я могу использовать плагин maven-shade для этого? Извините, я раньше не использовал теневой плагин. – SheppardDigital

+1

Посмотрите на плагин [jclouds Jenkins] (https://github.com/jenkinsci/jclouds-plugin). Он в основном определяет модуль jclouds-shaded, который имеет зависимости jclouds и настраивает maven-shade-plugin для создания uber-jar с jclouds и конфликтующими зависимостями. Они затушевывают Guava/Guice, но в вашем случае вы хотите затенять только Gson. Они также настраивают перенос пакетов, чтобы избежать столкновений пакетов с «внешними» зависимостями (вы также должны делать это с Gson). –

+0

Наконец, в вашем проекте вместо того, чтобы иметь зависимости от jclouds, вам просто нужно зависеть от созданной вами jclouds-shaded jar. Он будет содержать все, что необходимо. –

0

Я изначально боролся за создание ubar jar, используя затененный плагин, и в конечном итоге получил его работу. Для всех, кто, возможно, боролся, как я.

Сначала создайте новый (пустой) проект maven.

Вот мой POM-файл, в который входит apache jclouds более старая версия Gson и переименована в пакет Gson для использования внутри финальной банки, чтобы он не конфликтует с Gson в моем основном проекте (см. Раздел переезды в файле POM).

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>digital.sheppard</groupId> 
    <artifactId>jclouds-shaded</artifactId> 
    <version>1.0-SNAPSHOT</version> 

    <dependencies> 
     <dependency> 
      <groupId>com.google.code.gson</groupId> 
      <artifactId>gson</artifactId> 
      <version>2.4</version> 
     </dependency> 
     <dependency> 
      <groupId>org.apache.jclouds</groupId> 
      <artifactId>jclouds-all</artifactId> 
      <version>1.9.2</version> 
     </dependency> 
    </dependencies> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-shade-plugin</artifactId> 
       <version>2.4.3</version> 
       <executions> 
        <execution> 
         <phase>package</phase> 
         <goals> 
          <goal>shade</goal> 
         </goals> 
         <configuration> 
          <relocations> 
           <relocation> 
            <pattern>com.google.code.gson</pattern> 
            <shadedPattern>com.shaded.code.gson</shadedPattern> 
           </relocation> 
          </relocations> 
          <transformers> 
           <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> 
          </transformers> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 

</project> 

На терминале постройте проект для создания файла флага.

mvn package 

Наконец, скопируйте файл jar в корень вашего основного проекта, в моем случае - веб-приложение весной загрузки.

Создайте папку в корне вашего проекта под названием «maven-local-repo», а на терминале выполните следующую команду, чтобы установить вновь созданный затененный файл jar в локальный репозиторий вашего проекта (очевидно, измените имя файла , артефакт и т. д., чтобы соответствовать затененной банке, которую вы создали).

mvn deploy:deploy-file -DgroupId=digital.sheppard -DartifactId=jclouds-shaded -Dversion=1.0-SNAPSHOT -Durl=file:./local-maven-repo/ -DrepositoryId=local-maven-repo -DupdateReleaseInfo=true -Dfile=jclouds-shaded-1.0-SNAPSHOT.jar 

Добавить местный репозиторий в свой файл POM;

<repositories> 
     <repository> 
      <id>local-maven-repo</id> 
      <url>file:///${project.basedir}/local-maven-repo</url> 
     </repository> 
    </repositories> 

Наконец, добавьте зависимость;

<dependency> 
    <groupId>digital.sheppard</groupId> 
    <artifactId>jclouds-shaded</artifactId> 
    <version>1.0-SNAPSHOT</version> 
</dependency> 

Для меня это работало как шарм.

1

Я переключил свой код Java, чтобы использовать их необработанный HTTP API:

https://support.rackspace.com/how-to/cloud-files-curl-cookbook/

например

public class CloudFilesClient { 

    private final String username; 
    private final String apiKey; 
    private final RestTemplate rest = new RestTemplate(); 

    private static final String AUTH_URL  = "https://auth.api.rackspacecloud.com/v1.1/auth"; 

    private static final String AUTH_DOCUMENT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 
               "<credentials xmlns=\"http://docs.rackspacecloud.com/auth/api/v1.1\" " + 
               "    username=\"%s\" " + 
               "    key=\"%s\" />"; 


    private CloudFilesClient (String aUsername, String aApiKey) { 
    username = aUsername; 
    apiKey = aApiKey; 
    } 

    public List<Map<String,Object>> listObjects (String aRegionName, String aContainerName) { 
    Map<String, Object> auth = auth(); 
    Map<String, Object> cloudFiles = cloudFiles(auth, aRegionName); 
    HttpHeaders headers = new HttpHeaders(); 
    headers.set("X-Auth-Token", token(auth)); 
    HttpEntity<?> e = new HttpEntity<>(headers); 
    ResponseEntity<List> exchange = rest.exchange(((String)cloudFiles.get("publicURL"))+"/"+aContainerName, HttpMethod.GET, e, List.class); 
    return exchange.getBody(); 
    } 

    public Map<String,Object> putObject (String aRegionName, String aContainerName, String aObjectName, String aLocalFilePath) throws IOException { 
    Map<String, Object> auth = auth(); 
    Map<String, Object> cloudFiles = cloudFiles(auth, aRegionName); 
    String token = token(auth); 
    File file = new File(aLocalFilePath); 
    Assert.isTrue(file.exists(),"File not found: " + aLocalFilePath); 
    HttpHeaders headers = new HttpHeaders(); 
    headers.set("X-Auth-Token", token); 
    headers.setContentType(MediaType.valueOf(Files.probeContentType(file.toPath()))); 
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); 
    HttpEntity<Resource> requestEntity = new HttpEntity<>(new FileSystemResource(file), headers); 
    ResponseEntity<Map> result = rest.exchange(((String)cloudFiles.get("publicURL"))+"/"+aContainerName+"/"+aObjectName, HttpMethod.PUT, requestEntity,Map.class); 
    return result.getBody(); 
    } 

    public String getTemporaryUrl (String aRegionName, String aContainerName, String aObjectName) throws URISyntaxException { 
    String key = UUID.randomUUID().toString(); 
    Map<String, Object> auth = auth(); 
    Map<String, Object> cloudFiles = cloudFiles(auth, aRegionName); 
    HttpHeaders headers = new HttpHeaders(); 
    headers.set("X-Auth-Token", token(auth)); 
    headers.set("X-Account-Meta-Temp-Url-Key", key); 
    HttpEntity<?> e = new HttpEntity<>(headers); 
    rest.exchange(((String)cloudFiles.get("publicURL")), HttpMethod.POST, e, List.class); 
    String method = "GET"; 
    long expires = System.currentTimeMillis()/1000+3600; 
    URI endpoint = (new URI((String)cloudFiles.get("publicURL"))); 
    String base = endpoint.getScheme()+"://"+endpoint.getHost(); 
    String path = endpoint.getPath()+"/"+aContainerName+"/"+aObjectName; 
    String hmacBody = String.format("%s\n%s\n%s", method,expires,path); 
    String sig = HmacUtils.hmacSha1Hex(key, hmacBody); 
    return String.format("%s%s?temp_url_sig=%s&temp_url_expires=%s",base, path, sig, expires); 
    } 

    private Map<String,Object> auth() { 
    HttpHeaders headers = new HttpHeaders(); 
    headers.setContentType(MediaType.APPLICATION_XML); 
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); 
    HttpEntity<String> requestEntity = new HttpEntity<>(String.format(AUTH_DOCUMENT,username,apiKey), headers); 
    ResponseEntity<Map> result = rest.exchange(AUTH_URL, HttpMethod.POST, requestEntity, Map.class); 
    Map<String,Object> body = result.getBody(); 
    return (Map<String, Object>) body.get("auth"); 
    } 

    private Map<String, Object> cloudFiles (Map<String,Object> aAuth, String aRegionName) { 
    Map<String, Object> catalog = (Map<String, Object>) aAuth.get("serviceCatalog"); 
    List<Map<String, Object>> cloudFiles = (List<Map<String, Object>>) catalog.get("cloudFiles"); 
    Optional<Map<String, Object>> region = cloudFiles.stream().filter(r->r.get("region").equals(aRegionName)).findFirst(); 
    Assert.isTrue(region.isPresent(),"Unknown region: " + aRegionName); 
    return region.get(); 
    } 

    private String token (Map<String,Object> aAuth) { 
    Map<String, Object> token = (Map<String, Object>) aAuth.get("token"); 
    return (String)token.get("id"); 
    } 

    public static CloudFilesClient build (String aUsername, String aApiKey) { 
    return new CloudFilesClient(aUsername, aApiKey); 
    } 

} 
0

Я знаю почти ничего о Gradle, SpringBoot или JClouds ...

С этими оговорками из пути, я взломал мой Gradle файл сборки, как так:

dependencies { 
... 
    // REQUIRED TO ALLOW JCLOUDS AND GSON TO PLAY NICELY.... XXX 
    compile 'com.google.code.gson:gson:2.5' 
... 
} 

и похоже, это привело к блокировке версии GSON до версии 2.5, которая является самой новой версией, которая работает как с JClouds, так и с SpringBoot. С помощью этого взлома, я могу создать и запустить мое приложение.

Смежные вопросы