简体   繁体   English

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

[英]Apache jclouds java.lang.NoSuchMethodError when using Rackspace in a Spring Boot application

I'm trying to integrate Apache Jclouds into a Spring Boot application I'm working on so that I can upload files to Rackspace Cloud Files(UK).我正在尝试将 Apache Jclouds 集成到我正在处理的 Spring Boot 应用程序中,以便我可以将文件上传到 Rackspace Cloud Files(UK)。

I've created a class which I'm creating as a Bean;我创建了一个 class 作为 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;
    }

}

I'm declaring the bean in the same place I'm declaring all other beans (which work fine);我在声明所有其他 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")
        );
    }

But each time I run the application, the bean fails to load as a class not found error is generated when trying to create the bean.但是每次我运行应用程序时,bean 都无法加载,因为在尝试创建 bean 时会生成 class not found 错误。

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

I've included version 1.9.2 of jclouds in my pom file;我在我的 pom 文件中包含了 1.9.2 版的 jclouds;

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

Is someone able to tell my why I'm getting a class not found error?有人能告诉我为什么我收到 class not found 错误吗? I'm not including any Google dependencies in my POM, so any that are available are being included by one of my dependencies.我没有在我的 POM 中包含任何 Google 依赖项,因此任何可用的都包含在我的一个依赖项中。

This is a known issue in jclouds. 这是jclouds中的一个已知问题。 See JCLOUDS-1160 and JCLOUDS-1166 . JCLOUDS-1160JCLOUDS-1166 Until those issues are fixed you won't be able to use jclouds with Spring Boot if you can't force a version of Gson <= 2.5. 在修复这些问题之前,如果你不能强制使用Gson <= 2.5的版本,那么你将无法使用Spring Boot的jclouds。

Another option is to use the maven-shade-plugin to shade the jclouds dependencies and bundle Gson in it. 另一个选择是使用maven-shade-plugin来遮蔽jclouds依赖关系并将Gson捆绑在其中。 This way you should be able to use the Gson version your environment needs, while jclouds uses the shaded one. 这样你就可以使用你的环境需要的Gson版本,而jclouds使用着色版本。

I initially struggled creating the ubar jar using the shaded plugin, and eventually got it working. 我最初使用着色插件努力创建ubar jar,最终让它运行起来。 For anyone else who may have struggled like me. 对于任何可能像我一样挣扎的人。

First, create a new (empty) maven project. 首先,创建一个新的(空)maven项目。

Here's my POM file which included apache jclouds an older version of Gson, and renamed the Gson package for use inside the final jar so it doesn't conflict with Gson in my main project (see the relocations section of the POM file). 这是我的POM文件,其中包括apache jclouds旧版本的Gson,并重命名为最终jar中使用的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>

At the terminal, build the project to create the jar file. 在终端上,构建项目以创建jar文件。

mvn package

Finally, copy the jar file into the root of your main project, in my case a spring boot web application. 最后,将jar文件复制到主项目的根目录中,在我的例子中是一个spring boot web应用程序。

Create a folder in the root of your project called 'maven-local-repo', and at the terminal execute the following command to install your newly created shaded jar file into the local repository of your project (obviously change the filename, artifact etc to match the shaded jar you created). 在项目的根目录中创建一个名为“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

Add your local repository to your POM file; 将本地存储库添加到POM文件中;

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

Finally add a dependency; 最后添加一个依赖;

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

For me that worked like a charm. 对我而言,就像一个魅力。

I switched my Java Code to use their raw HTTP API: 我将我的Java代码切换为使用原始HTTP API:

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

eg 例如

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

}

I know hardly anything about gradle, SpringBoot, or JClouds... 我几乎不了解gradle,SpringBoot或JClouds ......

With those disclaimers out of the way, I hacked my gradle build file like so: 有了这些免责声明,我就像这样破解了我的gradle构建文件:

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

and this seemed to have the effect of locking the GSON version to 2.5 which is the newest version that works with both JClouds and SpringBoot. 这似乎具有将GSON版本锁定到2.5的效果,这是适用于JCloud和SpringBoot的最新版本。 With this hack in place, I can build and run my application. 有了这个hack,我可以构建并运行我的应用程序。

For those who strumbled upon this in early 2023, my jcloud version is 2.5.0, and I solved it by forcing gradle to use Gson 2.8.9.对于那些在 2023 年初偶然发现这个问题的人,我的 jcloud 版本是 2.5.0,我通过强制 gradle 使用 Gson 2.8.9 解决了这个问题。

configurations {
    all {
        resolutionStrategy {
            force 'com.google.code.gson:gson:2.8.9'
        }
    }
}

Take a look at the release notes of newer jcloud versions to see what's the lasted supported GSON version and try to use it.查看较新的 jcloud 版本的发行说明,了解最后支持的 GSON 版本是什么,并尝试使用它。 Sometimes Guava can also cause compatibility issues with Spring.有时 Guava 也会导致与 Spring 的兼容性问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 运行 Spring Boot 应用程序时出现 java.lang.NoSuchMethodError - java.lang.NoSuchMethodError while running spring boot application 将Spring Boot Starter Web依赖项与Mongo Driver 3.11.0一起使用时,java.lang.NoSuchMethodError - java.lang.NoSuchMethodError when using Spring Boot Starter Web dependency with Mongo Driver 3.11.0 使用Apache James 3发送邮件时出现java.lang.NoSuchMethodError - java.lang.NoSuchMethodError when sending mail using Apache James 3 Spring Boot 错误:java.lang.NoSuchMethodError:org.apache.tomcat.util.scan.StandardJarScanner.setJarScanFilter - Spring Boot Error: java.lang.NoSuchMethodError: org.apache.tomcat.util.scan.StandardJarScanner.setJarScanFilter 使用Picasso时java.lang.NoSuchMethodError - java.lang.NoSuchMethodError when using Picasso java.lang.NoSuchMethodError | 春天 - java.lang.NoSuchMethodError | Spring 从GitHub重新发布:Spring Boot应用程序无法启动,并显示错误“ java.lang.NoSuchMethodError - Reposted from GitHub: Spring Boot Application fails to start with error "java.lang.NoSuchMethodError Spring Boot应用程序异常java.lang.NoSuchMethodError:com.fasterxml.jackson.databind.ObjectWriter.forType - Spring boot application exception java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectWriter.forType 使用XSAttributeUse.getValueConstraintValue()时,Apache Xerces引发java.lang.NoSuchMethodError - Apache Xerces throws java.lang.NoSuchMethodError when using XSAttributeUse.getValueConstraintValue() Apache POI java.lang.NoSuchMethodError - Apache POI java.lang.NoSuchMethodError
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM