vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
590 stars 164 forks source link

Ignore abstract classes that implements AppShellConfigurator #13822

Open jcgueriaud1 opened 2 years ago

jcgueriaud1 commented 2 years ago

Describe your motivation

I want to be able to package common configuration in a jar that I can reuse it in different applications.

Describe the solution you'd like

I would like to create one common abstract class in a module:

public abstract class CommonAppShell implements AppShellConfigurator {

    @Override
    public void configurePage(AppShellSettings settings) {
        AppShellConfigurator.super.configurePage(settings);
        settings.addInlineWithContents("window.polymerSkipLoadingFontRoboto = true;", Inline.Wrapping.JAVASCRIPT);
    }
}

Then in the application:

public class AppShell extends CommonAppShell {
}

But I have this error:

Multiple classes implementing AppShellConfigurator were found. However, only a single class implementing AppShellConfigurator is allowed. Remove “implements AppShellConfigurator” from all but one of the following classes: demo.designsystem.vaadin.AppShell demo.designsystem.vaadin.DesignAppShell

I'm not sure if it's a bug or an enhancement.

In this pull request the own interface AppShellConfigurator is ignored: https://github.com/vaadin/flow/pull/13663/files but I think it would be more relevant to exclude all the interfaces and the abstract classes. That would fix the issue.

SonReimer commented 1 year ago

The described scenario is the same as our's.

SonReimer commented 1 year ago

There is a simple workaround adding this snippet to your spring configuration:

 @Bean
  public AppShellPredicate appShellPredicate() {
    return clz -> AppShellConfigurator.class.isAssignableFrom(clz) &&
        !(Modifier.isAbstract(clz.getModifiers()) || clz.isInterface());
  } 
ghost commented 1 year ago

@SonReimer thanks for your suggested workaround. I am trying to figure out what you mean by "your spring configuration". Would you please advise what Spring file should you snippet go to? Thanks in advance.

SonReimer commented 1 year ago

This may be your application class, which is a configuration class too, or any other Spring configuration class , that is referenced from your application by @Import. Perhaps you could create one and put it to your common module ?

ghost commented 1 year ago

Thanks for your prompt response. From where will appShellPredicate() be called to avoid the error described by @jcgueriaud1? I have placed the function in the common module but it's not being called.

SonReimer commented 1 year ago

Here's an example:

package de.bmiag.gear.frontend.spring.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.server.startup.AppShellPredicate;

/**
 * spring frontend configuration
 */

@Configuration
public class FrontendMetaConfiguration {

  @Bean
  public AppShellPredicate appShellPredicate() {
    return clz -> AppShellConfigurator.class.isAssignableFrom(clz) &&
        !(Modifier.isAbstract(clz.getModifiers()) || clz.isInterface());
  }
}
ghost commented 1 year ago

Thanks for your example. For some reason, it didnt' work for me. However, I found a better way to manipulate page settings towards SEO-friendly content, which is using static HTML rather than dynamic Vaadin pages.

mcollovati commented 1 day ago

The issue was triaged and currently added to the backlog priority queue for further investigation