Production mode breaks TextField

I experience a pretty strange problem. My application runs fine on my local machine. But as soon as I compile it with mvn install -P production the TextFields in a FormLayout are broken. Instead of the actual fields only the labels are displayed. They are padded right after each other without any space between.

What I want:

What I get:

My setup is 14.1.25 with spring boot.
18215579.png
18215582.png

Hi.

I tried to replicate this on the spring starter with only text fields and form layout, but this at least didn’t get the page to break in production mode.

Is the packaged application run on a specific server or as a jar?
Would you have a simple sample application with the problem?

  • Mikael

The occurance seems pretty random. Right now I have a view with textfields but my tabs are no longer working… I see just a non-clickable label. When I do a mvn vaadin:prepare-frontend the ui is re-compiled at the next start in my IDE. mvn vaadin:build-frontend breaks it again.

Is there any exceptions in the server log or the browsers console log?
There shouldn’t be any difference with only running prepare-frontend reaust vs also running build-frontend apart from
not getting a webpack-dev-server running in the latter case.

I cannot find any error message even with debug level. The occurrence seems pretty random.

When I inspect what is rendered from the textfield it is empty:

Another error that was present for some time now was, that the labels were at the textfield’s right side and they did not respect the FormLayout but looked like they were in a FlexLayout. Absolutely weird behaviour. :frowning:
18217242.png

Christian,

Can you post a code snippet showing how you create the textfields?

Sure. I started with this code:

`@Component
@UIScope
public class CustomerData extends FormLayout {

public CustomerData(ProposalValues proposalValues, TemplateStore templateStore) {
    for (String placeholder : templateStore.getPlaceholder()) {
        var textField = new TextField();
        textField.setPlaceholder(getTranslation(placeholder+".placeholder"));
        addFormItem(textField, placeholder);
        textField.addValueChangeListener(e -> {
            proposalValues.put(placeholder, e.getValue());
        });

    };
}

}`

But once the problem started to occur even a simple add(new TextField("foo"); did not work.

Seems I finally found a way to reproduce the problem. I’ll try to create a simple PoC tomorrow.

Setup:
A VerticalLayout with Tabs. The active tab is a FormLayout with TextFields which are not visible.
As soon as a add a new TextField() to the VerticalLayout even without adding it to the Layout, all TextFields are visible again. They still do not stick to the FormLayout. Maybe I can find a “solution” for this, too.

Christian,

The code seems legit. I wonder if your installation is messed up.

You can try the following:

delete your maven (.m2) direction.

If you’re using NPM:

rm node_modules
rm package-lock.json
rm -rf target
nvm clean install 
npm install

I’ve had a few experiences where removing .m2 or clearing the MPN directories fixed the issues.

Cleared everything, same result.

But I think I found the solution - and a way to reproduce the issue. What triggered the error was a stupid mistake. Instead of public CreateTab(CustomerData customerData, ChapterSelection chapterSelection, Download download) { I used public CreateTab(Component customerData, ChapterSelection chapterSelection, Download download) {.

Spring was able to find the import since the parameter name was identical to the bean name automatically generated from the class. Then something breaks during build-frontend.

With these two classes the behavior can be reproduced:

@UIScope
@Route(value = "")
public class CreateTab extends VerticalLayout {

    public CreateTab(Component customerData) {
        //new TextField();
        add(customerData);
    }
}
@Component
@UIScope
public class CustomerData extends FormLayout {
    
    CustomerData() {
        addFormItem(new TextField(), "Label");
    }
}

Add this two classes to a clean vaadin starter project and remove the default ui elements.

If you do a mvn install -P production the UI is broken. If you enable the TextField in CreateTab it works again. Partially… The TextField does not regard the FormLayout.

As soon as you change the injected type from Component to CustomerDataeverything works as expected.

Christian,

Just a guess, but it might be that the optimizer is eliminating the TextField. When you package for production, only the used components are included.

In your case, it might be that the optimizer determined that the TextField was never used and elimitated it from the production bundle. One way to circumwent would be to include a TextField in one of your other views.

From

https://vaadin.com/docs/v14/flow/production/tutorial-production-mode-basic.html

Bundling is an optimisation where we merge multiple files to a collection so that the browser doesn’t need to request so many files making loading faster.

In 14.1 you can turn off the optimization to help debug issues:

https://vaadin.com/docs/v14/flow/production/tutorial-production-mode-advanced.html

optimizeBundle (default: true): Whether to include only frontend resources used from application entry points (the default) or to include all resources found on the class path. Should normally be left to the default, but a value of false can be useful for faster production builds or debugging discrepancies between development and production mode. This feature is available only in Vaadin Platform 14.1 and newer.

Does it work if you do this?

@UIScope
@Route(value = "")
public class CreateTab extends VerticalLayout {

    public CreateTab(Component customerData) {
	    // Adding textfield just to see if it fixes problem.
        TextField tf = new TextField();
        add(customerData);
    }
}

Martin Israelsen:
Does it work if you do this?

@UIScope
@Route(value = "")
public class CreateTab extends VerticalLayout {

    public CreateTab(Component customerData) {
	    // Adding textfield just to see if it fixes problem.
        TextField tf = new TextField();
        add(customerData);
    }
}

As I wrote above, that’s the workaround I found too. So this matches perfectly to your optimizer theory. The FormLayout keeps being broken.

I consider this behaviour a bug, thus I opened an issue:

https://github.com/vaadin/flow/issues/8115