Huge issue with hiding elements >= 24.5.0 , show up after reload

Hi everyone. in several views i have problems with invisible components which are not showing up after first start of the app. Only after reload of the page (F5 or cmd+r) the components become visible.

In the code bewlow it is the mail-Field. It is invisible once i start the app and visit the view. When i reload the page it becomes visible. But the other name und firstname are visible!

The same issue i have in other views where i use Font Awesome Icon on buttons. They become only visible when i reload the page. Does anyone knows what this could be?

The problem only occur only after mvn clean package -Pproduction. When i run it in my IDE it works.

I have updated already to 24.6.6, did the vaadin dance but it wont work. I am using Java 21
In the browser console i see following errors (in this view is no split layout used, dont know why it thows an error).

This problem comes up when i switched from 24.5.0 to a higher version. My productive branch is still in 24.5.0 and there i cant reproduce this error.

Here is the mentioned View where it occurs:

Code

`@Route(value = “user”, layout = MainView.class)
@PageTitle(“Benutzerverwaltung”)
@RolesAllowed({SecurityRoles.ROLE_REHNTIER_VIEW, SecurityRoles.ROLE_USERMANAGEMENT_VIEW})
public class UserManagementView extends FormLayout {

PasswordEncoder passwordEncoder = (PasswordEncoder) ApplicationContextProvider.getApplicationContext().getBean("encoder");
PasswordField p1 = new PasswordField("Password");
PasswordField p2 = new PasswordField("Password repeat");
UserDetailsServiceImpl userService = SpringContext.getBean(UserDetailsServiceImpl.class);
UserRoleService userRoleService = SpringContext.getBean(UserRoleService.class);
Binder<User> binderUserDetails = new Binder<>(User.class);
List<User> userList = new ArrayList<>();

User user = new User();

TextField username = new TextField(getTranslation("username"));
TextField firstName = new TextField(getTranslation("firstname"));
TextField lastName = new TextField(getTranslation("lastname"));
Checkbox enabled = new Checkbox(getTranslation("active"));
EmailField mail = new EmailField(getTranslation("email"));
Grid<String> permissionGrid = new Grid();

Button createNewUserButton = new Button(getTranslation("add") + " " + getTranslation("user"), VaadinIcon.PLUS.create());
private ColoredVerticalLayout userDataPanel;
private ColoredVerticalLayout permissionPanel;
private Map<String, Checkbox> roleCheckboxes = new HashMap<>();

public UserManagementView() {

    initUserDetailList();
    bindAllFields();
    createNewUserButton.addClickListener(event -> showNewUserDialog());

    HorizontalLayout horizontalLayout = new HorizontalLayout();
    horizontalLayout.setPadding(true);
    horizontalLayout.setAlignItems(FlexComponent.Alignment.BASELINE);
    horizontalLayout.setVerticalComponentAlignment(FlexComponent.Alignment.BASELINE);
    horizontalLayout.add(createSelectUser(), createNewUserButton);
    this.add(horizontalLayout, 2);

    VerticalLayout verticalLayoutUserData = new VerticalLayout();
    verticalLayoutUserData.setPadding(false);
    verticalLayoutUserData.setWidth("100%");
    userDataPanel = new ColoredVerticalLayout(createUserDataPanel(), getTranslation("user"), VaadinIcon.USER_CARD);
    userDataPanel.setEnabled(false);
    verticalLayoutUserData.add(userDataPanel);
    this.add(verticalLayoutUserData);

    refreshCheckboxesBasedOnUserRoles();

    VerticalLayout verticalLayoutPermissions = new VerticalLayout();
    verticalLayoutPermissions.setPadding(false);
    verticalLayoutPermissions.setWidth("100%");
    permissionPanel = new ColoredVerticalLayout(createPermissionsPanel(), getTranslation("usermanagementview.permissions"), VaadinIcon.SIGN_IN);
    permissionPanel.setEnabled(false);
    verticalLayoutPermissions.add(permissionPanel);
    this.add(verticalLayoutPermissions);
    mail.setErrorMessage(getTranslation("error.validation.failed"));

}

private void refreshCheckboxesBasedOnUserRoles() {
    if (user.getUserRoles() != null) {
        for (UserRole userRole : user.getUserRoles()) {
            Checkbox correspondingCheckbox = roleCheckboxes.get(userRole.getUserRoleName());
            if (correspondingCheckbox != null) {
                correspondingCheckbox.setValue(true);
            }
        }
    }
}

private Component createUserDataPanel() {
    FormLayoutFlexColumns formLayout = new FormLayoutFlexColumns(3);
    formLayout.add(firstName);
    formLayout.add(lastName);
    formLayout.add(mail);
    formLayout.add(enabled, 3);
    formLayout.add(createSaveUserButton());
    formLayout.add(createDeleteButton());
    formLayout.add(createResetPasswordButton());

    return formLayout;
}

private Component createPermissionsPanel() {
    VerticalLayout verticalLayout = new VerticalLayout();
    permissionGrid.addColumn(item -> getTranslation(item)).setHeader("Permission");
    permissionGrid.addComponentColumn(item -> isRoleAllowed(item)).setHeader("Access Permited");
    verticalLayout.add(permissionGrid);

    return verticalLayout;
}

private Component createResetPasswordButton() {
    FormLayout formLayout = new FormLayout();
    formLayout.getStyle().set("padding", "15px");
    formLayout.add(p1);
    formLayout.add(p2);
    formLayout.add(createUpdatePasswordButton());

    Button button = new Button("Reset Password");
    button.addClickListener(buttonClickEvent -> {
        DialogWithTitleBar dialog = new DialogWithTitleBar("Reset Password", formLayout, 50);
        dialog.open();
    });

    return button;
}

private void showNewUserDialog() {
    VerticalLayout verticalLayout = new VerticalLayout();
    TextField userNameTf = new TextField(getTranslation("username"));
    TextField userFirstNameTf = new TextField(getTranslation("firstname"));
    TextField userLastTf = new TextField(getTranslation("lastname"));
    TextField userEmailTf = new TextField(getTranslation("email"));
    PasswordField passwordField1 = new PasswordField(getTranslation("password"));
    PasswordField passwordField2 = new PasswordField(getTranslation("passwordRepeat"));
    verticalLayout.add(userNameTf);
    verticalLayout.add(userFirstNameTf);
    verticalLayout.add(userLastTf);
    verticalLayout.add(userEmailTf);
    verticalLayout.add(passwordField1);
    verticalLayout.add(passwordField2);
    Button saveButton = new Button(getTranslation("save"), VaadinIcon.LOCK.create());
    verticalLayout.add(saveButton);

    DialogWithTitleBar dialogWithTitleBar = new DialogWithTitleBar(verticalLayout, "70%", "70%");

    saveButton.addClickListener(event -> {
        if (userNameTf.getValue() != null && !userNameTf.getValue().equalsIgnoreCase("") && passwordField1.getValue().equals(passwordField2.getValue())) {
            User user = new User();
            user.setUsername(userNameTf.getValue());
            user.setPassword(passwordEncoder.encode(passwordField1.getValue()));
            user.setEnabled(true);
            user.setFirstName(userFirstNameTf.getValue());
            user.setFirstName(userFirstNameTf.getValue());
            user.setLastName(userLastTf.getValue());
            user.setMail(userEmailTf.getValue());
            user.setAccountNonLocked(true);
            user.setCredentialsNonExpired(true);
            userService.save(user);
            dialogWithTitleBar.close();
            UI.getCurrent().getPage().reload();
            NotificationUtil.getSavedSuccesful().open();

        } else {
            NotificationUtil.getDynamicNotification(Emoji.WARN, getTranslation("usermanagementview.userwrong")).open();
        }
    });
    verticalLayout.add(new Span(getTranslation("usermanagementview.infoaftersave")));
    dialogWithTitleBar.open();
}

private void selectUserChangeListener(AbstractField.ComponentValueChangeEvent<Select<User>, User> e) {
    if (e.getValue() != null && !e.getValue().getUsername().equals("")) {
        user = userService.findByUsername(e.getValue().getUsername());
        binderUserDetails.readBean(user);
        userDataPanel.setEnabled(true);
        permissionPanel.setEnabled(true);
        updatePermissionGrid();
    }
}

private void updatePermissionGrid() {
    Map<String, String> map = SecurityRoles.getRoles();
    List<String> allRoles = new ArrayList();
    for (Map.Entry<String, String> entry : map.entrySet()) {
        allRoles.add(entry.getValue());
    }
    permissionGrid.setItems(allRoles);

}

private Component createSelectUser() {
    Select<User> selectUser = new Select<>();
    selectUser.setWidth("300px");
    selectUser.setLabel("Login Name");
    selectUser.setPlaceholder(getTranslation("choose"));
    selectUser.setItems(userList);
    selectUser.setItemLabelGenerator(User::getUsername);
    selectUser.addValueChangeListener((e) -> selectUserChangeListener(e));
    return selectUser;
}

private Component createDeleteButton() {
    Button deleteButton = new Button(getTranslation("delete"), VaadinIcon.TRASH.create());
    deleteButton.addClickListener(event -> {
        ConfirmDialog dialog = new ConfirmDialog();
        dialog.setHeader(getTranslation("record") + " " + getTranslation("delete"));
        dialog.setText(getTranslation("dialog.delete"));
        dialog.setCancelable(true);
        dialog.addCancelListener(cancelEvent -> {
            dialog.close();
        });
        dialog.setRejectable(false);
        dialog.setCancelText(getTranslation("cancel"));
        dialog.setConfirmText(getTranslation("delte"));
        dialog.addConfirmListener(confirmEvent -> {
            deleteUserData(user, dialog);
        });
        dialog.open();
    });
    return deleteButton;
}

private void deleteUserData(User user, ConfirmDialog dialog) {
    userService.delete(user);
    userRoleService.removeAllRoles(user.getId());
    dialog.close();
    UI.getCurrent().getPage().reload();
    NotificationUtil.getDynamicNotification(Emoji.THUMB_UP, getTranslation("notification.proceeded.sucessfully")).open();
}

private void initUserDetailList() {
    userList = userService.findAllWithoutRehntier();
}

private Component createUpdatePasswordButton() {
    Button button = new Button(getTranslation("updatepassword"), new Icon(VaadinIcon.LOCK));
    button.addClickListener(event -> {
        String value1 = p1.getValue();
        String value2 = p2.getValue();
        if (value1.equals(value2)) {
            userService.updatePassword(user.getId(), username.getValue(), passwordEncoder.encode(value1));
            NotificationUtil.getSavedSuccesful().open();
            NotificationUtil.getDynamicNotification(Emoji.WARN, getTranslation("notification.loginlogout")).open();
        } else {
            NotificationUtil.getDynamicNotification(Emoji.SCREAM_FACE, getTranslation("notification.passwordnotmatching")).open();
        }
    });
    return button;
}

private Component createSaveUserButton() {
    Button button = new Button(getTranslation("save"), new Icon(VaadinIcon.LOCK));
    button.addClickListener((e) -> saveUser());
    return button;
}

private void saveUser() {
    try {
        //   user.setPassword(passwordEncoder.encode(password.getValue()));
        binderUserDetails.writeBean(user);
        userService.save(user);
        NotificationUtil.getSavedSuccesful().open();
    } catch (ValidationException e) {
        e.printStackTrace();
    }
}

void checkboxValueChanged(AbstractField.ComponentValueChangeEvent<Checkbox, Boolean> e, String roleName) {
    String roleEnum = SecurityRoles.getRoleEnumByRoleName(roleName);
    if (e.getValue()) {
        if (!isRoleAlreadyAllowed(roleEnum)) {
            userRoleService.addRole(user.getId(), roleEnum);
            NotificationUtil.getSavedSuccesful().open();
            NotificationUtil.getDynamicNotification(Emoji.WARN, getTranslation("notification.loginlogout")).open();
        }
    } else {
        userRoleService.removeRole(user.getId(), roleEnum);
        NotificationUtil.getSavedSuccesful().open();
        NotificationUtil.getDynamicNotification(Emoji.WARN, getTranslation("notification.loginlogout")).open();
    }
}

private Component isRoleAllowed(String role) {
    String roleEnum = SecurityRoles.getRoleEnumByRoleName(role);
    boolean allowed = false;
    if (user.getUserRoles() != null) {
        for (UserRole userRole : user.getUserRoles()) {
            if (userRole.getUserRoleName().toString().equals(roleEnum)) {
                allowed = true;
                break;
            }
        }
    }
    Checkbox cb = new Checkbox();
    cb.setValue(allowed);
    cb.addValueChangeListener((e) -> checkboxValueChanged(e, role));
    return cb;
}

private boolean isRoleAlreadyAllowed(String role) {
    boolean allowed = false;
    if (user.getUserRoles() != null) {
        for (UserRole userRole : user.getUserRoles()) {
            if (userRole.getUserRoleName().equals(role)) {
                allowed = true;
                break;
            }
        }
    }
    return allowed;
}

private void bindAllFields() {
    binderUserDetails.bind(firstName, "firstName");
    binderUserDetails.bind(lastName, "lastName");
    binderUserDetails.bind(username, "username");
    binderUserDetails.bind(mail, "mail");
    binderUserDetails.bind(enabled, "enabled");
    binderUserDetails.readBean(user);
}

}`

When i switch back to 24.4.22 everything works like expected! Looks like a bug

Edit: sometimes it works, sometimes not. I dont get it

You can enable “forceProductionBuild” and disable “optimizeBundle” in your maven config to see if that makes a difference for you. (I would guess it’s going to work afterwards)

Thanks can’t find a documentation for that, do you have any link for this?

Starting a Vaadin Project with Gradle | Start a Project | Getting Started | Vaadin Docs first docs search result :sweat_smile: even tho it says Gradle, it’s the same for Maven

BTW, when upgrading the Vaadin version, what does the production build logs look like?
Does it tell that a new bundle is created or is it using the default bundle?
Can you post the logs produced by the build-frontend goal?

On a first attempt that worked. But why? Why it only appears with some components, but not all. Also the icons on buttons are now available. hell yeah thank you Christian

For some reason, the bytecode scanner may not find some component. Can you enable optimizeBundle again and run maven with -X flag?
This will produce a verbose output, but the log could contain useful information to understand why the component is missing.

Cant find an issue whn using - X

But have a new problem with the icons which disappear. When i resize the window, it very randomly hide and show Icons while resizing the window. Not a big problem because no one resizes its screen every second :D But its possible, that icons disappear