0

I am currently working on microservices using springboot and Vaadin 8, and I want to use Embedded UI 2.0 add-on for Vaadin.
I first tried embedding a simple Springboot + Vaadin into a host Vaadin application as shown in the example.
Here's the result code for the host application :

import ...
import org.vaadin.embedded.VaadinUIComponent;


@Theme(ValoTheme.THEME_NAME)
public class HostUI extends UI {

@Override
protected void init(VaadinRequest vaadinRequest) { 
    /*My Spring boot application */      
    VaadinUIComponent ui1 = new VaadinUIComponent("http://localhost:8081/app2/");
    ui1.setSizeFull(); 
    /* A simple vaadin application*/ 
    VaadinUIComponent ui2 = new VaadinUIComponent("http://localhost:9020");

    HorizontalSplitPanel split = new HorizontalSplitPanel(ui1, ui2);
    split.setSizeFull();
    setContent(split);
}

But I keep having an issue with VAADIN/* resources loading :

{"timestamp":1501683162735,"status":404,"error":"Not Found","message":"No message available","path":"
/app2/widgetsets/ws84167e472e91ff0ea8255f8f1b189aa0/ws84167e472e91ff0ea8255f8f1b189aa0.nocache.js"}

where /app2/ is the path to my application.

I'm not sure how the path to the resources are resolved, but I know that the Vaadin directory is supposed to be /app2/VAADIN/* since the widgetsets and other vaadin compiled resources are working just fine and are available when I open the application directly from my browser.
Here are some additional information :

  • Vaadin version : 8.0.5
  • Embedded UI add-on version : 2.0
  • I used ValoTheme for all 3 applications (host and embedded)
  • vaadin.widgetset.mode is set to fetch mode
  • I made sure that CORS is enabled for the applications.

I searched quite a while to resolve this issue but couldn't find enough sources for this particular situation, and I'm also a beginner in both Spring and Vaadin, so I could definitely use some help.

zelha
  • 3
  • 4
  • Haven't checked the add-on sources, but I have a hunch it's tightly coupled to boot, probably dispatcher servlet, and the Vaadin servlet servicing your apps' requests. It'll probably help getting some answers if you could provide a [sscce](http://sscce.org) to easily reproduce your issue. – Morfic Aug 02 '17 at 20:02
  • Here's a [link](https://github.com/zelha/45465131-sscce.git) to a repository were I reproduced the bug, if that's okay. – zelha Aug 03 '17 at 10:49

2 Answers2

0

TL;DR; version

This seems to be a bug in the add-on, and there's a similar issue open on their tracker, not sure whether it's you or someone else. But why do you need to use it in the first place? What are you trying to achieve that can not be done with a regular Vaadin application and you need to embed multiple UIs?


Detailed version

So I've done some digging and your observation is correct, /VAADIN/ is missing from the path. There may also be other failing requests which are handled by vaadinServlet in a spring boot app, such as heartbeat and uidl.

Stand alone app-request:

stand alone app request

Embedded app-request:

embedded app request

With a little mode debugging, it seems that the add-on is indeed using an incorrect path: incorrect path

Finally traced back to an incorrect regex replacement of ./VAADIN with http://localhost:9030/ instead of the correct one http://localhost:9030/VAADIN.

It seems to me like it's a bug in the add-on, but probably only the dev can confirm or explain why it's being done like this.

regex replacement

As a work around we can use a spring controller to redirect the requests to the correct URLs, but even this has it's limitation. It breaks at the first page refresh, because the v-uiId which is normally increased, remains 0.

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class VaadinRedirectController {
    private static final String INCOMPLETE_WIDGETSET_PATH = "/widgetsets/**";
    private static final String INCOMPLETE_THEME_PATH = "/themes/**";
    private static final String INCOMPLETE_UIDL_PATH = "/UIDL/**";
    private static final String INCOMPLETE_HEARTBEAT_PATH = "/HEARTBEAT/**";

    @RequestMapping(value = {INCOMPLETE_WIDGETSET_PATH, INCOMPLETE_THEME_PATH,})
    public String redirectWidgetsetAndThemeRequests(HttpServletRequest request) {
        return createRedirectPath(request, "VAADIN");
    }

    @RequestMapping(value = {INCOMPLETE_UIDL_PATH, INCOMPLETE_HEARTBEAT_PATH})
    public String redirectUidlAndHeartbeatRequests(HttpServletRequest request) {
        return createRedirectPath(request, "vaadinServlet");
    }

    private String createRedirectPath(HttpServletRequest request, String prefix) {
        String path = "redirect:/" + prefix + getPath(request);
        if (request.getQueryString() != null && !request.getQueryString().isEmpty()) {
            path += "?" + request.getQueryString();
        }
        return path;
    }

    private Object getPath(HttpServletRequest request) {
        return request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
    }
}
Morfic
  • 15,178
  • 3
  • 51
  • 61
  • Thanks for your answer. I need to use the add-on as a solution for the UI-composition problem since I have to build some UI screen or page to display UIs of my multiple services (so that each service can have it's own standalone ui, and be accessible without the 'host' application). Regarding your solution, I tried implementing it, and made some tests : The controller redirects all requests like `localhost:8080/widgetsets/**` as expected; but not `localhost:8080widgetsets/**`, wich is the url produced by the host application. I don't know if there's a possible solution for this. – zelha Aug 04 '17 at 11:03
  • @Zineb.elh yeah, forgot about that, add a `/` in your host application to the boot app url :-). But please keep in mind that it still breaks on first refresh... haven't found a solution for that yet. – Morfic Aug 04 '17 at 11:06
  • Thanks again for helping. I'm aware that it's not a final solution for the problem. I am waiting for the add-on developer to look into it. I am trying to understand the role of the `v-uiId` that is sent at each request in order to work around that too. I noticed that the UI does not interact (ie, doesn't change when I click on a button). Is that related to the `v-uiId` issue ? – zelha Aug 04 '17 at 13:44
  • @Zineb.elh I updated my answer with a link to a [similar issue ](https://github.com/zelha/45465131-sscce.git) open on the project's github page and just got a notification about a release 2.1 from the dev. I'm not at home to try it, but perhaps you can give it a go and report to Alejandro whether the issues are fixed or not in this new version. This way you can work closely towards the resolution. – Morfic Aug 04 '17 at 13:52
0

Nice explanation by Morfic! Thanks. And yeah, there was a problem with the add-on. Fixed in 2.1. Please see more info at https://vaadin.com/forum#!/thread/16448312

Alejandro Duarte
  • 1,365
  • 8
  • 15