Spring Boot: Publish Thymeleaf template without restarting the server - spring

Is there a way to publish Thymeleaf template without running and building the war file?
This is how my gradle file looks:
apply plugin: 'war'
war {
baseName = 'bootBlog'
version = '0.1.0'
}
repositories {
mavenLocal()
mavenCentral()
maven { url "https://repo.spring.io/libs-release" }
}
configurations {
providedRuntime
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-data-mongodb")
compile("org.springframework.boot:spring-boot-starter-actuator")
testCompile("junit:junit")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")

The way thymeleaf works is by caching all thymeleaf templates as the server is booting up. This is the reason you are not getting the latest template. To stop the caching, there is an application setting that is in the application.properties called:
spring.thymeleaf.cache=false
Turning this off prevents caching and allows the templates to be refreshed without restarting the server.
Once you entered in the configuration, stop the server and start it with gradle bootRun. From now on you will be able to get the latest thymeleaf templates without a refresh.

If you still want to use Springboot rather than Gradle, you can add two more properties in your properties file :
project.base-dir (it is not a springboot known property, see it as a
variable to define the path to your project)
spring.thymeleaf.prefix
To summerize, your properties file should contain these properties :
project.base-dir=file:///path/to/your/project/base/dir
spring.thymeleaf.prefix=${project.base-dir}/src/main/resources/templates/
spring.thymeleaf.cache=false

Related

Unable to exclude Jar from grails war

I am using grails 4.0
In my build.gradle, I have following entry.
war {
exclude("**/abc-1.0.0.jar", "**/xyz-1.0.0.jar")
}
But for some reason, both these jars are included in the war file, when I run the command grails prod war
I have tried varies options, but nothing seems to work.
are you sure you're not trying to limit dependencies...?
ex.
dependencies {
...
compile("org.grails:grails-plugin-interceptors"){
exclude(module: 'org.slf4j:slf4j-api:1.7.22')
exclude(module: 'org.slf4j:jcl-over-slf4j:1.7.22')
}
}

How to use JPA metamodel with gradle, intellij IDEA?

I am using java 8, spring boot 2.0.0, spring-data-jpa(spring-boot-starter-data-jpa), gradle, intellij. I've been trying to use JPA Metamodel, but having difficulty on finding how to configure.
Metamodels for Entity classes aren't just generated.
I guessed it would be simple, but now it seems that can be wrong. How can I use it?
JDK11 / Gradle 5.0 / Hibernate 5.3.7.Final
sourceSets.main.java.srcDirs += "${buildDir}/generated"
compileJava {
options.annotationProcessorGeneratedSourcesDirectory = file("${buildDir}/generated")
}
dependencies {
annotationProcessor("javax.xml.bind:jaxb-api")
annotationProcessor("org.hibernate:hibernate-jpamodelgen")
}
Generated Metamodel classes will be generated at 'build/generated'
If you are using JDK8 or Hibernate 5.4+, annotationProcessor("javax.xml.bind:jaxb-api") may unnecessary.
I did this the other day using the scalified metamodel gradle plugin (https://plugins.gradle.org/plugin/com.scalified.plugins.gradle.metamodel). I'm using Spring Boot 2.0.5, but I don't see why it wouldn't work the same with Spring Boot 2.0.0. I'm using Gradle 4.8.1 as well.
Below is an excerpt of my build.gradle.
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath (
"org.springframework.boot:spring-boot-gradle-plugin:2.0.0",
"gradle.plugin.com.scalified.plugins.gradle:metamodel:0.0.1");
}
}
apply plugin: "com.scalified.plugins.gradle.metamodel"
// The plugin will default to the latest version of Hibernate if this is not specified
metamodel {
hibernateVersion = '5.2.14.Final' // For Spring Boot 2.0.0
hibernateVersion = '5.2.17.Final' // For Spring Boot 2.0.5
}
This builds the metamodal files under src/generated and they can be used in your code. I had to also change an IntelliJ setting because IntelliJ's Build Automatically excludes some Gradle tasks that could be long running. See Automatically run Gradle task in project build with IntelliJ IDEA and https://youtrack.jetbrains.com/issue/IDEA-175165 for more details.
This setting I changed to overcome this is: Preferences->Build/Execution/Deployment->Gradle->Runner->Delegate IDE build/run actions to Gradle. An alternative would be to run the metamodelCompile gradle task manually as needed. That would lessen the time to rebuild by a little if you aren't frequently change your entities.

Spring Boot war file works with embedded but not with standalone Tomcat

I want to create a war file from a Spring Boot application, which I can deploy to a standalone Tomcat container, not using the embedded one.
I can create the war file and run it on its own using "java -jar pdfjs-annotator.war" and it works fine.
I built the application using gradle bootRepackage (Using Gradle, Tomcat7, Java 1.7).
But when I deploy the war file to a standalone Tomcat and start it, the app seems to boot without errors according to the log, but I cannot access any of the resources nor do the controller urls work.
For example, my index.html is a static html page under src/main/resources/static/index.html, which I can usually call via localhost:8080/index.html, but when deployed to a standalone Tomcat, the page does not get delivered (it's then in the war file in WEB-INF/classes/static/index.html) through that same url. And also any kind of controller mapping don't seem to work. I am getting a 404 error instead.
build.gradle:
buildscript {
ext {
springBootVersion = '1.2.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("io.spring.gradle:dependency-management-plugin:0.5.0.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'war'
war {
baseName = 'pdfjs-annotator'
version = '1.0.0-SNAPSHOT'
}
allprojects {
apply plugin: 'java'
sourceCompatibility = 1.6
targetCompatibility = 1.6
}
repositories {
mavenCentral()
}
configurations {
providedRuntime
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-data-rest")
compile("org.springframework.boot:spring-boot-starter-web")
runtime("mysql:mysql-connector-java")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
testCompile("org.springframework.boot:spring-boot-starter-test")
compile ('org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final')
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7'
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
}
My main application class:
#EnableJpaRepositories
#SpringBootApplication
public class PdfAnnotator extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(PdfAnnotator.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(PdfAnnotator.class);
}
}
When I look into the exploded war, I do see the following META-INF/MANIFEST.MF:
Manifest-Version: 1.0
Start-Class: com.mypackage.pdfcomment.PdfAnnotator
Spring-Boot-Version: 1.2.3.RELEASE
Main-Class: org.springframework.boot.loader.WarLauncher
The gradle build process usually generated two war artifacts, one named .war and one named .war.original - the .war is the one that holds proper MANIFEST.MF entries and it's the one I used to deploy to the standalone Tomcat.
What's missing? I already checked other questions here on SO:
spring boot war without tomcat embedded
Deploying a WAR in tomcat
and also the Spring Boot docs, but could not find a hint of what's wrong.
* === Update === *
I installed a brand new Tomcat7, deployed the war file there, and everything's working fine. Seemed to be some issue with the Tomcat instance/configuration I had running. Not sure what exactly the issue was, but I won't bother to check it further since it's working fine now with the new Tomcat.
I had this exact problem. It was because my application was built with Java 1.8 but Tomcat was running with 1.7. Everything appeared to deploy properly and there were no errors. I simply got a 404 trying to hit my services which had otherwise been fine with the embedded tomcat server. Took me ages to figure it out but it was just a case of upgrading java on the Tomcat installation.
The project is actually setup correctly and it turned out that the problem was with the Tomcat instance I was running. Probably something wrong with the configuration or jars. The instance is in place already for a long time, maybe things got messed up over time.
Now with a brand new Tomcat7 instance installed, the war works just fine.

You can't change configuration 'providedRuntime' because it is already resolved

I am using Gradle 2.0 with Groovy 2.3.3.
When I run the build below I get the error > You can't change configuration 'providedRuntime' because it is already resolved!
Other posts and release notes suggest that it is to do with +=, however, I'm not using that operator so I am a bit confused.
apply plugin: 'war'
repositories {
mavenCentral()
}
//We don't want transitive dependencies added as we are matching a third-party build
configurations.all {
transitive = false
}
war {
archiveName='gradle.war'
from(configurations.providedRuntime.files) {
into "app-jars"
}
classpath fileTree('webinf-libs') // adds a file-set to the WEB-INF/lib dir.
}
dependencies {
providedRuntime group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.2'
}
Changing war configuration to:
war {
archiveName='gradle.war'
from(configurations.providedRuntime) {
into "app-jars"
}
classpath fileTree('webinf-libs') // adds a file-set to the WEB-INF/lib dir.
}
will solve the issue.
The problem occurred because files was called in war configuration block and then dependencies were added to providedRuntime. Since calling files resolves the configuration (and war block is evaluated at configuration phase) it can't be modified later on.
You can also change order of dependencies and war and it will be the same.

Gradle multiple project build ClassNotFound on deploy

My web app is build using two projects one that contains the api and second web part. In Eclipse I am able to use classes from project-api in project-web however in deploy I have exception:
Caused by: java.lang.ClassNotFoundException: project.api.TestApi
This is my main build.gradle file:
sourceCompatibility = 1.7
subprojects {
apply plugin: 'java'
}
This is build.gradle from api:
apply plugin: 'java'
apply plugin: 'eclipse'
repositories {
mavenCentral()
}
dependencies {
}
And this is part of my build.gradle from web:
dependencies {
compile project(':project-api')
...
}
If I go and see web app libraries I can't see anything like project-api.jar. Wham am I doing wrong?
UPDATE:
It is issue only in eclipse. If I run gradlew war and deploy this manually to tomcat I can deploy it without any issued. project-api.jar is included in war. I tried already to run few times
`gradlew clean cleanEclipse eclipse`
but it doesn't help. I also try to reimport projects in eclipse but still the same.
EDIT:
This project is a spring mvc app and I just discovered that when I build war from gradle I am able to deploy war manually without any errors. Issue is only when trying to deploy via eclipse.
EDIT: Here is settings.gradle
rootProject.name = 'project'
include 'project-test'
include 'project-web'
include 'project-api'
You need to convert the dependencies of the deployable project to a "faceted project".
Project properties -> Project Facets -> Convert to faceted form...
Then mark each dependency as a "Utility Module".

Resources