在Spring Boot应用程序中使用Rackspace时,Apache jclouds java.lang.NoSuchMethodError

我正在尝试将Apache Jclouds集成到我正在处理的Spring Boot应用程序中,以便我可以将文件上传到Rackspace Cloud Files(英国)。

我创建了一个我正在创建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 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] osboot.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.(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.(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.(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.(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.(Lcom/google/gson/internal/ConstructorConstructor;Lcom/google/gson/FieldNamingStrategy;Lcom/google/gson/internal/Excluder;)V at org.jclouds.json.internal.DeserializationConstructorAndReflectiveTypeAdapterFactory.(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.(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() ~[classes/:na] at com.appapi.config.AppConfiguration$$EnhancerBySpringCGLIB$$d004a038$$FastClassBySpringCGLIB$$59b0bc24.invoke() ~[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() ~[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文件中包含了1.9.2版本的jclouds;

  org.apache.jclouds jclouds-all 1.9.2  

有人能告诉我为什么我找到一个没有找到课程的错误? 我没有在我的POM中包含任何Google依赖项,因此任何可用的东西都包含在我的某个依赖项中。

这是jclouds中的一个已知问题。 见JCLOUDS-1160和JCLOUDS-1166 。 在修复这些问题之前,如果你不能强制使用Gson <= 2.5的版本,那么你将无法使用Spring Boot的jclouds。

另一个选择是使用maven-shade-plugin来遮蔽jclouds依赖关系并将Gson捆绑在其中。 这样你就可以使用你的环境需要的Gson版本,而jclouds使用阴影版本。

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

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

这是我的POM文件,其中包括apache jclouds旧版本的Gson,并重命名为最终jar中使用的Gson包,因此它与我的主项目中的Gson不冲突(请参阅POM文件的重定位部分)。

   4.0.0 digital.sheppard jclouds-shaded 1.0-SNAPSHOT   com.google.code.gson gson 2.4   org.apache.jclouds jclouds-all 1.9.2      org.apache.maven.plugins maven-shade-plugin 2.4.3   package  shade     com.google.code.gson com.shaded.code.gson             

在终端上,构建项目以创建jar文件。

 mvn package 

最后,将jar文件复制到主项目的根目录中,在我的例子中是一个spring boot web应用程序。

在项目的根目录中创建一个名为“maven-local-repo”的文件夹,并在终端执行以下命令将新创建的着色jar文件安装到项目的本地存储库中(显然将文件名,工件等更改为匹配你创建的阴影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文件中;

   local-maven-repo file:///${project.basedir}/local-maven-repo   

最后添加一个依赖;

  digital.sheppard jclouds-shaded 1.0-SNAPSHOT  

对我来说,就像一个魅力。

我将我的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 = "" + ""; private CloudFilesClient (String aUsername, String aApiKey) { username = aUsername; apiKey = aApiKey; } public List> listObjects (String aRegionName, String aContainerName) { Map auth = auth(); Map cloudFiles = cloudFiles(auth, aRegionName); HttpHeaders headers = new HttpHeaders(); headers.set("X-Auth-Token", token(auth)); HttpEntity e = new HttpEntity<>(headers); ResponseEntity exchange = rest.exchange(((String)cloudFiles.get("publicURL"))+"/"+aContainerName, HttpMethod.GET, e, List.class); return exchange.getBody(); } public Map putObject (String aRegionName, String aContainerName, String aObjectName, String aLocalFilePath) throws IOException { Map auth = auth(); Map 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 requestEntity = new HttpEntity<>(new FileSystemResource(file), headers); ResponseEntity 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 auth = auth(); Map 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 auth () { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_XML); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); HttpEntity requestEntity = new HttpEntity<>(String.format(AUTH_DOCUMENT,username,apiKey), headers); ResponseEntity result = rest.exchange(AUTH_URL, HttpMethod.POST, requestEntity, Map.class); Map body = result.getBody(); return (Map) body.get("auth"); } private Map cloudFiles (Map aAuth, String aRegionName) { Map catalog = (Map) aAuth.get("serviceCatalog"); List> cloudFiles = (List>) catalog.get("cloudFiles"); Optional> 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 aAuth) { Map token = (Map) aAuth.get("token"); return (String)token.get("id"); } public static CloudFilesClient build (String aUsername, String aApiKey) { return new CloudFilesClient(aUsername, aApiKey); } } 

我几乎不知道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的效果,这是适用于JCloud和SpringBoot的最新版本。 有了这个hack,我可以构建并运行我的应用程序。