2016-09-21 72 views
3

我试图将Apache Jclouds集成到我正在开发的Spring Boot应用程序中,以便我可以将文件上载到Rackspace Cloud文件(英国)。在Spring Boot应用程序中使用Rackspace时,Apache jclouds java.lang.NoSuchMethodError

我创建了一个我正在创建的Bean作为Bean;

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(哪些工作正常)在相同的地方宣布的bean;

@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") 
     ); 
    } 

但是,每次运行应用程序时,bean都无法加载,因为尝试创建bean时发现类未找到错误。

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 

我在我的pom文件中包含了jcloud的1.9.2版本;

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

有人能够告诉我为什么我得到一个类未找到错误吗?我没有在我的POM中包含任何Google依赖项,因此任何可用的依赖项都包含在我的一个依赖项中。

+0

你能分享'mvn dependency:tree'输出 –

回答

3

这是jclouds中的一个已知问题。见JCLOUDS-1160JCLOUDS-1166。在解决这些问题之前,如果您无法强制使用Gson < = 2.5,那么您将无法在Spring Boot中使用jcloud。

另一种选择是使用maven-shade-plugin来遮蔽jclouds的依赖关系并将Gson包装在其中。这样,你应该能够使用你的环境需要的Gson版本,而jclouds使用阴影。

+0

感谢您的评论。我将如何使用maven-shade-plugin来解决这个问题?对不起,我以前没有使用阴影插件。 – SheppardDigital

+1

看看[jclouds Jenkins插件](https://github.com/jenkinsci/jclouds-plugin)。它基本上定义了一个jclouds-shaded模块,它具有jclouds依赖性,并配置maven-shade-plugin来生成一个带有jclouds和冲突依赖项的超级jar。他们为Guava/Guice遮阳,但在你的情况下,你只想遮住Gson。他们还配置了软件包重定位以避免软件包与“外部”依赖关系发生冲突(你也应该使用Gson来完成)。 –

+0

最后,在您的项目中,您只需要依赖刚刚创建的“jclouds-shaded”jar,而不是依赖jclouds。它将包含所需的一切。 –

0

我最初努力使用阴影插件创建ubar jar,并最终得到它的工作。对于任何可能像我一样挣扎的人。

首先,创建一个新的(空的)maven项目。

这是我的POM文件,其中包含apache jclouds Gson的旧版本,并将Gson包更名为在最终jar中使用,因此它与我的主项目中的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> 

在终端上建立项目来创建jar文件。

mvn package 

最后,将jar文件复制到您的主项目的根目录下,在我的情况下是一个spring启动web应用程序。

在项目的根目录中创建一个名为'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这个build文件像这样:

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

和这似乎将GSON版本锁定为2.5,这是与JClouds和SpringBoot兼容的最新版本。有了这个黑客,我可以构建并运行我的应用程序。

相关问题