首页 > 解决方案 > 为什么我可以从端点框架中排除 servlet-api,但不能从端点管理控制应用程序引擎全部中排除?

问题描述

端点-管理-控制-appengine-all

端点框架

这两个包都带有一些版本的servlet-api-2.5.jar/servlet-api依赖

<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>

没有任何排除

2020-07-16 01:22:48.113  WARN 1 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextExcepti
on: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
2020-07-16 01:22:48.127  INFO 1 --- [           main] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-07-16 01:22:48.130 ERROR 1 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.apache.catalina.authenticator.AuthenticatorBase.startInternal(AuthenticatorBase.java:1321)

The following method did not exist:

    'java.lang.String javax.servlet.ServletContext.getVirtualServerName()'

The method's class, javax.servlet.ServletContext, is available from the following locations:

    jar:file:/app/libs/servlet-api-2.5.jar!/javax/servlet/ServletContext.class
    jar:file:/app/libs/endpoints-management-control-appengine-all-1.0.12.jar!/javax/servlet/ServletContext.class
    jar:file:/app/libs/tomcat-embed-core-9.0.36.jar!/javax/servlet/ServletContext.class

The class hierarchy was loaded from the following locations:

    javax.servlet.ServletContext: file:/app/libs/servlet-api-2.5.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of javax.servlet.ServletContext

有一项排除

        <dependency>
            <groupId>com.google.endpoints</groupId>
            <artifactId>endpoints-framework</artifactId>
            <version>${endpoints.framework.version}</version>
        </dependency>
        <!-- [START api_management] -->
        <dependency>
            <groupId>com.google.endpoints</groupId>
            <artifactId>endpoints-management-control-appengine-all</artifactId>
            <version>1.0.12</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- [END api_management] -->

(和上面完全一样)

与其他排除

        <dependency>
            <groupId>com.google.endpoints</groupId>
            <artifactId>endpoints-framework</artifactId>
            <version>${endpoints.framework.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- [START api_management] -->
        <dependency>
            <groupId>com.google.endpoints</groupId>
            <artifactId>endpoints-management-control-appengine-all</artifactId>
            <version>1.0.12</version>
        </dependency>
        <!-- [END api_management] -->
2020-07-16 01:25:49.509  WARN 1 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextExcepti
on: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
2020-07-16 01:25:49.524  INFO 1 --- [           main] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-07-16 01:25:49.529 ERROR 1 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.apache.catalina.authenticator.AuthenticatorBase.startInternal(AuthenticatorBase.java:1321)

The following method did not exist:

    'java.lang.String javax.servlet.ServletContext.getVirtualServerName()'

The method's class, javax.servlet.ServletContext, is available from the following locations:

    jar:file:/app/libs/endpoints-management-control-appengine-all-1.0.12.jar!/javax/servlet/ServletContext.class
    jar:file:/app/libs/tomcat-embed-core-9.0.36.jar!/javax/servlet/ServletContext.class

The class hierarchy was loaded from the following locations:

    javax.servlet.ServletContext: file:/app/libs/endpoints-management-control-appengine-all-1.0.12.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of javax.servlet.ServletContext

两个排除项

        <dependency>
            <groupId>com.google.endpoints</groupId>
            <artifactId>endpoints-framework</artifactId>
            <version>${endpoints.framework.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- [START api_management] -->
        <dependency>
            <groupId>com.google.endpoints</groupId>
            <artifactId>endpoints-management-control-appengine-all</artifactId>
            <version>1.0.12</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- [END api_management] -->

(同上)

因此,我们可以得出结论,排除根本不适用于 endpoints-management-control-appengine-all。

我不知道如何解决这个问题?一定有一些奇怪的怪癖正在发生。

显然,目标是删除所有过时的传递 servlet 依赖项,以便jar:file:/app/libs/tomcat-embed-core-9.0.36.jar!/javax/servlet/ServletContext.class可以自动选择,这可能具有新的虚拟化方法,正如答案所建议的那样,尝试调用不存在的方法。STS

为了测试这些排除项,我正在使用 google jib 插件和 docker run 创建一个 docker 容器

            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>2.4.0</version>
                <configuration>
                    <to>
                        <image>gcr.io/${endpoints.project.id}/endpoints-container</image>
                    </to>
                </configuration>
            </plugin>

PORT=8080 && docker run --rm -p 9090:${PORT} -e PORT=${PORT} gcr.io/project-id/endpoints-container

我不确定这个细节是否相关,但我确实注意到endpoints-management-control-appengine-all具有不同的包结构,就 javax servlet 2.5 的包含方式而言,与endpoints-framework相比。

com包括在端点框架中不会发生的旁边

在此处输入图像描述

标签: spring-bootmavenservletsgoogle-cloud-platformgoogle-cloud-endpoints

解决方案


推荐阅读