Repository: jhipster/generator-jhipster (ts)

Issue:
Move client app to classpath:/public
##### **Overview of the feature request**

By default Spring-boot serves anything that is into `classpath:/public`
So I propose to build the client into `target/classes/public` instead of `target/www`.
With this we can remove our custom addition of static assets for IDEs in WebConfigurer.
So far I've tested with IDEA, maven, and `java -jar`. Not yet by deploying in an app server, not yet with gradle.
We have a lot of ways to run the app and it can be tricky. Do you see use-cases I'm missing ?

##### **Motivation for or Use Case**

* Policy 1, less custom code
* Our current implementation can have a bad effect if someone runs the prod war from a dir that has a `target/www` directory. In that case our detection will serve what is in this folder instead of what is in the war.
* This would be compatible with Webflux (our current is not : you can't do `setDocumentRoot` in Webflux)
* After that, we may be able to use Spring's built-in cache control instead of our custom cache filter.

-   [x] Checking this box is mandatory (this is just to show you read everything)

<!-- Love JHipster? Please consider supporting our collective:
👉  https://opencollective.com/generator-jhipster/donate -->


Pull request:
Move client app to classpath:/public
Fix #9118 

-   Please make sure the below checklist is followed for Pull Requests.

-   [x] [Travis tests](https://travis-ci.org/jhipster/generator-jhipster/pull_requests) are green
-   [x] Tests are added where necessary
-   [x] Documentation is added/updated where necessary
-   [x] Coding Rules & Commit Guidelines as per our [CONTRIBUTING.md document](https://github.com/jhipster/generator-jhipster/blob/master/CONTRIBUTING.md) are followed

<!--
Please also reference the issue number in a commit message to [automatically close the related Github issue](https://help.github.com/articles/closing-issues-via-commit-messages/)

Note: It is also possible to add `[skip ci]` to your commit message to skip Travis tests
-->


Patch:
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index afe3f3df4d..6b1d61f5ab 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -92,8 +92,6 @@ jobs:
     displayName: 'TOOLS: install google-chrome-stable'
   - script: sudo npm install -g npm
     displayName: 'TOOLS: update NPM'
-  - script: sudo chown -R vsts:docker /home/vsts/.npm/
-    displayName: 'BUGS-FIX: change /home/vsts/.npm/ permission'
   - bash: $(JHI_SCRIPTS)/01-display-configuration.sh
     displayName: 'TOOLS: display configuration'
   - bash: $(JHI_SCRIPTS)/03-system.sh
diff --git a/generators/ci-cd/templates/azure-pipelines.yml.ejs b/generators/ci-cd/templates/azure-pipelines.yml.ejs
index d3285583c2..51f0914040 100644
--- a/generators/ci-cd/templates/azure-pipelines.yml.ejs
+++ b/generators/ci-cd/templates/azure-pipelines.yml.ejs
@@ -37,8 +37,6 @@ jobs:
   <%_ if (clientPackageManager === 'npm') { _%>
   - script: sudo npm install -g npm
     displayName: 'TOOLS: update NPM'
-  - script: sudo chown -R vsts:docker /home/vsts/.npm/
-    displayName: 'BUGS-FIX: change /home/vsts/.npm/ permission'
   <%_ } else if (clientPackageManager === 'yarn') { _%>
   - script: |
       curl -o- -L https://yarnpkg.com/install.sh | bash
diff --git a/generators/client/files-angular.js b/generators/client/files-angular.js
index 61cf6f5bc6..5784693285 100644
--- a/generators/client/files-angular.js
+++ b/generators/client/files-angular.js
@@ -115,6 +115,7 @@ const files = {
         {
             path: MAIN_SRC_DIR,
             templates: [
+                'WEB-INF/web.xml',
                 { file: 'favicon.ico', method: 'copy' },
                 'robots.txt',
                 '404.html',
diff --git a/generators/client/files-react.js b/generators/client/files-react.js
index 6a6617a999..e760157298 100644
--- a/generators/client/files-react.js
+++ b/generators/client/files-react.js
@@ -102,6 +102,7 @@ const files = {
         {
             path: MAIN_SRC_DIR,
             templates: [
+                'WEB-INF/web.xml',
                 { file: 'favicon.ico', method: 'copy' },
                 'robots.txt',
                 '404.html',
diff --git a/generators/client/index.js b/generators/client/index.js
index 974b26f7db..f411ce07fd 100644
--- a/generators/client/index.js
+++ b/generators/client/index.js
@@ -331,7 +331,8 @@ module.exports = class extends BaseBlueprintGenerator {
                 this.styleSheetExt = this.useSass ? 'scss' : 'css';
                 this.pkType = this.getPkType(this.databaseType);
                 this.apiUaaPath = `${this.authenticationType === 'uaa' ? `${this.uaaBaseName.toLowerCase()}/` : ''}`;
-                this.DIST_DIR = this.BUILD_DIR + constants.CLIENT_DIST_DIR;
+                this.DIST_DIR = this.getResourceBuildDirectoryForBuildTool(this.configOptions.buildTool) + constants.CLIENT_DIST_DIR;
+                this.AOT_DIR = `${this.getResourceBuildDirectoryForBuildTool(this.configOptions.buildTool)}aot`;
                 this.CLIENT_MAIN_SRC_DIR = constants.CLIENT_MAIN_SRC_DIR;
             },
 
diff --git a/generators/client/templates/angular/package.json.ejs b/generators/client/templates/angular/package.json.ejs
index c08a7f0b4c..9d29c508eb 100644
--- a/generators/client/templates/angular/package.json.ejs
+++ b/generators/client/templates/angular/package.json.ejs
@@ -167,8 +167,8 @@
     "lint": "tslint --project tsconfig.json -e 'node_modules/**'",
     "lint:fix": "<%= clientPackageManager %> run lint <%= optionsForwarder %>--fix",
     "ngc": "ngc -p tsconfig-aot.json",
-    "cleanup": "rimraf <%= BUILD_DIR %>{aot,www}",
-    "clean-www": "rimraf <%= BUILD_DIR %>/www/app/{src,<%= BUILD_DIR %>}",
+    "cleanup": "rimraf <%= DIST_DIR %> <%= AOT_DIR %>",
+    "clean-www": "rimraf <%= DIST_DIR %>app/{src,<%= BUILD_DIR %>}",
     <%_ if (protractorTests) { _%>
     "e2e": "protractor <%= TEST_SRC_DIR %>protractor.conf.js",
     "postinstall": "webdriver-manager update --gecko false",
diff --git a/generators/client/templates/angular/src/main/webapp/WEB-INF/web.xml.ejs b/generators/client/templates/angular/src/main/webapp/WEB-INF/web.xml.ejs
new file mode 100644
index 0000000000..f1611b515a
--- /dev/null
+++ b/generators/client/templates/angular/src/main/webapp/WEB-INF/web.xml.ejs
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app
+    xmlns="http://java.sun.com/xml/ns/javaee"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+    version="3.0">
+
+    <mime-mapping>
+        <extension>html</extension>
+        <mime-type>text/html;charset=utf-8</mime-type>
+    </mime-mapping>
+
+</web-app>
diff --git a/generators/client/templates/angular/tsconfig-aot.json.ejs b/generators/client/templates/angular/tsconfig-aot.json.ejs
index 3a78c4e9fc..d6bef235a8 100644
--- a/generators/client/templates/angular/tsconfig-aot.json.ejs
+++ b/generators/client/templates/angular/tsconfig-aot.json.ejs
@@ -40,7 +40,7 @@
         "importHelpers": true
     },
     "angularCompilerOptions": {
-        "genDir": "<%= BUILD_DIR %>aot",
+        "genDir": "<%= AOT_DIR %>",
         "skipMetadataEmit" : true,
         "fullTemplateTypeCheck": true,
         "preserveWhitespaces": true
diff --git a/generators/client/templates/angular/webpack/webpack.dev.js.ejs b/generators/client/templates/angular/webpack/webpack.dev.js.ejs
index a984008327..63103b997f 100644
--- a/generators/client/templates/angular/webpack/webpack.dev.js.ejs
+++ b/generators/client/templates/angular/webpack/webpack.dev.js.ejs
@@ -37,7 +37,7 @@ const ENV = 'development';
 module.exports = (options) => webpackMerge(commonConfig({ env: ENV }), {
     devtool: 'eval-source-map',
     devServer: {
-        contentBase: './<%= BUILD_DIR %>www',
+        contentBase: './<%= DIST_DIR %>',
         proxy: [{
             context: [<% if (authenticationType === 'uaa') { %>
                 '/<%= uaaBaseName.toLowerCase() %>',<% } %>
@@ -76,7 +76,7 @@ module.exports = (options) => webpackMerge(commonConfig({ env: ENV }), {
         main: './<%= MAIN_SRC_DIR %>app/app.main'
     },
     output: {
-        path: utils.root('<%= BUILD_DIR %>www'),
+        path: utils.root('<%= DIST_DIR %>'),
         filename: 'app/[name].bundle.js',
         chunkFilename: 'app/[id].chunk.js'
     },
diff --git a/generators/client/templates/angular/webpack/webpack.prod.js.ejs b/generators/client/templates/angular/webpack/webpack.prod.js.ejs
index 96f21d3e21..544394e86d 100644
--- a/generators/client/templates/angular/webpack/webpack.prod.js.ejs
+++ b/generators/client/templates/angular/webpack/webpack.prod.js.ejs
@@ -49,7 +49,7 @@ module.exports = webpackMerge(commonConfig({ env: ENV }), {
         main: './<%= MAIN_SRC_DIR %>app/app.main'
     },
     output: {
-        path: utils.root('<%= BUILD_DIR %>www'),
+        path: utils.root('<%= DIST_DIR %>'),
         filename: 'app/[name].[hash].bundle.js',
         chunkFilename: 'app/[id].[hash].chunk.js'
     },
diff --git a/generators/client/templates/react/package.json.ejs b/generators/client/templates/react/package.json.ejs
index 74ed6ac82c..ab56cb9591 100644
--- a/generators/client/templates/react/package.json.ejs
+++ b/generators/client/templates/react/package.json.ejs
@@ -187,7 +187,7 @@ limitations under the License.
     "prettier:format": "prettier --write \"{,src/**/}*.{md,json,ts,tsx,css,scss}\"",
     "lint": "tslint --project tsconfig.json -e 'node_modules/**'",
     "lint:fix": "<%= clientPackageManager %> run lint <%= optionsForwarder %>--fix",
-    "cleanup": "rimraf <%= BUILD_DIR %>www",
+    "cleanup": "rimraf <%= DIST_DIR %>",
     <%_ if (protractorTests) { _%>
     "e2e": "protractor <%= TEST_SRC_DIR %>protractor.conf.js",
     "postinstall": "webdriver-manager update --gecko false",
diff --git a/generators/client/templates/react/src/main/webapp/WEB-INF/web.xml.ejs b/generators/client/templates/react/src/main/webapp/WEB-INF/web.xml.ejs
new file mode 100644
index 0000000000..f1611b515a
--- /dev/null
+++ b/generators/client/templates/react/src/main/webapp/WEB-INF/web.xml.ejs
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app
+    xmlns="http://java.sun.com/xml/ns/javaee"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+    version="3.0">
+
+    <mime-mapping>
+        <extension>html</extension>
+        <mime-type>text/html;charset=utf-8</mime-type>
+    </mime-mapping>
+
+</web-app>
diff --git a/generators/client/templates/react/webpack/webpack.dev.js.ejs b/generators/client/templates/react/webpack/webpack.dev.js.ejs
index 1e9b64d941..26fc437b22 100644
--- a/generators/client/templates/react/webpack/webpack.dev.js.ejs
+++ b/generators/client/templates/react/webpack/webpack.dev.js.ejs
@@ -41,7 +41,7 @@ module.exports = (options) => webpackMerge(commonConfig({ env: ENV }), {
     './<%= CLIENT_MAIN_SRC_DIR %>app/index'
   ],
   output: {
-    path: utils.root('<%= BUILD_DIR %>www'),
+    path: utils.root('<%= DIST_DIR %>'),
     filename: 'app/[name].bundle.js',
     chunkFilename: 'app/[id].chunk.js'
   },
@@ -67,7 +67,7 @@ module.exports = (options) => webpackMerge(commonConfig({ env: ENV }), {
   devServer: {
     stats: options.stats,
     hot: true,
-    contentBase: './<%= BUILD_DIR %>www',
+    contentBase: './<%= DIST_DIR %>',
     proxy: [{
       context: [<% if (authenticationType === 'uaa') { %>
         '/<%= uaaBaseName.toLowerCase() %>',<% } %>
diff --git a/generators/client/templates/react/webpack/webpack.prod.js.ejs b/generators/client/templates/react/webpack/webpack.prod.js.ejs
index cd1511099b..2df3bfa8be 100644
--- a/generators/client/templates/react/webpack/webpack.prod.js.ejs
+++ b/generators/client/templates/react/webpack/webpack.prod.js.ejs
@@ -40,7 +40,7 @@ module.exports = webpackMerge(commonConfig({ env: ENV }), {
     main: './<%= MAIN_SRC_DIR %>app/index'
   },
   output: {
-    path: utils.root('<%= BUILD_DIR %>www'),
+    path: utils.root('<%= DIST_DIR %>'),
     filename: 'app/[name].[hash].bundle.js',
     chunkFilename: 'app/[name].[hash].chunk.js'
   },
diff --git a/generators/common/index.js b/generators/common/index.js
index fb9998058c..1f7afaf09b 100644
--- a/generators/common/index.js
+++ b/generators/common/index.js
@@ -66,7 +66,7 @@ module.exports = class extends BaseBlueprintGenerator {
                 this.CLIENT_MAIN_SRC_DIR = constants.CLIENT_MAIN_SRC_DIR;
                 this.CLIENT_TEST_SRC_DIR = constants.CLIENT_TEST_SRC_DIR;
                 this.BUILD_DIR = this.getBuildDirectoryForBuildTool(this.buildTool);
-                this.CLIENT_DIST_DIR = this.BUILD_DIR + constants.CLIENT_DIST_DIR;
+                this.CLIENT_DIST_DIR = this.getResourceBuildDirectoryForBuildTool(this.configOptions.buildTool) + constants.CLIENT_DIST_DIR;
 
                 // Make documentation URL available in templates
                 this.DOCUMENTATION_URL = constants.JHIPSTER_DOCUMENTATION_URL;
diff --git a/generators/generator-base-private.js b/generators/generator-base-private.js
index b2636194cd..317a627849 100644
--- a/generators/generator-base-private.js
+++ b/generators/generator-base-private.js
@@ -1120,6 +1120,14 @@ module.exports = class extends Generator {
         return buildTool === 'maven' ? 'target/' : 'build/';
     }
 
+    /**
+     * Get resource build directory used by buildTool
+     * @param {string} buildTool - buildTool
+     */
+    getResourceBuildDirectoryForBuildTool(buildTool) {
+        return buildTool === 'maven' ? 'target/classes/' : 'build/resources/main/';
+    }
+
     /**
      * @returns generated JDL from entities
      */
diff --git a/generators/generator-constants.js b/generators/generator-constants.js
index 2c1d83137b..0556f3413d 100644
--- a/generators/generator-constants.js
+++ b/generators/generator-constants.js
@@ -67,8 +67,8 @@ const NPM_VERSION = '6.4.1';
 const MAIN_DIR = 'src/main/';
 const TEST_DIR = 'src/test/';
 
-// Note: this will be prepended with 'target/' for Maven, or with 'build/' for Gradle.
-const CLIENT_DIST_DIR = 'www/';
+// Note: this will be prepended with 'target/classes' for Maven, or with 'build/resources/main' for Gradle.
+const CLIENT_DIST_DIR = 'static/';
 
 const SUPPORTED_VALIDATION_RULES = ['required', 'unique', 'max', 'min', 'maxlength', 'minlength', 'maxbytes', 'minbytes', 'pattern'];
 
diff --git a/generators/kubernetes-helm/templates/README-KUBERNETES-HELM.md.ejs b/generators/kubernetes-helm/templates/README-KUBERNETES-HELM.md.ejs
index ff69f0ee2f..2ce69a78e6 100644
--- a/generators/kubernetes-helm/templates/README-KUBERNETES-HELM.md.ejs
+++ b/generators/kubernetes-helm/templates/README-KUBERNETES-HELM.md.ejs
@@ -18,19 +18,19 @@ $ <%= dockerPushCommand %> <%= appConfigs[i].targetImageName %>
 To use the templates generated by this sub-generator `helm cli and tiller` should be installed. Instructions on installing `helm` can be referred
 at [https://github.com/helm/helm](https://github.com/helm/helm)
 
-Once Helm is installed you need to add the below repositories:
+Once, helm is installed, then you need to add the below repositories,
 ```
 helm repo add stable https://kubernetes-charts.storage.googleapis.com
 helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com
-```
-These repositories should be added to the local cache, because this sub-generator will pull some charts from them.
+```  
+These repos should be added to the local cache, because this sub-generator will pull some charts from these repos. 
 
-This repository in turn uses the `kubernetes` sub-generator for the microservices manifests and few service like database, Elasticsearch, Prometheus etc. that are referred from the above repositories.
+This repo in turn uses `kubernets` sub-generator for the microservices manifests and few service like db, elk, prometheus etc. are referred from the above repos. 
 
 
 ## Deployment
 
-You can deploy all your applications by running the following bash command:
+You can deploy all your apps by running the below bash command:
 
 ```
 bash helm-apply.sh (or) ./helm-apply.sh
@@ -38,16 +38,16 @@ bash helm-apply.sh (or) ./helm-apply.sh
 
 `helm-apply.sh` will always do a clean install. Any of the existing charts with the same identity gets removed first and then it does a clean install.
 
-You can upgrade all your apps (if you have made any changes to the generated manifests) by running the following bash command:
+
+You can upgrade all your apps (if at all if you have made any changes to the generated manifests) by running the below bash command:
 
 ```
 bash helm-upgrade.sh (or) ./helm-upgrade.sh
 ```
 
-For Kubernetes specific information, refer to the `kubernetes` sub-generator Readme instructions.
+For kubernetes specific info, refer `kubernetes` sub-generator readme instructions.
 
 ### Backlogs to be covered
-
-* Couchbase is yet to be integrated with Helm repository, it is still referring the Kubernetes sub-generator manifest - to be tested
+* Couchbase is yet to be integrated with helm repo, it is still referring the k8s sub generator manifest. Not tested.
 * helm upgrade - to be tested
 * Istio - to be tested
diff --git a/generators/kubernetes/prompts.js b/generators/kubernetes/prompts.js
index f962d066b8..06c0e6c4e8 100644
--- a/generators/kubernetes/prompts.js
+++ b/generators/kubernetes/prompts.js
@@ -54,11 +54,11 @@ function askForKubernetesServiceType() {
         {
             type: 'list',
             name: 'kubernetesServiceType',
-            message: 'Choose the Kubernetes service type for your edge services',
+            message: 'Choose the kubernetes service type for your edge services',
             choices: [
                 {
                     value: 'LoadBalancer',
-                    name: 'LoadBalancer - Let a Kubernetes cloud provider automatically assign an IP'
+                    name: 'LoadBalancer - Let a kubernetes cloud provider automatically assign an IP'
                 },
                 {
                     value: 'NodePort',
diff --git a/generators/kubernetes/templates/README-KUBERNETES.md.ejs b/generators/kubernetes/templates/README-KUBERNETES.md.ejs
index e96b6a527b..9a5431e503 100644
--- a/generators/kubernetes/templates/README-KUBERNETES.md.ejs
+++ b/generators/kubernetes/templates/README-KUBERNETES.md.ejs
@@ -1,4 +1,4 @@
-# JHipster-generated Kubernetes configuration
+# JHipster generated kubernetes configuration
 
 ## Preparation
 
@@ -52,7 +52,7 @@ The default way to update a running app in kubernetes, is to deploy a new image
 $ kubectl set image deployment/<app-name>-app <app-name>=<new-image> <%= kubernetesNamespace === 'default' ? '' : ` -n ${kubernetesNamespace}` %>
 ```
 
-Using livenessProbes and readinessProbe allow you to tell Kubernetes about the state of your applications, in order to ensure availablity of your services. You will need minimum 2 replicas for every application deployment if you want to have zero-downtime deployed. This is because the rolling upgrade strategy first kills a running replica in order to place a new. Running only one replica, will cause a short downtime during upgrades.
+Using livenessProbes and readinessProbe allows you to tell kubernetes about the state of your apps, in order to ensure availablity of your services. You will need minimum 2 replicas for every app deployment, you want to have zero-downtime deployed. This is because the rolling upgrade strategy first kills a running replica in order to place a new. Running only one replica, will cause a short downtime during upgrades.
 <%_ if (monitoring === 'elk' || monitoring === 'prometheus') { _%>
 
 ## Monitoring tools
@@ -122,26 +122,26 @@ $ kubectl scale statefulset jhipster-registry --replicas 3<%= kubernetesNamespac
 
 > my apps doesn't get pulled, because of 'imagePullBackof'
 
-Check the registry your Kubernetes cluster is accessing. If you are using a private registry, you should add it to your namespace by `kubectl create secret docker-registry` (check the [docs](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) for more info)
+check the registry your kubernetes cluster is accessing. If you are using a private registry, you should add it to your namespace by `kubectl create secret docker-registry` (check the [docs](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) for more info)
 
-> my applications get killed, before they can boot up
+> my apps get killed, before they can boot up
 
-This can occur if your cluster has low resource (e.g. Minikube). Increase the `initialDelySeconds` value of livenessProbe of your deployments
+This can occur, if your cluster has low resource (e.g. Minikube). Increase the `initialDelySeconds` value of livenessProbe of your deployments
 
-> my applications are starting very slow, despite I have a cluster with many resources
+> my apps are starting very slow, despite I have a cluster with many resources
 
-The default setting are optimized for middle-scale clusters. You are free to increase the JAVA_OPTS environment variable, and resource requests and limits to improve the performance. Be careful!
+The default setting are optimized for middle scale clusters. You are free to increase the JAVA_OPTS environment variable, and resource requests and limits to improve the performance. Be careful!
 
 <%_ if (monitoring === 'prometheus') { _%>
-> I have selected Prometheus but no targets are visible
+> I have selected prometheus but no targets are visible
 
-This depends on the setup of the Prometheus operator and the access control policies in your cluster. Version 1.6.0+ is needed for the RBAC setup to work.
+This depends on the setup of prometheus operator and the access control policies in your cluster. Version 1.6.0+ is needed for the RBAC setup to work.
 
-> I have selected Prometheus, but my targets never get scraped
+> I have selected prometheus, but my targets never get scraped
 
-This means your applications are probably not built using the `prometheus` profile in Maven/Gradle
+This means your apps are probably not built using the `prometheus` profile in Maven/Gradle
 <%_ } _%>
 
-> my SQL-based microservice is stuck during Liquibase initialization when running multiple replicas
+> my SQL based microservice stuck during liquibase initialization when running multiple replicas
 
 Sometimes the database changelog lock gets corrupted. You will need to connect to the database using `kubectl exec -it` and remove all lines of liquibases `databasechangeloglock` table.
diff --git a/generators/server/index.js b/generators/server/index.js
index 88908bc9eb..ecfae736dd 100644
--- a/generators/server/index.js
+++ b/generators/server/index.js
@@ -327,7 +327,7 @@ module.exports = class extends BaseBlueprintGenerator {
 
                 // Make dist dir available in templates
                 this.BUILD_DIR = this.getBuildDirectoryForBuildTool(this.buildTool);
-                this.CLIENT_DIST_DIR = this.BUILD_DIR + constants.CLIENT_DIST_DIR;
+                this.CLIENT_DIST_DIR = this.getResourceBuildDirectoryForBuildTool(this.configOptions.buildTool) + constants.CLIENT_DIST_DIR;
             }
         };
     }
diff --git a/generators/server/templates/build.gradle.ejs b/generators/server/templates/build.gradle.ejs
index c142cbeed2..62b280d65f 100644
--- a/generators/server/templates/build.gradle.ejs
+++ b/generators/server/templates/build.gradle.ejs
@@ -89,6 +89,7 @@ description = ''
 
 bootWar {
     mainClassName = '<%= packageName %>.<%= mainClass %>'
+    includes = ['WEB-INF/**', 'META-INF/**']
 }
 
 war {
@@ -97,6 +98,7 @@ war {
     <%_ } _%>
     enabled = true
     extension = 'war.original'
+    includes = ['WEB-INF/**', 'META-INF/**']
 }
 
 springBoot {
diff --git a/generators/server/templates/gradle/docker.gradle.ejs b/generators/server/templates/gradle/docker.gradle.ejs
index aced4ce1c8..362f19f3b5 100644
--- a/generators/server/templates/gradle/docker.gradle.ejs
+++ b/generators/server/templates/gradle/docker.gradle.ejs
@@ -46,11 +46,3 @@ jib {
     }
 }
 
-<%_ if (!skipClient) { _%>
-task copyWwwIntoStatic (type: Copy) {
-    from '<%= CLIENT_DIST_DIR %>'
-    into 'build/resources/main/static'
-}
-
-jibDockerBuild.dependsOn copyWwwIntoStatic
-<%_ } _%>
diff --git a/generators/server/templates/gradle/profile_dev.gradle.ejs b/generators/server/templates/gradle/profile_dev.gradle.ejs
index 30c0a54cf5..f91fa8c341 100644
--- a/generators/server/templates/gradle/profile_dev.gradle.ejs
+++ b/generators/server/templates/gradle/profile_dev.gradle.ejs
@@ -60,15 +60,10 @@ task webpackBuildDev(type: <%= _.upperFirst(clientPackageManager) %>Task) {
 
     outputs.files(fileTree("<%= CLIENT_DIST_DIR %>"))
 
-    dependsOn <%= clientPackageManager %>_install
+    dependsOn <%= clientPackageManager %>Install
 
     args = ["run", "webpack:build"]
 }
-
-task copyIntoStatic (type: Copy) {
-    from '<%= CLIENT_DIST_DIR %>'
-    into 'build/resources/main/static'
-}
 <%_ } _%>
 
 processResources {
@@ -93,6 +88,5 @@ processResources {
 
 <%_ if (!skipClient) { _%>
 processResources.dependsOn webpackBuildDev
-copyIntoStatic.dependsOn processResources
-bootJar.dependsOn copyIntoStatic
+bootJar.dependsOn processResources
 <%_ } _%>
diff --git a/generators/server/templates/gradle/profile_prod.gradle.ejs b/generators/server/templates/gradle/profile_prod.gradle.ejs
index 6486097f8b..7de98f7453 100644
--- a/generators/server/templates/gradle/profile_prod.gradle.ejs
+++ b/generators/server/templates/gradle/profile_prod.gradle.ejs
@@ -53,11 +53,6 @@ task webpack_test(type: <%= _.upperFirst(clientPackageManager) %>Task, dependsOn
 task webpack(type: <%= _.upperFirst(clientPackageManager) %>Task, dependsOn: '<%= clientPackageManager %>_install') {
     args = ["run", "webpack:prod"]
 }
-
-task copyIntoStatic (type: Copy) {
-    from '<%= CLIENT_DIST_DIR %>'
-    into 'build/resources/main/static'
-}
 <%_ } _%>
 
 processResources {
@@ -93,6 +88,5 @@ gitProperties {
 <%_ if (!skipClient) { _%>
 test.dependsOn webpack_test
 processResources.dependsOn webpack
-copyIntoStatic.dependsOn processResources
-bootJar.dependsOn copyIntoStatic
+bootJar.dependsOn processResources
 <%_ } _%>
diff --git a/generators/server/templates/gradlew.bat b/generators/server/templates/gradlew.bat
old mode 100755
new mode 100644
diff --git a/generators/server/templates/mvnw.cmd b/generators/server/templates/mvnw.cmd
old mode 100755
new mode 100644
diff --git a/generators/server/templates/pom.xml.ejs b/generators/server/templates/pom.xml.ejs
index cfb7a5e688..bed29fa0b6 100644
--- a/generators/server/templates/pom.xml.ejs
+++ b/generators/server/templates/pom.xml.ejs
@@ -1060,22 +1060,6 @@
                                 </resources>
                             </configuration>
                         </execution>
-                        <execution>
-                            <id>jib-www-resources</id>
-                            <phase>verify</phase>
-                            <goals>
-                                <goal>copy-resources</goal>
-                            </goals>
-                            <configuration>
-                                <outputDirectory>${project.build.directory}/classes/static/</outputDirectory>
-                                <resources>
-                                    <resource>
-                                        <directory>${project.build.directory}/www</directory>
-                                        <filtering>false</filtering>
-                                    </resource>
-                                </resources>
-                            </configuration>
-                        </execution>
                     </executions>
                 </plugin>
                 <plugin>
@@ -1219,7 +1203,7 @@
             <id>webpack</id>
             <activation>
                 <file>
-                    <missing>${basedir}/target/www/app/main.bundle.js</missing>
+                    <missing>${basedir}/<%= CLIENT_DIST_DIR %>app/main.bundle.js</missing>
                 </file>
             </activation>
             <dependencies>
@@ -1301,16 +1285,7 @@
                         <groupId>org.apache.maven.plugins</groupId>
                         <artifactId>maven-war-plugin</artifactId>
                         <configuration>
-                            <failOnMissingWebXml>false</failOnMissingWebXml>
-                            <warSourceDirectory><%= CLIENT_DIST_DIR %></warSourceDirectory>
-                            <webResources>
-                                <resource>
-                                    <directory><%= CLIENT_MAIN_SRC_DIR %></directory>
-                                    <includes>
-                                        <include>WEB-INF/**</include>
-                                    </includes>
-                                </resource>
-                            </webResources>
+                            <warSourceIncludes>WEB-INF/**,META-INF/**</warSourceIncludes>
                         </configuration>
                     </plugin>
                 </plugins>
@@ -1349,18 +1324,7 @@
                         <groupId>org.apache.maven.plugins</groupId>
                         <artifactId>maven-war-plugin</artifactId>
                         <configuration>
-                            <failOnMissingWebXml>false</failOnMissingWebXml>
-                            <%_ if (!skipClient) { _%>
-                            <warSourceDirectory><%= CLIENT_DIST_DIR %></warSourceDirectory>
-                            <webResources>
-                                <resource>
-                                    <directory><%= CLIENT_MAIN_SRC_DIR %></directory>
-                                    <includes>
-                                        <include>WEB-INF/**</include>
-                                    </includes>
-                                </resource>
-                            </webResources>
-                            <%_ } _%>
+                            <warSourceIncludes>WEB-INF/**,META-INF/**</warSourceIncludes>
                         </configuration>
                     </plugin>
                 </plugins>
@@ -1394,18 +1358,7 @@
                         <groupId>org.apache.maven.plugins</groupId>
                         <artifactId>maven-war-plugin</artifactId>
                         <configuration>
-                            <failOnMissingWebXml>false</failOnMissingWebXml>
-                            <%_ if (!skipClient) { _%>
-                            <warSourceDirectory><%= CLIENT_DIST_DIR %></warSourceDirectory>
-                            <webResources>
-                                <resource>
-                                    <directory><%= CLIENT_MAIN_SRC_DIR %></directory>
-                                    <includes>
-                                        <include>WEB-INF/**</include>
-                                    </includes>
-                                </resource>
-                            </webResources>
-                            <%_ } _%>
+                            <warSourceIncludes>WEB-INF/**,META-INF/**</warSourceIncludes>
                         </configuration>
                     </plugin>
                     <plugin>
@@ -1541,8 +1494,7 @@
                         <groupId>org.apache.maven.plugins</groupId>
                         <artifactId>maven-war-plugin</artifactId>
                         <configuration>
-                            <failOnMissingWebXml>false</failOnMissingWebXml>
-                            <warSourceDirectory><%= CLIENT_MAIN_SRC_DIR %></warSourceDirectory>
+                            <warSourceIncludes>WEB-INF/**,META-INF/**</warSourceIncludes>
                         </configuration>
                     </plugin>
                     <plugin>
diff --git a/generators/server/templates/src/main/docker/.dockerignore.ejs b/generators/server/templates/src/main/docker/.dockerignore.ejs
index dd303d07b1..803533a78c 100644
--- a/generators/server/templates/src/main/docker/.dockerignore.ejs
+++ b/generators/server/templates/src/main/docker/.dockerignore.ejs
@@ -27,7 +27,6 @@ reports/
 surefire-reports/
 test-classes/
 test-results/
-www/
 !*.jar
 !*.war
 <%_ if (prodDatabaseType === 'cassandra') { _%>


Test patch:
diff --git a/generators/server/templates/src/test/java/package/config/WebConfigurerTest.java.ejs b/generators/server/templates/src/test/java/package/config/WebConfigurerTest.java.ejs
index 3df8727e20..bf8516e778 100644
--- a/generators/server/templates/src/test/java/package/config/WebConfigurerTest.java.ejs
+++ b/generators/server/templates/src/test/java/package/config/WebConfigurerTest.java.ejs
@@ -26,9 +26,6 @@ import io.github.jhipster.web.filter.CachingHttpHeadersFilter;
 import io.undertow.Undertow;
 import io.undertow.Undertow.Builder;
 import io.undertow.UndertowOptions;
-<%_ if (!skipClient) { _%>
-import org.apache.commons.io.FilenameUtils;
-<%_ } %>
 <%_ if (devDatabaseType === 'h2Disk' || devDatabaseType === 'h2Memory') { _%>
 import org.h2.server.web.WebServlet;
 <%_ } _%>
@@ -44,6 +41,9 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 import org.xnio.OptionMap;
 
 import javax.servlet.*;
+<%_ if (!skipClient) { _%>
+import java.io.File;
+<%_ } _%>
 import java.util.*;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -120,7 +120,7 @@ public class WebConfigurerTest {
         assertThat(container.getMimeMappings().get("json")).isEqualTo("text/html;charset=utf-8");
         <%_ if (!skipClient) { _%>
         if (container.getDocumentRoot() != null) {
-            assertThat(container.getDocumentRoot().getPath()).isEqualTo(FilenameUtils.separatorsToSystem("<%= BUILD_DIR %>www"));
+            assertThat(container.getDocumentRoot()).isEqualTo(new File("<%= CLIENT_DIST_DIR %>"));
         }
         <%_ } _%>
 
diff --git a/test-integration/scripts/23-package.sh b/test-integration/scripts/23-package.sh
index 9d2693e184..f22e7874c7 100755
--- a/test-integration/scripts/23-package.sh
+++ b/test-integration/scripts/23-package.sh
@@ -9,7 +9,6 @@ source $(dirname $0)/00-init-env.sh
 if [[ "$JHI_APP" == *"uaa"* ]]; then
     cd "$JHI_FOLDER_UAA"
     ./mvnw verify -DskipTests -Pdev
-    mv target/*.war app.war
 fi
 
 #-------------------------------------------------------------------------------
diff --git a/test/utils/expected-files.js b/test/utils/expected-files.js
index ce9ab0bc7d..c7a9b630e7 100644
--- a/test/utils/expected-files.js
+++ b/test/utils/expected-files.js
@@ -471,6 +471,7 @@ const expectedFiles = {
         `${CLIENT_MAIN_SRC_DIR}content/images/jhipster_family_member_2_head-512.png`,
         `${CLIENT_MAIN_SRC_DIR}content/images/jhipster_family_member_3_head-512.png`,
         `${CLIENT_MAIN_SRC_DIR}content/images/logo-jhipster.png`,
+        `${CLIENT_MAIN_SRC_DIR}WEB-INF/web.xml`,
         `${CLIENT_MAIN_SRC_DIR}favicon.ico`,
         `${CLIENT_MAIN_SRC_DIR}index.html`,
         `${CLIENT_MAIN_SRC_DIR}manifest.webapp`,