vaadin / flow

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

build-frontend fails with java.lang.ClassNotFoundException #6004

Open mpetzold opened 5 years ago

mpetzold commented 5 years ago

I am not able to run build-frontend Maven goal. It fails with a ClassNotFoundException I have tested 14.0.0.rc2 and moste recent snapshot versions of flow and Maven plugin.

  1. Create Java project
  2. Add simple POM with repository and vaadin maven plugin
  3. Configure as Maven project
  4. Run Maven build: com.github.eirslett:frontend-maven-plugin:1.7.6:install-node-and-npm -DnodeVersion="v10.16.0"
  5. Run Maven build: vaadin:prepare-frontend
  6. Run Maven build: vaadin:build-frontend

Vaadin / Flow version: 14.0.0.rc2 Vaadin Maven Plugin: 14.0.0.rc2 Java version: 1.8 OS version: Debian 9

[INFO] BUILD FAILURE} [INFO] ------------------------------------------------------------------------} [INFO] Total time: 7.562 s} [INFO] Finished at: 2019-06-28T14:43:14+02:00} [INFO] Final Memory: 34M/174M} [INFO] ------------------------------------------------------------------------} [ERROR] Failed to execute goal com.vaadin:vaadin-maven-plugin:14.0-SNAPSHOT:build-frontend (default-cli) on project technology.tavla.server.runtime.core.manager: Execution default-cli of goal com.vaadin:vaadin-maven-plugin:14.0-SNAPSHOT:build-frontend failed: Unable to locate a required class using custom class loader: com.vaadin.flow.server.webcomponent.WebComponentModulesWriter -> [Help 1]} org.apache.maven.lifecycle.LifecycleExecutionException}{ : Failed to execute goal com.vaadin:vaadin-maven-plugin:14.0-SNAPSHOT:build-frontend (default-cli) on project technology.tavla.server.runtime.core.manager: Execution default-cli of goal com.vaadin:vaadin-maven-plugin:14.0-SNAPSHOT:build-frontend failed: Unable to locate a required class using custom class loader} at org.apache.maven.lifecycle.internal.MojoExecutor.execute(}{ MojoExecutor.java:224}{ )} at org.apache.maven.lifecycle.internal.MojoExecutor.execute(}{ MojoExecutor.java:153}{ )} at org.apache.maven.lifecycle.internal.MojoExecutor.execute(}{ MojoExecutor.java:145}{ )} at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(}{LifecycleModuleBuilder.java:116}{ )} at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(}{LifecycleModuleBuilder.java:80}{ )} at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(}{ SingleThreadedBuilder.java:51}{ )} at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(}{ LifecycleStarter.java:128}{ )} at org.apache.maven.DefaultMaven.doExecute(}{ DefaultMaven.java:307}{ )} at org.apache.maven.DefaultMaven.doExecute(}{ DefaultMaven.java:193}{ )} at org.apache.maven.DefaultMaven.execute(}{ DefaultMaven.java:106}{ )} at org.apache.maven.cli.MavenCli.execute(}{ MavenCli.java:862}{ )} at org.apache.maven.cli.MavenCli.doMain(}{ MavenCli.java:286}{ )} at org.apache.maven.cli.MavenCli.main(}{ MavenCli.java:197}{ )} at sun.reflect.NativeMethodAccessorImpl.invoke0(}{ Native Method}{ )} at sun.reflect.NativeMethodAccessorImpl.invoke(}{ NativeMethodAccessorImpl.java:62}{ )} at sun.reflect.DelegatingMethodAccessorImpl.invoke(}{DelegatingMethodAccessorImpl.java:43}{ )} at java.lang.reflect.Method.invoke(}{ Method.java:498}{ )} at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(}{ Launcher.java:289}{ )} at org.codehaus.plexus.classworlds.launcher.Launcher.launch(}{\cf2\ul Launcher.java:229}{ )} at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(}{Launcher.java:415}{ )} at org.codehaus.plexus.classworlds.launcher.Launcher.main(}{ Launcher.java:356}{ )} Caused by: }{ org.apache.maven.plugin.PluginExecutionException}{ : Execution default-cli of goal com.vaadin:vaadin-maven-plugin:14.0-SNAPSHOT:build-frontend failed: Unable to locate a required class using custom class loader} at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(}{ DefaultBuildPluginManager.java:145}{ )} at org.apache.maven.lifecycle.internal.MojoExecutor.execute(}{ MojoExecutor.java:208 ... 20 more} Caused by: }{ java.lang.IllegalStateException}{ : Unable to locate a required class using custom class loader} at com.vaadin.flow.server.frontend.FrontendWebComponentGenerator.generateWebComponents(FrontendWebComponentGenerator.java:78 at com.vaadin.flow.server.frontend.NodeTasks.(}{ NodeTasks.java:257}{ )} at com.vaadin.flow.server.frontend.NodeTasks.(}{ NodeTasks.java:37}{ )} at com.vaadin.flow.server.frontend.NodeTasks$Builder.build(}{NodeTasks.java:136}{ )} at com.vaadin.flow.plugin.maven.BuildFrontendMojo.runNodeUpdater(}{BuildFrontendMojo.java:143}{ )} at com.vaadin.flow.plugin.maven.BuildFrontendMojo.execute(}{ BuildFrontendMojo.java:127}{ )} at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(}{DefaultBuildPluginManager.java:134}{ )} ... 21 more Caused by: java.lang.ClassNotFoundException : com.vaadin.flow.server.webcomponent.WebComponentModulesWriter} at java.net.URLClassLoader.findClass(}{ URLClassLoader.java:381 at java.lang.ClassLoader.loadClass(}{ ClassLoader.java:424 at java.lang.ClassLoader.loadClass(}{ ClassLoader.java:357 at com.vaadin.flow.plugin.common.FlowPluginFrontendUtils$ReflectionsClassFinder.loadClass(}{ FlowPluginFrontendUtils.java:93 at com.vaadin.flow.server.frontend.ClassFinder$CachedClassFinder.loadClass(}{ ClassFinder.java:136 at com.vaadin.flow.server.frontend.FrontendWebComponentGenerator.generateWebComponents(}{ FrontendWebComponentGenerator.java:71 ... 27 more

ujoni commented 5 years ago

Hello @mpetzold and thank you for reporting this issue!

Few things to clarify: Are you able to provide clear instructions on how to replicate the issue, or an example project? Or, if those are out of the question, could you provide more information about the project in which you encountered this issue? Are you using Spring or CDI? Is this an OSGi project? Did you use snapshot versions in conjunction with 14.0.0.rc2 or was the platform itself a snapshot build?

I attempted to replicate the issue locally but was unable to do so, so any further information would be appreciated.

mpetzold commented 5 years ago

I have updated the description, here is the POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>vaadin-test</groupId>
    <artifactId>vaadin-test</artifactId>
    <version>0.0.1</version>

    <!-- REPOSITORIES -->

    <pluginRepositories>
        <pluginRepository>
            <id>vaadin-prereleases</id>
            <url>https://maven.vaadin.com/vaadin-prereleases</url>
            <snapshots><enabled>false</enabled></snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>vaadin-snapshots</id>
            <url>https://oss.sonatype.org/content/repositories/vaadin-snapshots/</url>
            <releases><enabled>false</enabled></releases>
        </pluginRepository>
    </pluginRepositories>

    <!-- BUILD -->

    <build>
        <plugins>
            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>14.0.0.rc2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-frontend</goal>
                            <goal>build-frontend</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
mpetzold commented 5 years ago

And here is the demo project attached. vaadin-test.zip

ujoni commented 5 years ago

Hi @mpetzold!

To me it seems that your pom is missing Vaadin prerelease repository and Vaadin dependencies. Also, it seemed like the project is using language level 5, while Vaadin supports 8+.

pom.xml additions:

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <repositories>
        <repository>
            <id>vaadin-prereleases</id>
            <url>https://maven.vaadin.com/vaadin-prereleases</url>
            <snapshots><enabled>false</enabled></snapshots>
        </repository>
        <repository>
            <id>vaadin-snapshots</id>
            <url>https://oss.sonatype.org/content/repositories/vaadin-snapshots/</url>
            <releases><enabled>false</enabled></releases>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-core</artifactId>
            <version>14.0.0.rc2</version>
        </dependency>
    </dependencies>

It can also be faster and easier to start out with one of our starter project, such as skeleton-starter-flow, which is a minimal entry point.

mpetzold commented 5 years ago

Hi ujoni, thanks for your suggestion!

However, the prerelease repository is already there. Compile target is not important because I don't have any classes to be compiled. I am working with 1.8 of course.

Why should the project depend on vaadin-core?

I place all Vaadin dependencies in the classpath of the Jar. This is my approach, and my project is far bigger. This is only a test case.

Do you mean the plugin depends on vaadin-core? Maybe a dependency is missing then?

This still does not explain the Exception. The plugin should run anyway or not?

ujoni commented 5 years ago

Vaadin consists of many components and some of those depend on others. The vaadin-core brings in the core components, default theme, and a few other things. The vaadin-maven-plugin depends on flow-server which in turn depends on flow-push.

The error you are seeing comes when the plugin does not find a class defined in flow-server.

mpetzold commented 5 years ago

Ok, so why does it not find the class, even if it depends on flow-server?

mehdi-vaadin commented 5 years ago

@mpetzold You should add flow-server to your dependencies.

<dependencies>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>flow-server</artifactId>
        <version>2.0.1</version>
    </dependency>
</dependencies>
mpetzold commented 5 years ago

Once again, I have all vaadin-core jars and dependencies already in the classpath of my application. IMHO the plugin should work also if the application does not depend on flow-server via Maven.

If the plugin throws a ClassNotFoundException something with the plugin is wrong.

mehdi-vaadin commented 5 years ago

The classpath of your application is different from the classpath of Maven. And, the vaadin maven plugin uses the dependencies of your project declared in pom.xml to scan and load classes. It doesn't use the classpath of your application nor the classpath of Maven.

manolo commented 5 years ago

If you add extra libraries to your classpath using any way that shortcuts maven, that is not a valid configuration in flow.

Even if you have something in your classpath when running mvn it will not be considered, because maven computes the dependency tree based on the dependencies defined in pom.xml but not in the runtime environment.

IMO, it makes not sense to have a maven project if maven does not manage all app and build dependencies.

manolo commented 5 years ago

@mpetzold

And here is the demo project attached.

I don't see any java class in the .zip file, so I cannot run any vaadin project

mpetzold commented 5 years ago

IMHO: Vaadin is a framework / library for Java and not a framework / library for Maven. However, of course you can consider Maven as the default build tool. But still Vaadin should run if standard Java classpaths are used (e.g. Vaadin on Jar classpath).

The Maven plugin resolves a Vaadin class from the project classpath instead of the plugin classpath. This is bad design and leads to the problems I described. This is a classloader issue and should be resolved.

BUT: For your information, I have switched to 14.0.0.RC2 using npm-based frontend builds. With the 14 release and nmp-based builds this issue is not relevant anymore. I don't need it fixed, but this clearly is a bug.