How to package ReactJs app with Spring Boot Webflux - java

I am wondering is there any way to combine REST API and UI of Spring boot Webflux application. I use React for the UI part.
In normal Spring MVC application I can use frontend-maven-plugin along with maven-resources-plugin to build and copy the static resources to target directory. Something like this:
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<installDirectory>target</installDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v10.15.0</nodeVersion>
<npmVersion>6.4.1</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>webpack build dev</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>run webpack:build</arguments>
<npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>position-react-build</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<outputDirectory>${project.build.outputDirectory}/static</outputDirectory>
<resources>
<resource>
<directory>${frontendSrcDir}/build</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Everything works fine. But it is maybe because I use embedded Tomcat Server (default for Spring Boot with Spring MVC).
For the second approach, I would like to use Spring Boot Webflux. By default the application will run on Netty. I tried to apply the same maven configuration. But when the application is started it does not handlethe ReactJs application.

Related

Cannot load static file in tomcat

Firstly, I build the vuejs project in springboot by adding the following plugin:
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${frontend-maven-plugin.version}</version>
<configuration>
<workingDirectory>src/main/frontend</workingDirectory>
</configuration>
<executions>
<execution>
<id>install node and yarn</id>
<goals>
<goal>install-node-and-yarn</goal>
</goals>
<configuration>
<nodeVersion>${nodejs.version}</nodeVersion>
<yarnVersion>v1.22.4</yarnVersion>
</configuration>
</execution>
<execution>
<id>yarn install</id>
<goals>
<goal>yarn</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>yarn build</id>
<goals>
<goal>yarn</goal>
</goals>
<configuration>
<arguments>build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-frontend</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target/classes/resources/</outputDirectory>
<overwrite>true</overwrite>
<resources>
<resource>
<directory>src/main/frontend/dist</directory>
<includes>
<include>static/</include>
<include>index.html</include>
<include>favicon.ico</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
I have successfully built and run it when building into a jar file.
But now I want to run it with tomcat so I change the build format to war file but when running it can't load static file.
I think it's due to context path:
When run in tomcat: http://localhost:8080/report_system-1.0/
When run jar file: http://localhost:8080
But I don't know how to fix that.
You need to set publicPath when building the app for different environments. Something like
module.exports = {
publicPath: process.env.NODE_ENV === 'production'
? '/report_system-1.0/'
: '/'
}

How to serve React built files to Spring Boot application

I have a Spring Boot application that has multiple APIs and a standart React application that was created using the create-react-app command. What I want to do is to build the React app using
npm run build
and serve the built files from the Spring Boot application.
Here is my project structure:
Right now, during development I set a proxy to the frontend/package.json in order to send all requests to the backend server but need the same behaviour in production. How do I achieve that?
package.json:
"proxy": "http://localhost:8082/gui",
I also need everything packaged together in my war so in my pom.xml I use a couple of plugins to build the React app and copy the built files to the Spring Boot target folder:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<workingDirectory>frontend</workingDirectory>
<installDirectory>target</installDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v12.13.1</nodeVersion>
<npmVersion>6.12.1</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<configuration>
<target>
<copy todir="${project.build.directory}/classes/public">
<fileset dir="${project.basedir}/frontend/build" />
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
An important information is that the Spring Boot app has a custom context path:
server.servlet.context-path=/gui
so the homepage should be served from localhost:8080/gui.
I need to know how to serve the frontend from my Spring Boot server. Thank you in advance!

How to make Tomcat run a Spring/React app (Showing 404 not found)?

I have created an app with Spring Boot and React. It works perfectly fine if I run via Run As -> Spring Boot App. But when I make a war package with Maven (Clean Package) it shows 404 not found when I deploy it via Tomcat manager. My build plugins:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${frontend-maven-plugin.version}</version>
<configuration>
<nodeVersion>${node.version}</nodeVersion>
<npmVersion>${npm.version}</npmVersion>
<workingDirectory>${frontend-src-dir}</workingDirectory>
<installDirectory>${project.build.directory}</installDirectory>
</configuration>
<executions>
<execution>
<id>install-frontend-tools</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<nodeVersion>${node.version}</nodeVersion>
<npmVersion>${npm.version}</npmVersion>
</configuration>
</execution>
<execution>
<id>npm-install</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>build-frontend</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>position-react-build</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<outputDirectory>${project.build.outputDirectory}/static</outputDirectory>
<resources>
<resource>
<directory>${frontend-src-dir}/build</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I have a guess it has something to do with port 3000 in React (though I proxied in json package). My frontend is under src/main/frontend. in main I use
#SpringBootApplication
public class MapRunnerApp extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MapRunnerApp.class);
}
public static void main(String[] args) {
SpringApplication.run(MapRunnerApp.class, args);
}
}

Maven wildfly-maven-plugin custom standalone.xml

How can I use a custom standalone.xml when running wildfly-maven-plugin:start (not just adding datasources, drivers,...)?
Using wildfly-maven-plugin-1.0.2.Final:
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.0.2.Final</version>
...
<execution>
<id>pre-integration-phase</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
<goal>deploy</goal>
</goals>
</execution>
...
I have tried using maven-resources-plugin for copying resources (standalone.xml) in wildfly configuration folder, but it seems that wildfly:start overwrites and deletes every (other) file in Wildfly (configuration) directory.
This task is used for jenkins integration testing, thats why I need jboss running just when testing is in progress.
You can unpack the WildFly installation and then set jbossHome configuration element in wildfly-maven-plugin.
Example configuration:
<version.wildfly>8.2.0.Final</version.wildfly>
<jboss.home>${project.build.directory}/wildfly-${version.wildfly}</jboss.home>
<server.config>standalone.xml</server.config>
<!-- Unpack the distribution -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-wildfly</id>
<phase>generate-sources</phase>
<goals>
<goal>unpack</goal>
</goals>
<inherited>false</inherited>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-dist</artifactId>
<version>${version.wildfly}</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<!-- Copy server configuration -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${version.plugin.resources}</version>
<executions>
<execution>
<id>copy-standalone-xml</id>
<phase>generate-test-sources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${jboss.home}/standalone/configuration</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- WildFly plugin to deploy war -->
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${version.wildfly.maven.plugin}</version>
<configuration>
<jbossHome>${jboss.home}</jbossHome>
<serverConfig>${server.config}</serverConfig>
</configuration>
<executions>
<execution>
<id>pre-integration-phase</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>

Jetty doesn't start in pre-integration-test phase (Maven)

I'm trying to use Maven Failsafe Plugin to run my functional/integration tests, according to this guide: http://docs.codehaus.org/display/MAVENUSER/Maven+and+Integration+Testing, chapter Using the Maven Failsafe Plugin to run Integration Tests
However, jetty doesn't start in the pre-integration-test phase and thus all the tests fail. Is there any problem in the following POM configuration:
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.7.1</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.7</version>
<configuration>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8080</port>
<maxIdleTime>3600000</maxIdleTime>
</connector>
</connectors>
<contextPath>/</contextPath>
<scanIntervalSeconds>3</scanIntervalSeconds>
<scanTargetPatterns>
<scanTargetPattern>
<directory>src/main/webapp/WEB-INF</directory>
<excludes>
<exclude>**/*.jsp</exclude>
<exclude>**/*.html</exclude>
</excludes>
<includes>
<include>**/*.page</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</scanTargetPattern>
</scanTargetPatterns>
<execution>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-exploded</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</execution>
</configuration>
</plugin>
I run the integration tests by mvn verify
I know why - first I put the execution tags inside another execution tag (instead of executions) and then this executions block shouldn't be inside configuration tag, but outside of it, right inside the plugin tag.

Categories

Resources