Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swagger UI shows a blank page #10163

Closed
tarekoraby opened this issue Mar 2, 2021 · 21 comments
Closed

Swagger UI shows a blank page #10163

tarekoraby opened this issue Mar 2, 2021 · 21 comments

Comments

@tarekoraby
Copy link
Contributor

Description of the bug / feature

In a Vaadin 18 + Spring app, swagger-ui page is not showing (returns a blank page) with errors in the console.

Minimal reproducible example

  1. Create a v18 Java project from start.vaadin.com
  2. Add the dependency
<dependencies>
    <dependency>
   <groupId>org.springdoc</groupId>
   <artifactId>springdoc-openapi-ui</artifactId>
   <version>1.5.5</version>
</dependency>
  1. Change Vaadin mapping to a different path using vaadin.urlMapping in application.properties. For example,
vaadin.url-mapping=/ui/*
  1. Run the server, and open http://localhost:8080/swagger-ui.html

Expected behavior

The Swagger UI page is opened

Actual behavior

Only a blank page is displayed with the following errors in the console
image

Versions:

- Vaadin / Flow version: 18.0.6
- Java version: 11
- OS version: Windows
@tarekoraby
Copy link
Contributor Author

Note, that Swagger UI seems to work fine in v14.X

@FDelporte
Copy link

Same error on

  • Java version: 15
  • OS version: Mac

@denis-anisimov
Copy link
Contributor

The issue is most likely a generic one even though it's technically a Spring add-on issue.

@Frettman
Copy link

Frettman commented Feb 8, 2022

It needs to be exactly vaadin.urlMapping. vaadin.url-mapping will not work, even though your IDE might suggest it. It's not a regular Spring Boot configuration property and as such it's treated a bit differently that than you might expect.

@letrthang
Copy link

letrthang commented Jun 11, 2022

I am using vaadin flow 23, Java 17, Spring boot 2.7.0 and config not work.

image

Error message:

image

I think we don't need change vaadin base URL but we need config to set Vaadin servlet URL mapping having lowest priority in Spring. So it won't block other servlet mappings as CXF/swagger.

URL mapping priority maybe (Low to High): Spring servlet -> Vaadin servlet -> CXF/Swagger.

@kochetkov-ma
Copy link

kochetkov-ma commented Jul 2, 2022

I figured it out. And it appears to be a bug, but there is a simple way to avoid it.

Vaadin version 22.0.18
Spring Boot version 2.4.6

I had the following application.yaml

vaadin:
  url-mapping: /web/*

The problem is in this code below. Specifically in the name of the setting and how to get it by com.vaadin.flow.spring.RootMappedCondition.

public class RootMappedCondition implements Condition {

    public static final String URL_MAPPING_PROPERTY = "vaadin.urlMapping";

    @Override
    public boolean matches(ConditionContext context,
            AnnotatedTypeMetadata metadata) {
        return isRootMapping(
                context.getEnvironment().getProperty(URL_MAPPING_PROPERTY));
    }

We have the name of the setting "vaadin.urlMapping" in camelCase, and according to the Spring Boot specification it handles it by Relaxed Binding rules and for it vaadin.url-mapping == vaadin.urlMapping

BUT the way to get the setting context.getEnvironment().getProperty(URL_MAPPING_PROPERTY) knows nothing about these rules and only sees vaadin.urlMapping

To get the setting correctly, you need to get the VaadinConfigurationProperties bean from the context, but at this stage it is not in the context and the setting will not be resolved by Relaxed Binding rules from Spring Boot

So at this point you can easily bypass this problem and use the configuration name vaadin.urlMapping in application.yaml.

@Artur-
Copy link
Member

Artur- commented Jul 2, 2022

Sounds like what was fixed in #13791

@letrthang
Copy link

letrthang commented Jul 24, 2022

The issue still happens even we change url-mapping. It is better to fix on issue #12949

@Frettman
Copy link

@letrthang, I have the same setup (based on your screenshots) and it works for me. spring/issues#602 contains some details why simply changing the orders of the URL mappings for Vaadin and Spring's resource handlers won't help.
Also, judging from your screenshot, the issue in your case is that Spring handles Vaadin's path at /ui/, so letting Vaadin ignore requests to certain URLs and let them pass on to Spring, wouldn't really help. Or has the error changed now?
Also, I can confirm that in the latest Vaadin version both vaadin.urlMapping and vaadin.url-mapping work now.

@letrthang
Copy link

letrthang commented Jul 24, 2022

@Frettman it still doesn't work for me. I cannot access restful resource using postman and also swagger UI page doesn't show up.

image

image

@Frettman
Copy link

@letrthang, that error from your first screenshot is not from Vaadin; Vaadin would show something like in the image from this Stackoverflow question.
Your error looks like something from Spring, so to me it seems like you have another issue.
Have you tried accessing /swagger-ui/index.html directly? That's where /swagger-ui.html should get redirected to.

@letrthang
Copy link

letrthang commented Jul 24, 2022

@Frettman i created a test endpoint in vaadin demo project here, swagger still not work.

https://github.com/letrthang/vaadin23-flow-pro-components/blob/main/src/main/java/com/example/application/data/endpoint/TestSwaggerImpl.java

image

result:

image

Postman to send request also taken control by Vaadin handler:

image

@letrthang
Copy link

@tarekoraby @denis-anisimov may i know you have any plan to fix this issue ?

@tarekoraby
Copy link
Contributor Author

@mshabarov, can someone from the Flow team please provide an update on this issue?

@Artur-
Copy link
Member

Artur- commented Sep 15, 2022

This seems to work fine.

npx @vaadin/cli init swag-test
cd swag-test
# Add springdoc-openapi-ui dependency
# Add url mapping
mvn

opening http://localhost:4444/swagger-ui.html shows the swagger UI

@letrthang
Copy link

letrthang commented Sep 15, 2022

this config now will work with vaadin 23.2.1

vaadin.url-mapping=/web/*
springdoc.api-docs.path=/api/api-docs
springdoc.swagger-ui.path=/api/swagger-ui.html

However I prefer to get same config as Vaadin 14 as below which Vaadin home is root URL and allow to exclude swagger from root url (for now, this config is not working):

vaadin.url-mapping=/*
springdoc.api-docs.path=/api/api-docs
springdoc.swagger-ui.path=/api/swagger-ui.html

Anyway, there is other issue with open-api and Hilla:

Both springdoc-openapi-ui and Hilla using swagger-core and swagger-models with different versions, so causing swagger crashing.

Below config will work:

<properties>
        <java.version>17</java.version>
        <vaadin.version>23.2.1</vaadin.version>
        <hilla.version>1.2.1</hilla.version>
    </properties>
<dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.6.7</version>
            <!-- avoid conflict with hilla -->
            <exclusions>
                <exclusion>
                    <groupId>io.swagger.core.v3</groupId>
                    <artifactId>swagger-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>io.swagger.core.v3</groupId>
                    <artifactId>swagger-models</artifactId>
                </exclusion>
            </exclusions>
        </dependency> 

Below config will not work:

<properties>
        <java.version>17</java.version>
        <vaadin.version>23.2.1</vaadin.version>
        <hilla.version>1.2.1</hilla.version>
    </properties>
<dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.6.11</version>
            <!-- avoid conflict with hilla -->
            <exclusions>
                <exclusion>
                    <groupId>io.swagger.core.v3</groupId>
                    <artifactId>swagger-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>io.swagger.core.v3</groupId>
                    <artifactId>swagger-models</artifactId>
                </exclusion>
            </exclusions>
        </dependency> 
java.lang.NoSuchMethodError: 'io.swagger.v3.oas.models.media.ComposedSchema io.swagger.v3.oas.models.media.ComposedSchema.addAllOfItem(io.swagger.v3.oas.models.media.Schema)'
	at dev.hilla.generator.OpenAPIObjectGenerator.lambda$parseNonEndpointClassAsSchema$24(OpenAPIObjectGenerator.java:524) ~[endpoint-1.2.1.jar:na]

image

I submitted new issue to Hilla here:
vaadin/hilla#551

@Artur-
Copy link
Member

Artur- commented Sep 16, 2022

Without the url mapping it seems that the Vaadin handler is invoked before the Swagger handler, preventing the swagger ui from showing. If this order is removed https://github.com/vaadin/flow/blob/master/vaadin-spring/src/main/java/com/vaadin/flow/spring/VaadinServletConfiguration.java#L61 the Swagger UI is shown but instead Vaadin views fail to render because of a 404

@Frettman
Copy link

@Artur-, it's what I described in detail in vaadin/spring#602 and an attempt at a solution in vaadin/spring#604.
Let's just say setting the URL mapping is much easier ;)

@Artur-
Copy link
Member

Artur- commented Sep 16, 2022

Thanks, I was just wondering if there really is no concept of "I want to handle some of the paths that match this mapping so ask me and if I say 'no thanks', then ask the next handler".

It sounds really impossible to be able to answer upfront "Will Vaadin handle this request" without actually letting Vaadin handle the request and see. The static cases like routes are easy, the dynamic code that you are able to add here and there is not.

@Artur-
Copy link
Member

Artur- commented Sep 16, 2022

So if the resource handler and the Vaadin handler could be combined so that if the first returns 404, the second one is consulted then magically everything would work..

@Artur-
Copy link
Member

Artur- commented Oct 3, 2022

This is fixed in #14579 but not in a fully automatic way. You can define paths to exclude, e.g. vaadin.excludeUrls=/swagger-ui/** and those will not be handled by the vaadin servlet when it is mapped to /*

@Artur- Artur- closed this as completed Oct 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants