Create a war for my webapp (Spring + Vue and NuxtJS) - spring

I am trying to build my web application into a war that must contain both my frontend (written in Vue + NuxtJS) and my backend (Spring).
The architecture of my app is the following:
|
- src
|
-main
|
- frontend
|
- dist
|
- components
|
- pages
|
...
|
...
|
- webapp
|
- WEB-INF
| my backend files
I am trying to use this frontend-maven-plugin.
This is my build configuration in the pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<warName>MyApp</warName>
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
</configuration>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.12.0</version>
<executions>
<execution>
<id>Install node and yarn</id>
<goals>
<goal>install-node-and-yarn</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<nodeVersion>v15.13.0</nodeVersion>
<yarnVersion>v1.22.10</yarnVersion>
</configuration>
</execution>
<execution>
<id>yarn install</id>
<goals>
<goal>yarn</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>Copy Vue frontend into Spring Boot target static folder</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target/classes/static</outputDirectory>
<resources>
<resource>
<directory>src/main/frontend/dist</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
After running mvn clean package, I checked my target folder and I noticed that my frontend files are copied from src/main/frontend/dist into target/MyApp/WEB-INF/classes/static.
However, when I deploy my war in Tomcat, I am not able to visualize my frontend pages.
If I understood correctly, I should see my main index.html file at localhost:8080/MyApp. This doesn't happen, and I can't see any of the other pages as well.
The backend works as expected (at localhost:8080/MyApp/api/myApi).
I am clearly doing something wrong. Can anyone help me spot the problem? Thank you.

Related

Springboot failsafe multi-module integration test

I have to run integration-test with fail safe and my project is a multi module project, with one module for selenium test and another one with the actual web app.
I want to run the web app then the test over this app and then stopping this app and getting the report of the integration tests.
In order to do this I used this, inside the pom of the selenium test module :
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>reserve-tomcat-port</id>
<goals>
<goal>reserve-network-port</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<portNames>
<portName>tomcat.http.port</portName>
</portNames>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.9.RELEASE</version>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
<configuration>
<includes>
<include>
<groupId>com.example</groupId>
<artifactId>web-app</artifactId>
</include>
</includes>
<mainClass>com.example.App</mainClass>
<arguments>
<argument>--server.port=${tomcat.http.port}</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>post-integration-test</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<test.server.port>${tomcat.http.port}</test.server.port>
</systemPropertyVariables>
</configuration>
</plugin>
The error I get is that the main class is not found :
java.lang.ClassNotFoundException: App
It feels like inside the selenium test I can't get to the webapp classPath, It seems like its trying to run the selenium test main instead of the webapp's one

Getting 0% coverage report using jacoco-gwt-maven-plugin?

I am trying to get coverage report of GWTTestCases using jacoco-gwt-maven-plugin.
I followed the below link:
https://github.com/errai/jacoco-gwt-maven-plugin
pom.xml
<build>
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>2.7.0</version>
<executions>
<execution>
<configuration>
<extraJvmArgs>-Xmx512m</extraJvmArgs>
</configuration>
<goals>
<goal>compile</goal>
<goal>generateAsync</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jboss.errai</groupId>
<artifactId>jacoco-gwt-maven-plugin</artifactId>
<version>0.5.4.201202141554</version>
<configuration>
<snapshotDirectory>${project.build.directory}/test-classes</snapshotDirectory>
<propertyName>jacocoArgs</propertyName>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.6</version>
<configuration>
<argLine>${jacocoArgs}</argLine>
</configuration>
</plugin>
</plugins>
</build>
When I run the Project using commands as,
mvn clean
mvn install
Inside target folder I can see,
site Directory --> jacoco Directory --> index.html file gets created.
When I open index.html, code coverage is 0%.
What I am doing wrong, Please help.
I got some help from link below, but still struggling to get complete report
How do I setup coverage with GWT, maven, jacoco?
In target\test-classes folder I can see only GwtTestCovergeSample.class file from test package, does client and server folder class files should also be present here?

Move a config file into etc folder(of Karaf) when a (Maven)bundle is deployed

I want to move a cfg file into the etc folder of karaf whenever a bundle is deployed.
the cfg file is in under src/main/resource .i tried the following in the pom but its not working.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>deploy</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.test.properties</echo>
<copy file="src/main/resources/test.cfg" tofile="${env.KARAF_HOME}/etc/test.cfg"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
How can i do it ?
One of the solution could be:
- put your test.cfg file in a more specific folder. (eg: src/main/resources/cfg)
- use the maven resources plugin
This is a working example based on the maven phase generate-resources (replace that phase by deploy in your case):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-to-karaf</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/main/resources/cfg</directory>
<filtering>true</filtering>
</resource>
</resources>
<outputDirectory>D:\apache-karaf-3.0.1\etc\</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

How to add WSDL, XSD (and possibly other files) to WAR

I have a very simple pom.xml that generates a fully working web service if deployed locally (Tomcat 7). This is its <build> section:
<build>
<finalName>${artifact.id}</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>generate-sources</id>
<configuration>
<sourceRoot>${basedir}/target/generated/src/main/java</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>${basedir}/src/main/wsdl/mywebservice.wsdl</wsdl>
<extraargs>
<extraarg>-impl</extraarg>
<extraarg>-verbose</extraarg>
</extraargs>
<wsdlLocation>${basedir}/src/main/wsdl/mywebservice.wsdl</wsdlLocation>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/target/generated/src/main/java</source>
</sources>
</configuration>
</execution>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${basedir}/src/main/wsdl/mywebservice.wsdl</file>
<type>wsdl</type>
</artifact>
<artifact>
<file>${basedir}/src/main/xsd/myschema.xsd</file>
<type>xsd</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
The reason it only works if deployed locally and not when deployed to a remote server is because the remote server cannot find the .wsdl and the .xsd files in development source directories ${basedir}/target/generated/src/main/ and they are also nowhere to be found in the WAR file.
Apparently, I am missing something in my pom.xml that would make Maven add or attach those files to the WAR.
I tried the attach-artifact goal (as quoted above) but it only copies the files to my local (development) .m2 repository, not to the WAR file.
How do I add or attach files to the actual .war file to be deployed?
I solved the mystery.
Posting the answer here in case another newbie to Maven (plus CXF?) encounters this problem:
It turns out that the attach-artifact execution is totally unneeded and is a shot in the wrong direction.
All I had to do was to add at the top of the <build> section, just before <plugins> the following:
<resources>
<resource>
<directory>src/main/wsdl</directory>
</resource>
<resource>
<directory>src/main/xsd</directory>
</resource>
</resources>
That's all. Maven then automagically places all files in those directories in WEB-INF/classes/.

how to deploy web app to jetty

I have an web app(actually a gwt app), and i want to deploy it to Jetty server for selenium testing, i used maven, maven-jetty-plugin, gwt-maven-plugin and selenium-maven-plugin, i finally got jetty and selenium sever running but the selenium tests fail because of the famous 404 eror:
com.thoughtworks.selenium.SeleniumException: XHR ERROR: URL = http://127.0.0.1:8080/index.html Response_Code = 404 Error_Message = Not Found
i m not sure if my jetty configuration is correct since i m kind of new to it, here is it(maven-jetty-plugin):
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<configuration>
<contextPath>/sample-console</contextPath>
<webAppSourceDirectory>${basedir}/target/${project.artifactId}-${project.version}</webAppSourceDirectory>
<webXml>${basedir}/target/${project.artifactId}-${project.version}/WEB-INF/web.xml</webXml>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integraion-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
when i ran mvn clean install, i can see the output from command window:
[INFO] Configuring Jetty for project: DYI sample Console
[INFO] Webapp source directory = /Users/dyi/Documents/workspace/sample/console/target/sample-console-0.1-SNAPSHOT
[INFO] Reload Mechanic: automatic
[INFO] Classes = /Users/dyi/Documents/workspace/sample/console/target/classes
log4j:WARN No appenders could be found for logger (org.mortbay.log).
log4j:WARN Please initialize the log4j system properly.
[INFO] Context path = /sample-console
[INFO] Tmp directory = determined at runtime
[INFO] Web defaults = org/mortbay/jetty/webapp/webdefault.xml
[INFO] Web overrides = none
[INFO] web.xml file = /Users/dyi/Documents/workspace/sample/console/target/sample-console-0.1-SNAPSHOT/WEB-INF/web.xml
[INFO] Webapp directory = /Users/dyi/Documents/workspace/sample/console/target/sample-console-0.1-SNAPSHOT
[INFO] Starting jetty 6.1.22 ...
[INFO] Started Jetty Server
[INFO] [selenium:start-server {execution: start}]
and my folder structure looks like this:
--sample/
-- console/
-- src/
-- target/
-- classes/
-- sample-console-0.1-SNAPSHOT/
-- css/
-- images/
-- img/
-- index.html
-- js/
-- META-INF/
-- security/
-- test.html
-- WEB-INF/
-- classes/
-- lib/
-- web.xml
the thing i don't understand is i can see the index.html page is right there in the folder 'sample-console-0.1-SNAPSHOT', why it cannot find it? is that because i set the 'contextPath' wrong? i tried setting it to '/', then i got 503 service not available error. anyone can help? much thanks!!
It sounds like you're trying to run the app out of the webapp directory, which won't work in a GWT app. Try setting the goal in your jetty maven plugin to be run-war instead of run, like this:
<modelVersion>4.0.0</modelVersion>
<groupId>org.proj.web</groupId>
<artifactId>gwtapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>gwtapp</name>
<properties>
...
</properties>
<dependencies>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<excludes>
<exclude>**/integration/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/integration/**
</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
<!-- Selenium and integration testing support -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>start-server</goal>
</goals>
<configuration>
<background>true</background>
</configuration>
</execution>
<execution>
<id>stop</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop-server</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.2.2.v20101205</version>
<configuration>
<webAppConfig>
<contextPath>/${project.name}</contextPath>
</webAppConfig>
<scanIntervalSeconds>5</scanIntervalSeconds>
<stopPort>9966</stopPort>
<stopKey>foo</stopKey>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>9080</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-war</goal>
</goals>
<configuration>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>2.1.0-1</version>
<configuration>
<logLevel>INFO</logLevel>
<style>PRETTY</style>
<runTarget>/gwtapp.html</runTarget>
<hostedWebapp>${project.build.directory}/${project.build.finalName}</hostedWebapp>
<modules>
<module>${project.groupId}.gwtapp</module>
</modules>
<copyWebapp>true</copyWebapp>
</configuration>
<executions>
<execution>
<id>gwtcompile</id>
<phase>prepare-package</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
</build>
This will cause the compile and gwt-compile to run., assuming you have those configured correctly.
If your config looks like this, you can just run mvn clean integration-tests and your script will:
Compile your code
gwt:compile your code
Create the war file
start jetty and deploy the war file to jetty
Start the Selenium server
try to run any tests in any subdirectory of the integration package in your test directory.

Resources