Simple Camel application doesn't work with the Quartz component - java

I'm trying to run a simple Camel route using Quartz component to schedule a job. In this example is like an hello word every minute.
This is the example route:
public void configure() throws Exception {
from("quartz://myname?cron=0+ *+ *+ ?+ *+ *")
.to("log:hello");
}
When I run the application I get the following error:
An attempt was made to call a method that does not exist. The attempt was made from
the following location:
org.apache.camel.component.quartz.QuartzComponent.createEndpoint(QuartzComponent.java:150)
The following method did not exist:
'org.quartz.Trigger org.quartz.Scheduler.getTrigger(java.lang.String, java.lang.String)'
The method's class, org.quartz.Scheduler, is available from the following locations:
jar:file:/C:/Users/andre/.m2/repository/org/quartz-scheduler/quartz/2.3.2/quartz-2.3.2.jar!/org/quartz/Scheduler.class
The class hierarchy was loaded from the following locations:
org.quartz.Scheduler: file:/C:/Users/andre/.m2/repository/org/quartz-scheduler/quartz/2.3.2/quartz-2.3.2.jar
Action:
Correct the classpath of your application so that it contains a single, compatible
version of org.quartz.Scheduler
But actually I don't get how I should correct the classpath of my application.
This is the pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.mycompany</groupId>
<artifactId>camel-ose-springboot-xml</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Fabric8 :: Quickstarts :: Spring-Boot :: Camel XML</name>
<description>Spring Boot example running a Camel route defined in XML</description>
<properties>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<docker.image.version>1.9</docker.image.version>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<fuse.version>7.11.0.fuse-sb2-7_11_0-00028-redhat-00001</fuse.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.redhat-fuse</groupId>
<artifactId>fuse-springboot-bom</artifactId>
<version>7.11.0.fuse-sb2-7_11_0-00028-redhat-00001</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-quartz</artifactId>
<!-- use the same version as your Camel core version -->
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<repositories>
<repository>
<id>red-hat-ga-repository</id>
<url>https://maven.repository.redhat.com/ga</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>red-hat-ga-repository</id>
<url>https://maven.repository.redhat.com/ga</url>
</pluginRepository>
</pluginRepositories>
<build>
<defaultGoal>spring-boot:run</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jboss.redhat-fuse</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${fuse.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>openshift</id>
<build>
<plugins>
<plugin>
<groupId>org.jboss.redhat-fuse</groupId>
<artifactId>openshift-maven-plugin</artifactId>
<version>${fuse.version}</version>
<executions>
<execution>
<goals>
<goal>resource</goal>
<goal>build</goal>
<goal>apply</goal>
</goals>
</execution>
</executions>
<configuration>
<enricher>
<excludes>
<exclude>fmp-openshift-route</exclude>
</excludes>
</enricher>
<resources>
<labels>
<pod>
<property>
<name>com.company</name>
<value>Red_Hat</value>
</property>
<property>
<name>rht.prod_name</name>
<value>Red_Hat_Integration</value>
</property>
<property>
<name>rht.prod_ver</name>
<value>7.9</value>
</property>
<property>
<name>rht.comp</name>
<value>spring-boot-camel-xml</value>
</property>
<property>
<name>rht.comp_ver</name>
<value>${fuse.bom.version}</value>
</property>
</pod>
</labels>
</resources>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jkube.generator.from>registry.redhat.io/fuse7/fuse-java-openshift-rhel8:${docker.image.version}</jkube.generator.from>
</properties>
</profile>
<profile>
<id>java11</id>
<activation>
<jdk>[11,)</jdk>
</activation>
<properties>
<jkube.generator.from>registry.redhat.io/fuse7/fuse-java-openshift-jdk11-rhel8:${docker.image.version}</jkube.generator.from>
</properties>
</profile>
<profile>
<id>java17-build</id>
<activation>
<jdk>[17,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.5</version>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

There is a conflict in Quartz version somewhere, indeed the version of camel-quartz that you use (2.23.2.fuse-7_11_0-00037-redhat-00001), expects Quartz v1 while you end up with Quartz v2 which causes the issue.
You have two ways to fix your problem:
Keep on using Quartz v1
In that case, you will have to force the version of Quartz in your pom file by adding:
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
Switch to Quartz v2
In that case, you will have to change the camel-quartz artifact for camel-quartz2-starter as next:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-quartz2-starter</artifactId>
<!-- use the same version as your Camel core version -->
</dependency>
Then change the URI of the Quartz endpoint by specifying quartz2 instead of quartz as next:
public void configure() throws Exception {
from("quartz2://myname?cron=0+ *+ *+ ?+ *+ *")
.to("log:hello");
}
The choice is up to you, but I would definitely recommend switching to Quartz v2.

Related

Fail to generate allure-results directory based on JUnit 4

I failed to generate the directory allure-results in my project. I have tried many methods from google(create src/test/resources/allure.properties, set <resultsDirectory>${project.build.directory}/allure-results</resultsDirectory> in pom.xml, etc.), but all setting seems not to take effect. I also failed to redirect the result to other directories. It always said "[ERROR] Directory <project_path>/target/allure-results not found".
My command to generate report is
mvn clean test -Dtest=aaaTestClass io.qameta.allure:allure-maven:report
My pom.xml is like:
<?xml version="1.0" encoding="UTF-8"?>
<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>***</groupId>
<artifactId>***</artifactId>
<version>***</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>
<properties>
...
<aspectj.version>1.9.9</aspectj.version>
<allure.version>2.13.9</allure.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
...
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-engine</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8</version>
<scope>test</scope>
</dependency>
...
<!-- test report dependencies -->
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit4</artifactId>
<version>${allure.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<configuration>
<classifier>runnable</classifier>
<attach>false</attach>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<!--
<version>${maven.jar.version}</version>
-->
<version>2.4</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-surefire-plugin</artifactId>-->
<!-- <version>2.19.1</version>-->
<!-- <configuration>-->
<!-- <testFailureIgnore>true</testFailureIgnore>-->
<!-- <argLine>-->
<!-- -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"-->
<!-- </argLine>-->
<!-- <systemProperties>-->
<!-- <property>-->
<!-- <name>allure.results.directory</name>-->
<!-- <value>${project.build.directory}/allure-results</value>-->
<!-- </property>-->
<!-- </systemProperties>-->
<!-- <properties>-->
<!-- <property>-->
<!-- <name>listener</name>-->
<!-- <value>io.qameta.allure.junit4.AllureJunit4</value>-->
<!-- </property>-->
<!-- </properties>-->
<!-- </configuration>-->
<!-- <dependencies>-->
<!-- <dependency>-->
<!-- <groupId>org.aspectj</groupId>-->
<!-- <artifactId>aspectjweaver</artifactId>-->
<!-- <version>${aspectj.version}</version>-->
<!-- </dependency>-->
<!-- </dependencies>-->
<!-- </plugin>-->
<!-- <plugin>-->
<!-- <groupId>io.qameta.allure</groupId>-->
<!-- <artifactId>allure-maven</artifactId>-->
<!-- <version>2.10.0</version>-->
<!-- <configuration>-->
<!-- <reportVersion>${allure.version}</reportVersion>-->
<!-- <resultsDirectory>${project.build.directory}/allure-results</resultsDirectory>-->
<!-- <allureDownloadUrl>-->
<!-- https://***/io/qameta/allure/allure-commandline/2.18.1/allure-commandline-2.18.1.zip-->
<!-- </allureDownloadUrl>-->
<!-- </configuration>-->
<!-- </plugin>-->
</plugins>
</build>
<profiles>
<profile>
<id>aaa</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<includes>
<include>**/aaatest/*Test</include>
</includes>
<testFailureIgnore>true</testFailureIgnore>
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
</argLine>
<properties>
<property>
<name>listener</name>
<value>io.qameta.allure.junit4.AllureJunit4</value>
</property>
</properties>
<systemPropertyVariables>
<allure.results.directory>${project.build.directory}/allure-results</allure.results.directory>
</systemPropertyVariables>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-maven</artifactId>
<version>2.11.2</version>
<configuration>
<reportVersion>${allure.version}</reportVersion>
<resultsDirectory>${project.build.directory}/allure-results</resultsDirectory>
<allureDownloadUrl>
https://***/io/qameta/allure/allure-commandline/2.18.1/allure-commandline-2.18.1.zip
</allureDownloadUrl>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>bbb</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<includes>
<include>**/bbbtest/*Test</include>
</includes>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
The profile setup seems to be a mixture of Junit4 and JUnit5 configuration for Allure reports. Clean this up first, suggest the below for the first profile based on Junit4:
<profiles>
<profile>
<id>aaa</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<includes>
<include>**/aaatest/*Test</include>
</includes>
<testFailureIgnore>true</testFailureIgnore>
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
</argLine>
<properties>
<property>
<name>listener</name>
<value>io.qameta.allure.junit4.AllureJunit4</value>
</property>
</properties>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The configuration should generate the results in the default location of <project_path>/target/allure-results
There also is an issue with the mvn command. The first part of the command is mvn clean it will ensure that any existing target directory is removed before the next part of the command, in this case test.
The command as noted above is a two part command, the second effectively being mvn io.qameta.allure:allure-maven:report.
In summary, both mvn commands are being executed at the same time:
one that removes the target directory(mvn clean) or awaiting to create it (mvn test)
second that wants to generate a report in the target directory that does not exist or awaiting to be created by the above
Also to note that the second part of the command could also cause an exception even if the target directory did exist. As no allure results would have been created as the mvn test still needs to execute a test result / complete the test execution suite
The requirement here is a mvn cli command that will run both commands consequentially, use the && syntax like this:
mvn clean test -Dtest=aaaTestClass && mvn allure:report
This will run the test suite to completion and then generate the report
The report should generated in the following location:
<project_path>/target/site/allure-maven/index.html
In my project, I just add this dependency to fix this issue:
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit4</artifactId>
<version>3.0.0-M7</version>
</dependency>

SpringBoot AWS Lambda application deployment issue-Class not found: com.abc.test.TestServiceHandler

Created a Spring boot application using Java 11 and trying to deploy in AWS Lambda.
Encountering the following error in AWS Lambda. I see it is an issue with the way I am packaging the jar.
Any help is greatly appreciated.
{
"errorMessage": "Class not found: com.abc.test.TestServiceHandler",
"errorType": "java.lang.ClassNotFoundException"
}
I am building the jar using the following maven commands:
mvn clean install
mvn package -P shade
Below is my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.abc.test.store</groupId>
<artifactId>test-service</artifactId>
<version>${revision}</version>
<packaging>jar</packaging>
<name>Test-service</name>
<description>Test Service</description>
<properties>
<revision>local-SNAPSHOT</revision>
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring.boot.parent.version>2.6.4</spring.boot.parent.version>
<commons.lang3.version>3.12.0</commons.lang3.version>
<commons.collections.version>4.4</commons.collections.version> <aws.sdk.secretsmanager.version>1.12.150</aws.sdk.secretsmanager.version>
<jacoco.version>0.8.7</jacoco.version>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws.serverless</groupId>
<artifactId>aws-serverless-java-container-spring</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<version>${aws.sdk.secretsmanager.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons.lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons.collections.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.coverage.exclusions>
**/test/model/**/*,
</sonar.coverage.exclusions>
</properties>
</profile>
<profile>
<id>sbmp</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>shade</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes> <exclude>org.apache.tomcat.embed:*</exclude>
<exclude>*:spring-boot-devtools</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Please check following sample, save as src\main\java\com\abc\test\TestServiceHandler.java
package com.abc.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
public class TestServiceHandler implements RequestStreamHandler {
#Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
LambdaLogger logger = context.getLogger();
logger.log("Started up");
return;
}
}
Compile, and upload jar as you mentioned in question.
In aws lambda console code tab, under Runtime settings, Handler, edit it to com.abc.test.TestServiceHandler to call lambda.
Point from here says use RequestStreamHandler instead of RequestHandler which sample from doc used. It looks like importent.
Turns out my issue is related to my local machine (mac) that I am building my JAR from.From what I have debugged,the architecture used to build the jar is causing issues when deployed on Lambda.
Building the jar from windows machine did not cause any issues.
add this in your pom, you are missing thin layout plugin
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot.experimental/spring-boot-thin-layout -->
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>1.0.28.RELEASE</version>
</dependency>
</dependencies>
</plugin>

Vaadin + Spring Boot Production mode build with a runtime error: Failed to determine 'npm' tool

UPDATE ON THE SOLUTION
This bug seems to have been the cause of the problem: https://github.com/vaadin/flow/issues/6657
While the fix is rolled out the marked answer can be used as a workaround
Background
I'm in the process of creating a dockerized, Spring Boot + Vaadin flow based portal for my IoT project.
Problem
The portal works well running from my machine in Vaadin's development mode, with npm installed, but I can't seem to get the right setup for creating a lightweight deployment jar that already contains all the generated front end components.
When I'm running the service in a Docker container, I get the error that it cannot find npm but I assume that it shouldn't be needed for a production deployment
at com.vaadin.flow.server.startup.DevModeInitializer.initDevModeHandler(DevModeInitializer.java:327)
at com.vaadin.flow.spring.VaadinServletContextInitializer$DevModeServletContextListener.contextInitialized(VaadinServletContextInitializer.java:323)
... 46 common frames omitted
Caused by: com.vaadin.flow.server.ExecutionFailedException:
Failed to determine 'npm' tool.
Please install it either:
- by following the https://nodejs.org/en/download/ guide to install it globally
- or by running the frontend-maven-plugin goal to install it in this project:
$ mvn com.github.eirslett:frontend-maven-plugin:1.7.6:install-node-and-npm -DnodeVersion="v12.13.0"
Docker file without npm:
FROM openjdk:11-jre-slim
ARG PROJECT
ARG SERVICE_PORT
ARG JAR_FILE
EXPOSE ${SERVICE_PORT}
RUN mkdir /${PROJECT}
WORKDIR /${PROJECT}
ADD target/${JAR_FILE} ./app.jar
CMD ["java","-jar","app.jar"]
pom.xml (updated!)
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tlvlp</groupId>
<artifactId>iot-portal</artifactId>
<version>0.0.2</version>
<name>iot-portal</name>
<description>tlvlp IoT server portal</description>
<properties>
<java.version>11</java.version>
<vaadin.version>14.0.12</vaadin.version>
<dockerfile.maven.version>1.4.13</dockerfile.maven.version>
<flow.server.prod.version>2.0.17</flow.server.prod.version>
<!-- DOCKER IMAGE ARGS -->
<docker.project.repository>tlvlp/iot-portal</docker.project.repository>
<service.port>8600</service.port>
</properties>
<dependencies>
<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>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>${vaadin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>prod</id>
<properties>
<activatedProperties>prod</activatedProperties>
<vaadin.productionMode>true</vaadin.productionMode>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>flow-server-production-mode</artifactId>
<version>${flow.server.prod.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>flow-maven-plugin</artifactId>
<version>${flow.server.prod.version}</version>
<executions>
<execution>
<goals>
<goal>build-frontend</goal>
<goal>copy-production-files</goal>
<goal>package-for-production</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile.maven.version}</version>
<executions>
<execution>
<id>prod</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>${docker.project.repository}</repository>
<tag>${project.version}</tag>
<tag>latest</tag>
<buildArgs>
<PROJECT>${project.groupId}.${project.artifactId}</PROJECT>
<SERVICE_PORT>${service.port}</SERVICE_PORT>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>dev</id>
<properties>
<activatedProperties>dev</activatedProperties>
<vaadin.productionMode>false</vaadin.productionMode>
</properties>
</profile>
</profiles>
</project>
application.properties
spring.profiles.active=#activatedProperties#
application-prod.properties
vaadin.compatibilityMode=false
vaadin.servlet.productionMode=true
I appreciate any guidance :)
All the code can be found on the master branch of the project's public repository: https://github.com/tlvlp/iot-portal
I've finally managed to figure out the solution to the problem.
It was a correct assumption that npm is not required to run the production application.
What wasn't clear from even the official guide that although adding the following property to the prod build profile does populate to the built jar file, but
in itself does NOT trigger Vaadin to run in production mode (at least not together with SpringBoot):
<vaadin.productionMode>true</vaadin.productionMode>
Solution:
What ended up solving the problem is to assign the value of the same parameter in the SpringBoot properties file as well.
Then it started to use the assets generated using npm in build time.
Here is the application.properties file (shared by both dev and prod properties files).
spring.profiles.active=#spring.activatedProperties#
vaadin.productionMode=#vaadin.productionMode#
vaadin.compatibilityMode=false
Here is the complete and updated and working pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tlvlp</groupId>
<artifactId>iot-portal</artifactId>
<version>0.0.2</version>
<name>iot-portal</name>
<description>tlvlp IoT server portal</description>
<properties>
<java.version>11</java.version>
<vaadin.version>14.0.12</vaadin.version>
<dockerfile.maven.version>1.4.13</dockerfile.maven.version>
<flow.server.prod.version>2.0.17</flow.server.prod.version>
<!-- DOCKER IMAGE ARGS -->
<docker.project.repository>tlvlp/iot-portal</docker.project.repository>
<service.port>8600</service.port>
</properties>
<dependencies>
<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>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>${vaadin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>prod</id>
<properties>
<spring.activatedProperties>prod</spring.activatedProperties>
<vaadin.productionMode>true</vaadin.productionMode>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>flow-server-production-mode</artifactId>
<version>${flow.server.prod.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>flow-maven-plugin</artifactId>
<version>${flow.server.prod.version}</version>
<executions>
<execution>
<goals>
<goal>prepare-frontend</goal>
<goal>build-frontend</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile.maven.version}</version>
<executions>
<execution>
<id>prod</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>${docker.project.repository}</repository>
<tag>${project.version}</tag>
<tag>latest</tag>
<buildArgs>
<PROJECT>${project.groupId}.${project.artifactId}</PROJECT>
<SERVICE_PORT>${service.port}</SERVICE_PORT>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>dev</id>
<properties>
<spring.activatedProperties>dev</spring.activatedProperties>
<vaadin.productionMode>false</vaadin.productionMode>
</properties>
</profile>
</profiles>
</project>
As I have recently had the same struggle I have the following solution. The easiest way I found to have Java and Nodejs/NPM was to install it to the java base image. This will not be a small docker image. mvn clean package -Pproduction the vaadin root directory. Then edit the Dockerfile to include the installation like so: https://gitlab.com/snippets/1913782
Then build and run the image. Build time and image size will increase a lot. I would love to see some suggestions or additional progress made on this process. Coming from Vaadin8 into 14 has created numerous headaches with having to learn why non-Java things are broken.

Spring Boot MVC Multi-Module Executeable jar

I have a multimodule project, build with spring boot 1.1.7
The structure is
+ parent
+ import
+ web
+ backend
My Parent Module will include kind of microservices, what I want to manage from my parent (dependencies what all use) and so on. In import/backend there is my batch business logic, in web there is a mvc application, from where I can start batch job.
In Eclipse everything works fine for me, I can start the application from the Application.java file and application works.
Now I wanted to execute that application by executing executable jar file, but I get following error message when try starting from console.
java -jar application.jar
Kein Hauptmanifestattribut in application.jar
The jar is very small only 5kb, I didn't find any jars of 3 party dependencies in jar package.
The Pom of Web-Module is like follows:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>at.company.bbsng</groupId>
<artifactId>bbsng-import</artifactId>
<version>0.1.0-SNAPSHOT</version>
</parent>
<artifactId>bbsng-import-web</artifactId>
<name>bbsng-import-web</name>
<packaging>jar</packaging>
<properties>
<start-class>at.company.bbsng.dataimport.Application</start-class>
</properties>
<dependencies>
<!-- APPLICATION -->
<dependency>
<groupId>at.company.bbsng</groupId>
<artifactId>bbsng-import-backend</artifactId>
<version>${parent.version}</version>
</dependency>
<!-- SPRING ... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Pom of Import Module is:
<project>
<parent>
<groupId>at.company.bbsng</groupId>
<artifactId>bbsng</artifactId>
<version>0.1.0-SNAPSHOT</version>
</parent>
<artifactId>bbsng-import</artifactId>
<name>bbsng-import</name>
<packaging>pom</packaging>
<modules>
<module>backend</module>
<module>web</module>
</modules>
</project>
And Pom of Parent is:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>at.company.bbsng</groupId>
<artifactId>bbsng</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>bbsng</name>
<description>BBS Next Generation Application Prototype</description>
<properties>
<java-version>1.8</java-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<org.springframework.boot-version>1.1.7.RELEASE</org.springframework.boot-version>
</properties>
<modules>
<!-- <module>backend</module> -->
<!-- <module>business</module> -->
<module>import</module>
<!-- <module>infra</module> -->
<!-- <module>log</module> -->
<!-- <module>rest</module> -->
</modules>
<dependencyManagement>
<dependencies>
<!-- SPRING-BOOT ... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<type>pom</type>
<version>${org.springframework.boot-version}</version>
<scope>import</scope>
</dependency>
<!-- JAVAX ... -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- COMMONS ... -->
...
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5</version>
<configuration>
<tagBase>
svn://svn.int.company.at/stmlf-repository/prototype/bbsng/tags
</tagBase>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>external</id>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*custom*</exclude>
<exclude>**/custom/*</exclude>
</excludes>
</resource>
</resources>
</build>
</profile>
</profiles>
</project>
If you need further information please ask. Hope you can help me.
Thank you very much.
Finally I found solution. The magic keyword is repackage, see link http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/maven-plugin/usage.html
So I only need spring-boot-maven-plugin in my web module configured with repackage goal:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Then all dependencies are packed in executeable jar file and is startable from console.
I hope it helps for people who face same issue.

Entity manager lifecycle in Weblogic

I have EAR application written with EJB 3.1, where I'm using JPA 2.0.
Persistance unit is configured to use JTA
<persistence-unit name="JPACommonParameters" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
I've created simple deployment, where in EJB I inject Entity manager just like this
#PersistenceContext(unitName = "JPACommonParameters")
protected EntityManager em;
Using this jpa I called simple query using createNamedQuery.
Application is deployed on WLS 12.1.1.0, managed server.
After first deployment it is working. Everything is fine.
After updating the same application without any change I've receiving ClastCastException as object returned from query is not the same as in application.
result = (ParamDef) em.createNamedQuery("ParamDef.findActiveParamDef").
getSingleResult();
After long investigation I've found, that problem is with classloader. Object returned from entity manager is loaded by different classloader(Classloader used during first deployment) than object ParamDef in bracket I'm casting.
Everything is working fine when I will restart manged wls server.
My question is: How to configure application of wls to initialize entityManger every redeploy of application on server to get it working without restart.
Here is my pom file
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>ofs-direct-services</artifactId>
<groupId>com.oproc.first.app</groupId>
<version>1.1</version>
</parent>
<artifactId>IT-app</artifactId>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<name>IT-app Integ. Tests for app</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<cxf.version>2.2.3</cxf.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.1.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-wls-remote-12.1</artifactId>
<version>1.0.0.Alpha2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core</artifactId>
<version>1.1.5.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.oproc.first.app</groupId>
<artifactId>customer-app-services</artifactId>
<version>1.1</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>com.oproc.first.common.parameters</groupId>
<artifactId>common-parameters-services</artifactId>
<version>1.0</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>com.oproc.first.common.parameters</groupId>
<artifactId>common-parameters-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.oproc.first.common.parameters</groupId>
<artifactId>common-parameters-db</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.oproc.first.common.parameters</groupId>
<artifactId>common-parameters-services</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.oproc.first</groupId>
<artifactId>ejb-tuxedo-connector-ejb</artifactId>
<version>1.0</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>com.oproc.first</groupId>
<artifactId>ejb-tuxedo-connector-client</artifactId>
<version>1.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.oproc.first</groupId>
<artifactId>db4b-db</artifactId>
<version>1.0</version>
<type>jar</type>
</dependency>
</dependencies>
<profiles>
<profile>
<id>no_integration_testing</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<executions>
<execution>
<id>default-test</id>
<configuration>
<excludes>
<exclude>**/*Test.java</exclude>
</excludes>
<skipTests>true</skipTests>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>integration_testing</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArguments>
<endorseddirs>${project.build.directory}/endorsed</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<executions>
<execution>
<id>surefire-it</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skipTests>false</skipTests>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

Categories