gwt-maven-plugin: webapp structure - java

I am using gwt-maven-plugin and eclipse to create GWT+Spring webapp. In the end I want to get .war file to be deployed to some application server(tomcat etc). The problem is that the generated .war file has strange structure.
And then I run in on Tomcat the application doesn't work - SimpleGWT.html page has a link to javascript file which does all the job
<script type="text/javascript" language="javascript" src="SimpleGWT/SimpleGWT.nocache.js"></script>
My guess is that since the SimpleGWT.nocache.js in located inside SimpleGWT folder which is not inside WEB-INF - it is not accessible
Is there any way to alter options of gwt-maven-plugin in order to get normal webapp structure? Here is part of my pom.xml
<!-- GWT Maven Plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>2.6.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<!-- Plugin configuration. There are many available options, see
gwt-maven-plugin documentation at codehaus.org -->
<configuration>
<inplace>true</inplace>
<runTarget>SimpleGWT.html</runTarget>
<hostedWebapp>${webappDirectory}</hostedWebapp>
<i18nMessagesBundle>com.javacodegeeks.gwtspring.client.Messages</i18nMessagesBundle>
</configuration>
</plugin>

Its the issue that is mostly related to access static resources in an HTML page.
You are using relative path that does not have a "/" prefix. That is an absolute path
pointing to the root of the web-server.
In Spring MVC application org.springframework.web.servlet.DispatcherServlet is responsible fore serving all the contents for web apps.
What have you defined as url-pattern for above servlet mapping? Please try with *.html or /* as url-pattern.
For more information read about Unable to load java script files in Jetty webapplication.

Related

Spring Boot - Host JaCoCo coverage as static HTML

I am working with Spring Boot 2.2.5 and Java 8.
I have a Spring Boot webservice that I deploy and run as a linux service using the embedded Tomcat in Spring Boot.
During my Maven build, I generate code coverage metrics using the JaCoCo Maven plugin, and I would like to package and host these static HTML pages when I deploy to my server.
The output for these files is target/site/jacoco/index.html.
I know that you can deploy and host webpages through Spring Boot, but I have never accomplished it, and everything I lookup online seems to be more complicated than what im actually trying to do. The only thing i seem to have gathered so far, is that it need to get the html into my /resources directory.
Does anyone know how I can package all of the JaCoCo generated html pages into my .jar file, and host it on my webserver so that I can access it in a similar fashion to how I access any other API in the app?
I build and deploy the app with Jenkins. So if there is some nifty Jenkins way of doing it through my Jenkins.groovy script, that would be nice too.
I would like to be able to access something like: localhost:8080/my-app-context/coverage
Well, after some more digging and the right google questions, the solution was simpler than I thought. I stumbled across this article from Baeldung.
The goal:
get target/site/jacoco into the src/main/resources/static directory
get target/apidocs into the src/main/resources/static directory
The challenge:
Do it during a Maven/Jenkins build only.
The solution:
Use a Maven plugin to move the files after successful build
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-javadocs</id>
<phase>install</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/src/main/resources/static/apidocs</outputDirectory> <!-- output directory -->
<resources>
<resource>
<directory>${basedir}/target/apidocs</directory> <!-- source directory -->
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-jacoco</id>
<phase>install</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/src/main/resources/static/jacoco</outputDirectory> <!-- output directory -->
<resources>
<resource>
<directory>${basedir}/target/site/jacoco</directory> <!-- source directory -->
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
After putting the above code in my pom.xml, once the app is deployed to my server, both my JaCoCo coverage and my JavaDoc static html pages can be accessed at:
<context-root>/apidocs/index.html
<context-root>/jacoco/index.html
I hope this simplifies it for others looking to do the same.

Spring Boot and React can't load index.html

I'm trying to create a simple web application using create-react-app and Spring Boot, but spring can't find index.html in resources.
React's build folder is copied to target by maven-resources-plugin:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
...
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
...
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resources>
<resource>
<directory>src/main/app/build</directory>
<filtering>true</filtering>
</resource>
</resources>
...
</plugin>
This is my project structure:
Controller:
#Controller
public class BasicController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String index() {
return "index";
}
}
Get request to localhost:8080 returns 404. Could you please point me where am i mistaken.
UPDATE:
Managed to make it working by changing React's build output directory in maven plugin to
${basedir}/src/main/resources/META-INF/resources
and return "index" to return index.html.
Well, it's maybe not the precise answer your question, but I would try example from the docs.
Spring Boot will automatically add static web resources located within any of the following directories:
/META-INF/resources/
/resources/
/static/
/public/
In the case of the Consuming a RESTful Web Service with jQuery guide, we included index.html and hello.js files in the /public/ folder. This means that not only does Spring Boot offer a simple approach to building Java or Groovy apps, you can also use it to easily deploy client-side JavaScript code and test it within a real web server environment!
Just copy the content of CRA build directory to Spring Boot public directory (make sure index.html is at the /public/index.html).
If this works then try to automate the process.
I had the same issue. Spring boot backend with reactjs frontend. I solved it by adding a view resolver (thymeleaf) and copying the generated react build resources to outputDirectory/templates directory like below
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<configuration>
<target>
<copy todir="${project.build.outputDirectory}/templates">
<fileset
dir="${project.basedir}/src/main/javascript/build" />
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

Spring Boot alternative index page

My app uses Spring Boot on the back end and a SPA (Angular) site on the front end. Currently I am serving the index.html page from the webapp folder, which works automatically no configuration needed. Now I integrated a build process for the front end using gulp and all the created sources are "copied" into a build directory. Now I would like to serve the index.html file from the build directory as my main page.
I tried spring.application.index=build/index.htmland some other spring boot settings, but nothing worked. I believe no code is needed from my current code base but if anything is missing let me know.
Is there a way to configure this in the applications.properties file? Do I need to create a controller for the index page? Or is there any other way to change the default behavior?
thanks
Going by the common Spring Boot properties, you should be able to modify this property:
spring.application.index=
Admittedly, I do tend to create a minimal 'home' controller with a #RequestMapping("/") anyway. :)
It's worth noting that the build directory will only be on the classpath if it's under src/main/resources. It's also worth mentioning that the contents of src/main/webapp don't get bundled into the jar automatically. src/main/resources/static is where Spring Boot will look for your static web files. As such, there are a couple of alternatives for you.
Option 1: Configure your Grunt build to output to a directory under src/main/resources/static.
Option 2: Configure your Java build tool to take the Grunt output and put it in your resources directory, so that it's on the classpath. For example, using Maven, the following would move the contents of a directory called build into your src/main/rescources/static.
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes/static</outputDirectory>
<resources>
<resource>
<directory>build</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>

Obfuscating WAR file with Proguard

I want to obfuscate my web application built as WAR archive, as this sensitive application in first time deployed outside our data center. I tried to use the Proguard GUI tool to obfuscate the input war, with all the service jar required for the UI application, with other external dependencies. Though the Proguard runs successfully with some warnings, ex., duplicate definition of library class [javax.servlet.UnavailableException], the output war contains no classes, but has lib with the library jars and web.xml files. Any steps I mess? Any right document on this? I would appreciate if anyone can provide the right document or steps to successfully obfuscate a WAR file with dependent project (a .jar file) and other external jar files (that needs no obfuscation).
you wouldn't obfuscate a war but rather the jars your using. What you can do here is setup your project so the project that makes up the war - configuration xml, WEB-INF content, resources and the web content and servlet definitions and put your java in a library project. Obfuscate the library project and use those obfuscated jars in your web project.
That's what I do, hope it helps.
Protector4j is the best solution to obfuscate the war file, due to graphic user interface its too easy to use and their eclipse plugin is also available.
You will download it from this link
https://doc.protector4j.com/protect-tomcat-web-app
I have done the same way. I used the below url for code obfuscation and i am successful.
http://bratonfire.blogspot.com/2012/01/war-file-obfuscation-using-proguard.html
I created a new folder and redirected output of classes to this folder. But the strange thing is that i am able to see the .java and .class files in the two locations. I am also worried about recreating a war file. can someone mention the clear and detailed steps.
Thanks,
Rahul
We also have the same issue and need to obfuscate all classes packaged in war file.Here is the approach that I followed.
Firstly we need to set order of plugins **(compiler, proguard, war)**declared in pom.xml file as below.
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.14</version>
<configuration>
</configuration>
<executions>
<execution>
<!-- Dont worry about compiler error. For first time, change this value to package so that plugin installs successfully. -->
<phase>process-classes</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<warName>mfs-transaction-management</warName>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
<!-- Exclude your default packages from war packaging. Do not include "**" in double quotes in actual code -->
<packagingExcludes>
WEB-INF/classes/com/package/mypackage1/"**",
WEB-INF/classes/com/package/mypackage2/"**",
</packagingExcludes>
<webResources>
<webResource>
<directory>${project.build.directory}/proguardClasses</directory>
<targetPath>WEB-INF/classes</targetPath>
</webResource>
</webResources>
</configuration>
</plugin>
</plugins>`
Then create a file proguard.conf under the root of your project at the same level where pom.xml is placed.
Add your own configuration regarding proguard in the file and the add below two lines in this file to tell input and output folder to proguard plugin.
You need to set paths according to your project structure in these lines
-injars 'C:\Users\Rajdeep\git\dfs-core\mfs-transaction-management\target\classes'
-outjars 'C:\Users\Rajdeep\git\dfs-core\mfs-transaction-management\target\proguardClasses'
Apart from this you need to install proguard-base manually in maven repository using mvn install command.
Provide your own groupid, artifact and version and made same changes to pom.
It is proguard.jar found under proguard6.0.3\lib folder when you download proguard manually.
I think everything will be ok and now when you run mvn clean package, your war file should included obfuscated class files.
Use Proguard GUI to obfuscate war files.
Once you run proguardgu.bat or proguardgui.sh file from bin folder of your proguard directory. You can select wars by clicking Input/output menu.

How does Maven know where to put the source file under the exploded directory?

I am learning maven , though worked on ant in past.
I have am just trying to figure out what happens when command mvn install or mvn compile is executed. I am mainly
interested how project is built like location of resources to pick for build and where to put them once built
My project source structure is
src > main > java > java files
src > main > resources > reources like spring config atc
src > main > webapp > static files like js,css etc
src > main > webapp > WEB-INF > web.xml and jsp files
Once i give mvn package or mvn clean i see below exploded directory(my focus is on this) with name myProject
alongwith other files lile war, classes etc. Explode structure for myProject is
1) All files from (src > main > webapp) including WEB-INF gets copied under myProject
2) All files from (src > main > resources) gets copied under myProject > WEB-INF/Classes
3) All files from (src > main > java) gets copied under myProject > WEB-INF/Classes
As per my understanding when we give any of mvn install or mvn compile or mvn package
all compile phases gets executed. But My question is how Maven know where to put the source file under exploded directory.
Is it a standard maven follows?
Here is snippet for reference from pom.xml i am using
<artifactId>myProject</artifactId>
<packaging>war</packaging>
<name>myProject</name>
.....
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
<configuration>
<overlays>
</overlays>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jslint</goal>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<aggregations>
</aggregations>
</configuration>
</plugin>
</plugins>
</build>
Maven follow Java standard when it put compiled files in WEB-INF/classes.
Illustration from the The Java EE 6 Tutorial
This directory contains server-side classes: servlets, utility classes, and JavaBeans components. These classes are only visible to the servlet and are not public.
From Java Servlet 3.1 specifications :
10.5 Directory Structure
A special directory exists within the application hierarchy named “
WEB-INF
”. This
directory contains all things related to the application that aren’t in the document
root of the application. Most of the
WEB-INF
node is not part of the public document
tree of the application. Except for static resources and JSPs packaged in the
META-
INF/resources
of a JAR file that resides in the
WEB-INF/lib
directory, no other
files contained in the
WEB-INF
directory may be served di
rectly to a cl
ient by the
container. However, the contents of the
WEB-INF
directory are visible to servlet code
using the
getResource
and
getResourceAsStream
method calls on the
ServletContext
, and may be exposed using the
RequestDispatcher
calls. Hence, if
the Application Developer needs access, from
servlet code, to application specific
configuration information that he does not wish to be exposed directly to the Web
client, he may place it under this directory.

Categories