Missing js modules at start after building fat jar with profile production

First I have to confess that I opened a ticket https://github.com/vaadin/flow/issues/6596
because I didn’t know whether this bug belongs here into the forum or on github as ticket.

I can run my vaadin application from IntelliJ IDE but not from console as fat jar.
What I use:

IntelliJ 2019.2.2
Vaadin 14.0.7
Spring Boot 2.1.7.RELEASE
java version "11.0.4" 2019-07-16 LTS
npm version
{ npm: '6.9.0',
ares: '1.15.0',
brotli: '1.0.7',
cldr: '35.1',
http_parser: '2.8.0',
icu: '64.2',
modules: '64',
napi: '4',
nghttp2: '1.39.2',
node: '10.16.3',
openssl: '1.1.1c',
tz: '2019a',
unicode: '12.1',
uv: '1.28.0',
v8: '6.8.275.32-node.54',
zlib: '1.2.11' }

I get the following error:

2019-10-01 21:47:17.149 INFO 41556 — [ main]
dev-updater :

Failed to find the following imports in the node_modules tree:
- @vaadin/flow-frontend/contextMenuConnector-es6.js
- @vaadin/flow-frontend/gridConnector.js
- @vaadin/flow-frontend/contextMenuConnector.js
- @vaadin/flow-frontend/flow-component-renderer.js
- @vaadin/flow-frontend/gridConnector-es6.js
- @vaadin/flow-frontend/vaadin-grid-flow-selection-column.js
If the build fails, check that npm packages are installed.

My pom.xml (the *** in artifact id in the parent tag are a real name. I must hide it here :wink: :

<?xml version="1.0" encoding="UTF-8"?>



net.mirwaldt.***
net.mirwaldt
0.0.1-SNAPSHOT

4.0.0

<artifactId>webapp</artifactId>

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    <vaadin.version>14.0.7</vaadin.version>

    <drivers.dir>${project.basedir}/drivers</drivers.dir>
    <drivers.downloader.phase>pre-integration-test</drivers.downloader.phase>
</properties>

<pluginRepositories>
    <pluginRepository>
        <id>central</id>
        <url>https://repo1.maven.org/maven2/</url>
        <snapshots><enabled>false</enabled></snapshots>
    </pluginRepository>
</pluginRepositories>

<repositories>
    <repository>
        <id>central</id>
        <url>https://repo1.maven.org/maven2/</url>
        <snapshots><enabled>false</enabled></snapshots>
    </repository>
    <!-- Repository used by many Vaadin add-ons -->
    <repository>
        <id>Vaadin Directory</id>
        <url>https://maven.vaadin.com/vaadin-addons</url>
        <snapshots><enabled>false</enabled></snapshots>
    </repository>
</repositories>

<!-- https://www.baeldung.com/spring-boot-dependency-management-custom-parent -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.1.7.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-bom</artifactId>
            <version>${vaadin.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
    </dependency>

    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>3.0</version>
    </dependency>
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>

    <dependency>
        <groupId>com.vaadin</groupId>
        <!-- Replace artifactId with vaadin-core to use only free components -->
        <artifactId>vaadin</artifactId>
        <exclusions>
            <!-- Webjars are only needed when running in Vaadin 13 compatibility mode -->
            <exclusion>
                <groupId>com.vaadin.webjar</groupId>
                <artifactId>*</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.webjars.bowergithub.insites</groupId>
                <artifactId>*</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.webjars.bowergithub.polymer</groupId>
                <artifactId>*</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.webjars.bowergithub.polymerelements</groupId>
                <artifactId>*</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.webjars.bowergithub.vaadin</groupId>
                <artifactId>*</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.webjars.bowergithub.webcomponents</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-spring-boot-starter</artifactId>
        <exclusions>
            <!-- Excluding so that webjars are not included. -->
            <exclusion><groupId>com.vaadin</groupId>
                <artifactId>vaadin-core</artifactId></exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-testbench</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <defaultGoal>spring-boot:run</defaultGoal>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.1.7.RELEASE</version>

            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!--
            Take care of synchronizing java dependencies and imports in
            package.json and main.js files.
            It also creates webpack.config.js if not exists yet.
        -->
        <plugin>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-maven-plugin</artifactId>
            <version>${vaadin.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>build-frontend</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<profiles>
    <profile>
        <!-- Production mode is activated using -Pproduction -->
        <id>production</id>
        <properties>
            <vaadin.productionMode>true</vaadin.productionMode>
        </properties>

        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>flow-server-production-mode</artifactId>
            </dependency>
        </dependencies>

        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <jvmArguments>-Dvaadin.productionMode</jvmArguments>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>com.vaadin</groupId>
                    <artifactId>vaadin-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>build-frontend</goal>
                            </goals>
                            <phase>compile</phase>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

I see that the folder npm_modules/@vaadin/flow-frontend is empty but
the missing js-files are in the fatjar under META-INF/resources/frontend:

  • contextMenuConnector-es6.js
  • gridConnector.js
  • contextMenuConnector.js
  • flow-component-renderer.js
  • gridConnector-es6.js
  • vaadin-grid-flow-selection-column.js

Removing

 npm_modules
 package.json
 package-lock.json
 package.json
 webpack.config.js
 webpack.generated.js

didn’t help. It always runs in the same error and cannot build the frontend.

I discovered that target/frontend/generated-flow-imports.js references those missing js modules under npm_modules/@vaadin/flow-frontend/:

...
import '@vaadin/flow-frontend/flow-component-renderer.js';
import '@vaadin/flow-frontend/gridConnector-es6.js';
import '@vaadin/flow-frontend/vaadin-grid-flow-selection-column.js';
import '@vaadin/flow-frontend/contextMenuConnector-es6.js';
...
import '@vaadin/flow-frontend/gridConnector.js';
import '@vaadin/flow-frontend/contextMenuConnector.js';

Shouldn’t it be:

...
import 'frontend://flow-component-renderer.js';
import 'frontend://gridConnector-es6.js';
import 'frontend://vaadin-grid-flow-selection-column.js';
import 'frontend://contextMenuConnector-es6.js';
...
import 'frontend://gridConnector.js';
import 'frontend://contextMenuConnector.js';

Then it would reference to the frontend folder under META-INF/resources/frontend according to
https://vaadin.com/forum/thread/17063188/how-to-inline-js-from-webjar-in-a-spring-boot-app

I discovered https://github.com/vaadin/flow/issues/5632. There was once an attempt to make it working.

I found a workaround:
I copied all files from META-INF/resources/frontend to npm_modules/@vaadin/flow-frontend/.
That works.

Changing target/frontend/generated-flow-imports.js does not work because it is overwritten with every restart.

When you run a fat jar you are running the application in a web server that don’t have access to the FS in fact.
So you should not use dev mode.
But any issue related to node_modules may happen only if you are running the app in dev mode.
Since you have those issues you are using dev mode.

To be able to run application on external web server you should build the app in production mode.
In this case the resulting app will contain a bundle file compiled from project’s frontend resources and it doesn’t need to run any node/npm again and no need to access node_modules folder or any other FS folder.
There can’t be just any error like you have: all errors (if any) will be discovered during build time.

So please just build your app in production mode using the production profile and then execute your app in production mode (e.g. providing vaadin.productionMode property or productionMode init parameter).

Updated info: I’m not sure about need to run jar in dev mode but nowadays it’s possible.
The info included into jar should contain absolute paths to the FS and dev mode should work with jar as well.
But that’s available in the latest release. Please try it.