Ошибка выполнения с AmazonEc2Client при перемещении пакета с использованием тени maven

Я работаю над java-агентом и использую плагин maven shadow для перемещения своих зависимостей, чтобы избежать конфликтов и проблем с путями к классам. Я еще не очень хорошо знаком с плагином затенения, но я столкнулся с этой проблемой, когда я сказал плагину затенить мои зависимости и добавить все с помощью shaded (например, com.amazonaws.services.ec2 -> затененный.amazonaws .services.ec2), однако, когда я запускаю свое приложение, которое создает AmazonEc2Client, я получаю следующую ошибку:

Caused by: shaded.com.amazonaws.AmazonClientException: Unable to instantiate request handler chain for client: com.amazonaws.services.ec2.model.transform.EC2RequestHandler
    at shaded.com.amazonaws.handlers.HandlerChainFactory.createRequestHandlerChain(HandlerChainFactory.java:158)
    at shaded.com.amazonaws.handlers.HandlerChainFactory.newRequestHandlerChain(HandlerChainFactory.java:45)
    at shaded.com.amazonaws.services.ec2.AmazonEC2Client.init(AmazonEC2Client.java:308)
    at shaded.com.amazonaws.services.ec2.AmazonEC2Client.<init>(AmazonEC2Client.java:297)
    at shaded.com.amazonaws.services.ec2.AmazonEC2Client.<init>(AmazonEC2Client.java:280)
    at shaded.com.amazonaws.services.ec2.AmazonEC2ClientBuilder.build(AmazonEC2ClientBuilder.java:61)
    at shaded.com.amazonaws.services.ec2.AmazonEC2ClientBuilder.build(AmazonEC2ClientBuilder.java:27)
    at shaded.com.amazonaws.client.builder.AwsSyncClientBuilder.build(AwsSyncClientBuilder.java:46)
    at my.sample.project.Boot.<clinit>(Boot.java:49)
    ... 6 more
Caused by: java.lang.ClassNotFoundException: com.amazonaws.services.ec2.model.transform.EC2RequestHandler
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at shaded.com.amazonaws.util.ClassLoaderHelper.loadClass(ClassLoaderHelper.java:177)
    at shaded.com.amazonaws.util.ClassLoaderHelper.loadClass(ClassLoaderHelper.java:136)
    at shaded.com.amazonaws.handlers.HandlerChainF

Вот фрагмент моего pom.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.0.0</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <manifestEntries>
                            <Premain-Class>my.sample.project.Boot</Premain-Class>
                        </manifestEntries>
                    </transformer>
                </transformers>
                <relocations>
                    <relocation>
                        <pattern>com.amazonaws</pattern>
                        <shadedPattern>shaded.com.amazonaws</shadedPattern>
                    </relocation>
                    <artifactSet>
                        <includes>
                            <include>*:*</include>
                        </includes>
                    </artifactSet>
            </configuration>
       </execution>
    </executions>
</plugin>

А вот фрагмент кода, создающего экземпляр клиента EC2.

public static void premain(final String agentArgs, Instrumentation instrumentation) {
        log.info("Connecting to AWS...");
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        clientConfiguration.withRetryPolicy(new RetryPolicy(DEFAULT_RETRY_CONDITION,
                                                            new PredefinedBackoffStrategies.ExponentialBackoffStrategy(500, 8000),
                                                            DEFAULT_MAX_ERROR_RETRY,
                                                            true));
        AwsRequests.client = AmazonEC2Client.builder()
                                            .withClientConfiguration(clientConfiguration)
                                            .build();
    }

Проблема возникает из-за того, что когда amazonec2client фактически создается, похоже, что он все еще ожидает найти класс в пакете com.amazonaws.services.ec2, но он был закрашен в пакет shaded.com.amazonaws.services.ec2. Насколько я понимаю, плагин затенения обновит базовый код, чтобы указать на правильные затененные пакеты, я что-то упустил?

Любая помощь приветствуется, спасибо!


person thegoldengoose    schedule 19.05.2020    source источник


Ответы (1)


Мне удалось выяснить проблему, метод инициализации AmazonEC2client предполагает наличие следующих ресурсов:

requestHandler2s.addAll(chainFactory.newRequestHandlerChain("/com/amazonaws/services/ec2/request.handlers"));
requestHandler2s.addAll(chainFactory.newRequestHandler2Chain("/com/amazonaws/services/ec2/request.handler2s"));

Я только что сделал исключение в своем pom.xml для всего, что находится в пакете преобразования в amazonaws, например:

<excludes>
    <exclude>com.amazonaws.services.ec2.model.transform.*</exclude>
</excludes>

И это сработало, надеюсь, это поможет кому-то в будущем!

person thegoldengoose    schedule 20.05.2020
comment
Не работает для меня, сталкивающегося с той же проблемой. - person Vicky; 14.06.2021