xiaoymin / knife4j

Knife4j is a set of Swagger2 and OpenAPI3 All-in-one enhancement solution
https://doc.xiaominfo.com
Apache License 2.0
4.15k stars 622 forks source link

knife4j-aggregation-spring-boot-starter不支持springboot3 #739

Open Kyle0820 opened 9 months ago

Kyle0820 commented 9 months ago

你好,knife4j-aggregation-spring-boot-starter不支持springboot3,这里用了javax,pom和堆栈报错如下


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
<dependencies>
<dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-aggregation-spring-boot-starter</artifactId>
            <version>4.4.0</version>
        </dependency>
</dependencies>
java.lang.IllegalStateException: Error processing condition on org.springdoc.core.configuration.SpringDocConfiguration$QuerydslProvider.queryDslQuerydslPredicateOperationCustomizer
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-3.2.3.jar:3.2.3]
    at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:183) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:428) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:289) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:788) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:606) ~[spring-context-6.1.4.jar:6.1.4]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.3.jar:3.2.3]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.3.jar:3.2.3]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.3.jar:3.2.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[spring-boot-3.2.3.jar:3.2.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-3.2.3.jar:3.2.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-3.2.3.jar:3.2.3]
    at com.hainayun.lift.App.main(App.java:20) ~[classes/:na]
Caused by: java.lang.IllegalStateException: Failed to introspect Class [com.github.xiaoymin.knife4j.aggre.spring.configuration.Knife4jAggregationAutoConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@4e0e2f2a]
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:483) ~[spring-core-6.1.4.jar:6.1.4]
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:360) ~[spring-core-6.1.4.jar:6.1.4]
    at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:417) ~[spring-core-6.1.4.jar:6.1.4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$1(AbstractAutowireCapableBeanFactory.java:750) ~[spring-beans-6.1.4.jar:6.1.4]
    at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) ~[na:na]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:749) ~[spring-beans-6.1.4.jar:6.1.4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:682) ~[spring-beans-6.1.4.jar:6.1.4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:653) ~[spring-beans-6.1.4.jar:6.1.4]
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1644) ~[spring-beans-6.1.4.jar:6.1.4]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:562) ~[spring-beans-6.1.4.jar:6.1.4]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:534) ~[spring-beans-6.1.4.jar:6.1.4]
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:247) ~[spring-boot-autoconfigure-3.2.3.jar:3.2.3]
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:240) ~[spring-boot-autoconfigure-3.2.3.jar:3.2.3]
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:230) ~[spring-boot-autoconfigure-3.2.3.jar:3.2.3]
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:183) ~[spring-boot-autoconfigure-3.2.3.jar:3.2.3]
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:158) ~[spring-boot-autoconfigure-3.2.3.jar:3.2.3]
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-3.2.3.jar:3.2.3]
    ... 17 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/servlet/Filter
    at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na]
    at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578) ~[na:na]
    at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676) ~[na:na]
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:465) ~[spring-core-6.1.4.jar:6.1.4]
    ... 33 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.Filter
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526) ~[na:na]
    ... 37 common frames omitted
irezm commented 3 months ago

问题在于作者用了

javax.servlet javax.servlet-api provided

需要作者替换为

jakarta.servlet jakarta.servlet-api provided
irezm commented 3 months ago

问题在于作者用了 javax.servlet javax.servlet-api provided

需要作者替换为 jakarta.servlet jakarta.servlet-api provided

要么就是开发者自己下载源码重新编译

Kyle0820 commented 3 months ago

问题在于作者用了 javax.servlet javax.servlet-api provided 需要作者替换为 jakarta.servlet jakarta.servlet-api provided

要么就是开发者自己下载源码重新编译

是的我也知道原因,但是项目太忙没精力提交PR, 因为这个我已经用回spring boot2.7了

irezm commented 3 months ago

问题在于作者用了 javax.servlet javax.servlet-api provided 需要作者替换为 jakarta.servlet jakarta.servlet-api provided

要么就是开发者自己下载源码重新编译

是的我也知道原因,但是项目太忙没精力提交PR, 因为这个我已经用回spring boot2.7了

自己写两个接口就好了

     /**
     * 获取API文档
     */
    @GetMapping("/v3/api-docs")
    public ResponseEntity<JSONObject> apiDocs(HttpServletRequest request) {
        // 从resources目录下读取openapi.json文件
        String json = ResourceUtil.readUtf8Str("smart-doc/openapi.json");
        JSONObject parse = JsonUtil.parse(json, JSONObject.class);

        // 获得远程host 如https://irez.cn
        String remoteHost = request.getRequestURL().toString().replace(request.getRequestURI(), "");
        // 替换servers->url
        parse.getJSONArray("servers").getJSONObject(0).set("url", remoteHost);
        return ResponseEntity.ok(parse);
    }

    /**
     * 获取API文档
     */
    @GetMapping("/v3/api-docs/swagger-config")
    public ResponseEntity<JSONObject> swaggerConfig() {
        JSONObject parse = new JSONObject();
        parse.set("configUrl", "/v3/api-docs/swagger-config");
        parse.set("oauth2RedirectUrl", "http://127.0.0.1:37001/swagger-ui/oauth2-redirect.html");
        parse.set("url", "/v3/api-docs");
        parse.set("validatorUrl", "");
        return ResponseEntity.ok(parse);
    }

然后引用 knife4j-openapi2-ui或者knife4j-openapi3-ui依赖

com.github.xiaoymin knife4j-openapi3-ui
irezm commented 3 months ago

问题在于作者用了 javax.servlet javax.servlet-api provided 需要作者替换为 jakarta.servlet jakarta.servlet-api provided

要么就是开发者自己下载源码重新编译

是的我也知道原因,但是项目太忙没精力提交PR, 因为这个我已经用回spring boot2.7了

自己写两个接口就好了

     /**
     * 获取API文档
     */
    @GetMapping("/v3/api-docs")
    public ResponseEntity<JSONObject> apiDocs(HttpServletRequest request) {
        // 从resources目录下读取openapi.json文件
        String json = ResourceUtil.readUtf8Str("smart-doc/openapi.json");
        JSONObject parse = JsonUtil.parse(json, JSONObject.class);

        // 获得远程host 如https://irez.cn
        String remoteHost = request.getRequestURL().toString().replace(request.getRequestURI(), "");
        // 替换servers->url
        parse.getJSONArray("servers").getJSONObject(0).set("url", remoteHost);
        return ResponseEntity.ok(parse);
    }

    /**
     * 获取API文档
     */
    @GetMapping("/v3/api-docs/swagger-config")
    public ResponseEntity<JSONObject> swaggerConfig() {
        JSONObject parse = new JSONObject();
        parse.set("configUrl", "/v3/api-docs/swagger-config");
        parse.set("oauth2RedirectUrl", "http://127.0.0.1:37001/swagger-ui/oauth2-redirect.html");
        parse.set("url", "/v3/api-docs");
        parse.set("validatorUrl", "");
        return ResponseEntity.ok(parse);
    }

然后引用 knife4j-openapi2-ui或者knife4j-openapi3-ui依赖 com.github.xiaoymin knife4j-openapi3-ui

提交了一个测试demo https://github.com/irezm/springboot-knife4j-smart-doc