Gatling is not working with SpringBoot 2.0.1.RELEASE - spring

I'm trying to setup Gatling with Spring Boot 2.0.1.RELEASE.
I've created this api:
#RestController
#RequestMapping("/contact")
public class ContactController {
#GetMapping
public ResponseEntity get() {
return ResponseEntity.ok("Contact retrieved successfully");
}
}
And this basic simulation:
import io.gatling.core.Predef._
import io.gatling.http.Predef._
class ContactSimulation extends Simulation {
val httpConf = http.baseURL("http://localhost:8080")
val scn = scenario("GetContact")
.exec(
http("GetContact")
.get("/contact")
.check(status.is(200))
)
setUp(scn.inject(atOnceUsers(1))).protocols(httpConf)
}
The build.gradle is configured this way:
buildscript {
ext {
springBootVersion = '2.0.1.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'scala'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.gatling.poc'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('io.gatling.highcharts:gatling-charts-highcharts:2.3.0')
}
task loadTest(type: JavaExec) {
dependsOn testClasses
description = "Load Test With Gatling"
group = "Load Test"
classpath = sourceSets.test.runtimeClasspath
jvmArgs = [
"-Dgatling.core.directory.binaries=${sourceSets.test.output.classesDir.toString()}"
]
main = "io.gatling.app.Gatling"
args = [
"--simulation", "com.gatling.poc.simulations.ContactSimulation",
"--results-folder", "${buildDir}/gatling-results",
"--binaries-folder", sourceSets.test.output.classesDir.toString(),
"--bodies-folder", sourceSets.test.resources.srcDirs.toList().first().toString() + "/gatling/bodies",
]
}
While executing the tests:
./gradlew loadTest
I'm getting the following stacktrace:
21:00:12.804 [main] WARN io.netty.util.concurrent.DefaultPromise - An exception was thrown by org.asynchttpclient.netty.request.NettyRequestSender$1.operationComplete()
java.lang.NoSuchMethodError: io.netty.channel.DefaultChannelId.newInstance()Lio/netty/channel/DefaultChannelId;
at io.netty.channel.AbstractChannel.newId(AbstractChannel.java:111)
at io.netty.channel.AbstractChannel.<init>(AbstractChannel.java:83)
at io.netty.bootstrap.FailedChannel.<init>(FailedChannel.java:33)
at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:330)
at io.netty.bootstrap.Bootstrap.doResolveAndConnect(Bootstrap.java:163)
at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:156)
at org.asynchttpclient.netty.request.NettyChannelConnector.connect0(NettyChannelConnector.java:81)
at org.asynchttpclient.netty.request.NettyChannelConnector.connect(NettyChannelConnector.java:69)
at org.asynchttpclient.netty.request.NettyRequestSender$1.onSuccess(NettyRequestSender.java:292)
at org.asynchttpclient.netty.request.NettyRequestSender$1.onSuccess(NettyRequestSender.java:285)
at org.asynchttpclient.netty.SimpleFutureListener.operationComplete(SimpleFutureListener.java:24)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511)
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:485)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:424)
at io.netty.util.concurrent.DefaultPromise.addListener(DefaultPromise.java:162)
at io.netty.util.concurrent.DefaultPromise.addListener(DefaultPromise.java:33)
at org.asynchttpclient.netty.request.NettyRequestSender.sendRequestWithNewChannel(NettyRequestSender.java:285)
at org.asynchttpclient.netty.request.NettyRequestSender.sendRequestWithCertainForceConnect(NettyRequestSender.java:136)
at org.asynchttpclient.netty.request.NettyRequestSender.sendRequest(NettyRequestSender.java:107)
at org.asynchttpclient.DefaultAsyncHttpClient.execute(DefaultAsyncHttpClient.java:216)
at org.asynchttpclient.DefaultAsyncHttpClient.executeRequest(DefaultAsyncHttpClient.java:184)
at org.asynchttpclient.DefaultAsyncHttpClient.executeRequest(DefaultAsyncHttpClient.java:206)
at io.gatling.http.ahc.HttpEngine.warmpUp(HttpEngine.scala:96)
at io.gatling.http.protocol.HttpProtocol$$anon$1.$anonfun$newComponents$1(HttpProtocol.scala:62)
at io.gatling.core.protocol.ProtocolComponentsRegistry.comps$1(Protocol.scala:67)
at io.gatling.core.protocol.ProtocolComponentsRegistry.$anonfun$components$4(Protocol.scala:69)
at scala.collection.mutable.HashMap.getOrElseUpdate(HashMap.scala:82)
at io.gatling.core.protocol.ProtocolComponentsRegistry.components(Protocol.scala:69)
at io.gatling.http.action.HttpActionBuilder.lookUpHttpComponents(HttpActionBuilder.scala:25)
at io.gatling.http.action.sync.HttpRequestActionBuilder.build(HttpRequestActionBuilder.scala:33)
at io.gatling.core.structure.StructureBuilder.$anonfun$build$1(StructureBuilder.scala:34)
at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:122)
at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:118)
at scala.collection.immutable.List.foldLeft(List.scala:86)
at io.gatling.core.structure.StructureBuilder.build(StructureBuilder.scala:33)
at io.gatling.core.structure.StructureBuilder.build$(StructureBuilder.scala:32)
at io.gatling.core.structure.ScenarioBuilder.build(ScenarioBuilder.scala:38)
at io.gatling.core.structure.PopulationBuilder.build(ScenarioBuilder.scala:98)
at io.gatling.core.scenario.SimulationParams.$anonfun$scenarios$1(Simulation.scala:188)
at scala.collection.immutable.List.map(List.scala:283)
at io.gatling.core.scenario.SimulationParams.scenarios(Simulation.scala:188)
at io.gatling.app.Runner.run0(Runner.scala:95)
at io.gatling.app.Runner.run(Runner.scala:64)
at io.gatling.app.Gatling$.start(Gatling.scala:59)
at io.gatling.app.Gatling$.fromArgs(Gatling.scala:43)
at io.gatling.app.Gatling$.main(Gatling.scala:35)
at io.gatling.app.Gatling.main(Gatling.scala)
If I create the same project using SpringBoot 1.5.12.RELEASE, it works perfectly. I'm suspecting of the spring-boot-gradle-plugin since it changes according to the SpringBoot version.
If necessary I can create a project into github to demonstrate the problem. =)
I would appreciate if someone could help me!

I got fix this issue.
The problem was the version of the io.netty group used by the SpringBoot 2.0.1.RELEASE. It is using the version 4.1.23.Final which for some reason (maybe some change in scala) is not executing the gatling tests.
I did the downgrade to use the same version as SpringBoot 1.5.12.RELEASE, which is 4.0.51.Final. I had to add this configuration to the build.gradle:
{
// This build.gradle is the same that I posted above. For the sake of simplicity I just put the configuration that has been necessary to solve the problem.
// After dependencies{} section, I had to put this:
configurations.all {
resolutionStrategy {
eachDependency { DependencyResolveDetails details ->
if (details.requested.group == 'io.netty') {
details.useVersion "4.0.51.Final"
}
}
}
}
}
I don't think is the best solution since I'm reverting the io.netty version to use a older version, which can have some side effect. In my case I didn't have the option of downgrading the SpringBoot version. If you have the option to revert the SpringBoot version, I would recommend to do that.

Related

BootJar + MavenJar. Artifact wasn't produced by this build

I have a sample project with the following hierearhy:
Sample (root)
-- model (simple jar)
-- api (springboot jar)
I want to publish both generated jars: plain jar & bootJar to my localRepository.
gradlew clean build -xTest publishToMavenLocal
However, the following error occures:
* What went wrong:
Execution failed for task ':api:publishMavenJavaPublicationToMavenLocal'.
> Failed to publish publication 'mavenJava' to repository 'mavenLocal'
> Artifact api.jar wasn't produced by this build.
The root build.gradle is a follows:
plugins {
id 'java'
id "org.springframework.boot" version "2.2.5.RELEASE" apply false
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
}
group 'sample'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
ext {
artifactVersion = version
springBootVersion = "2.2.5.RELEASE"
}
allprojects {
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'maven'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
repositories {
mavenCentral()
jcenter()
}
}
subprojects {
apply plugin: "io.spring.dependency-management"
apply plugin: "maven-publish"
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencyManagement {
imports {
mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootVersion}"
}
}
dependencies {
implementation "org.springframework.boot:spring-boot-dependencies:${springBootVersion}"
}
publishing {
publications {
mavenJava(MavenPublication) {
groupId project.group
artifactId project.name
version project.version
from components.java
}
}
}
}
api build.gradle
apply plugin: 'org.springframework.boot'
dependencies {
compile project(":model")
implementation "org.springframework.boot:spring-boot-starter-web"
}
bootJar {
}
Adding bootJava task to api build.gradle allowes to publish the bootJar directly from api module, but the root publish task remains broken.
publishing {
publications {
bootJava(MavenPublication) {
artifact bootJar
}
}
}
I've tried almost every solution from docs & google, but none seem to work.
Can anyone explain, what is misconfigured?
Gradle version: 6.3
As stated by gradle documentation here:
Starting from Gradle 6.2, Gradle performs a sanity check before uploading, to make sure you don’t upload stale files (files produced by another build). This introduces a problem with Spring Boot applications which are uploaded using the components.java component
More explanation is available in the link above.
They propose the following workaround that I personally tried and worked for me :
configure the outgoing configurations
configurations {
[apiElements, runtimeElements].each {
it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
it.outgoing.artifact(bootJar)
}
}
here after the configuration from my build.gradle:
....
apply plugin: 'maven-publish'
...
configurations {
[apiElements, runtimeElements].each {
it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
it.outgoing.artifact(bootJar)
}
....
}
publishing {
publications {
myPublication(MavenPublication) {
groupId groupId
artifactId artifactId
version version
from components.java
versionMapping {
usage('java-api') {
fromResolutionOf('runtimeClasspath')
}
usage('java-runtime') {
fromResolutionResult()
}
}
}
}
repositories {
maven {
url azureRepoUrl
name azureRepoName
credentials {
username azureRepoUserName
password azureRepoAccessToken
}
}
}
}
Excerpt from
Starting from Gradle 6.2, the main jar task is disabled by the Spring Boot application, and the component expects it to be present. Because the bootJar task uses the same file as the main jar task by default, previous releases of Gradle would either:
publish a stale bootJar artifact
or fail if the bootJar task hasn’t been called previously
To simple workaround would be configuring the outgoing configurations. For multi-module Gradle project, place the below configuration in the service module(spring boot module).
dependencies {
.....
}
configurations {
[apiElements, runtimeElements].each {
it.outgoing.artifacts.removeIf {
it.buildDependencies.getDependencies(null).contains(jar)
}
it.outgoing.artifact(bootJar)
}
}
Note: There is no need for changing anything with artifactory task if it was configured correctly. This working solution has been tested with Gradle 6.4.1.
Don't try the alternate suggestion that they provided, because classifier attribute is deprecated in recent versions, also altering the bootJar task with custom configuration would result in improper uber jar construction, and if you extract the generated jar distributive, you could find the missing BOOT-INF directory and necessary META-INF/MANIFEST.MF values.
jar {
enabled = true
}
bootJar {
classifier = 'application'
}
Update:
From Spring Boot 2.5.0, jar task generates an additional jar archive which ends with -plain.jar. It may break someone's build if they have used some patterns like *.jar to copy the build archive, hence, to restrict the additional jar creation, the following jar task configuration code snippet should be used.
jar {
enabled = false
}
I could get this worked by just adding artifact bootJar in the publishing task as shown below and with out adding any configurations as suggested in the gradle documentation. I believe this could be working same as their first workaround in the documentation. Tested with gradle 6.5.1
publishing {
publications {
mavenJava(MavenPublication) {
artifact bootJar
artifact sourceJar {
classifier "sources"
}
}
}
}
project.tasks.publish.dependsOn bootJar
According to the 'Gradle' documentation under,
https://docs.gradle.org/current/userguide/upgrading_version_6.html#publishing_spring_boot_applications
Just add the following to the build.gradle file
jar {
enabled = true
}
bootJar {
classifier = 'application'
}
If you are using gradle kotlin dsl add the equivalent in your build.gradle. It worked for me
configurations {
val elements = listOf(apiElements, runtimeElements)
elements.forEach { element ->
element.get().outgoing.artifacts.removeIf { it -> it.buildDependencies.getDependencies(null).contains(tasks.jar.get())}
element.get().outgoing.artifact(tasks.bootJar.get())
}
}
For Spring Boot 2.5.0+, this configurations works for publishing the embedded jar, its sources and javadoc:
plugins {
id 'maven-publish'
id 'java-library'
}
jar {
enabled = false
}
java {
withSourcesJar()
withJavadocJar()
}
publishing {
publications {
publication(MavenPublication) {
artifact bootJar
from components.java
}
}
}

Spring Boot Test not working with Java 11

I'm trying to upgrade my existing Java 8 multi-project gradle application to Java 11. After fixing a few compilation issues, I ended up getting issues in test cases. When i run a test in Intellij, it throws the following error:
Error:java: Attempt to recreate a file for type {QueryDsl classes}
It is trying to generate the Querydsl classes but since those classes are already there, the test is throwing exception.
I'm using Java11, IntelliJ 2019, Gradle 5 to run the application.
These tests are working as expected in Java8.
I've no idea what is causing this error. Can anybody please help me in understanding this.
Code snippets are given below.
Root project build.gradle:
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.4.RELEASE)
classpath("net.ltgt.gradle:gradle-apt-plugin:0.21")
}
}
subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
task allDependencies(type: DependencyReportTask) {}
jar {
baseName = "${parent.name}-${project.name}"
}
sourceSets {
main {
java {
srcDirs 'src/main/java', 'build/generated/sources/main/java', 'build/generated/sources/annotationProcessor/java/main'
}
}
}
}
Sub-project build.gradle:
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'net.ltgt.apt'
bootJar {
baseName = "test"
version = "1.0.0"
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa: 2.1.4.RELEASE")
compile("com.querydsl:querydsl-core:4.1.3")
compile("com.querydsl:querydsl-jpa:4.1.3")
annotationProcessor(
"com.querydsl:querydsl-apt:4.1.3:jpa",
"javax.annotation:javax.annotation-api:1.3.2"
)
annotationProcessor("org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final")
testCompile("org.springframework.boot:spring-boot-starter-test:2.1.4.RELEASE")
testCompile("com.h2database:h2:2.1.4.RELEASE")
}
Integration test
#RunWith(SpringRunner.class)
#SpringBootTest(classes = MainClass.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ServiceImplTest {
#Autowired
private Service1Impl service;
#Test
public void getData() {
Data data = service.getData();
Assert.assertEquals(0, data.size());
}
}
I had the same issue and the problem was with the order of the dependencies in gradle. Somehow the java compiler in intellij can not work well.
Be sure you have this dependencies for QueryDSL
annotationProcessor group: 'com.querydsl', name: 'querydsl-apt', version: querydsl_version, classifier: 'jpa'
annotationProcessor group: 'org.hibernate.javax.persistence', name: 'hibernate-jpa-2.1-api', version: hibernate_jpa_version
annotationProcessor group: 'javax.annotation', name: 'javax.annotation-api', version: javax_annotation_version
Delete the out folder in your project just in case and rebuild with Ctrl+f9.
Note aside, executing build from gradle and test command worked fine. Check this out https://blog.jdriven.com/2018/10/using-querydsl-annotation-processor-with-gradle-and-intellij-idea/

Gradle kotlin in Gradle5.2 Unresolved reference: dependtest

A multi module project with Kotlin source code, which used to work, stops working after upgrading to Gradle 5.2, because the Kotlin classes from the compile project('depend-test') dependency are not found.
Attempted to change plugin version
already viewed https://github.com/gradle/gradle/issues/8980
i defind Test class in project('depend-test')
object Test {
const val test = "123"
}
i want to use Test class in project('test-test')
package com.example.test.controller
import com.example.dependtest.Test
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
#RestController
#RequestMapping
class TestController {
private val log = LoggerFactory.getLogger(TestController::class.java)
#GetMapping(value = ["/test"])
fun test() {
log.info(Test.test)
}
}
when i want to build project('test-test') to jar where i used gradle bootJar。 I get this error:
> Task :test-test:compileKotlin FAILED
e: /Users/houshuai/Documents/dev/demo/test/test-test/src/main/kotlin/com/example/test/controller/TestController.kt: (3, 20): Unresolved reference: dependtest
e: /Users/houshuai/Documents/dev/demo/test/test-test/src/main/kotlin/com/example/test/controller/TestController.kt: (22, 18): Unresolved reference: Test
Expected Behavior
The Kotlin classes in the compile project('depend-test') dependency should be found.
Current Behavior
The Kotlin classes in the compile project('depend-test') dependency are not found:
Try adding this to your build.gradle file
bootJar {
enabled = false
}
jar {
enabled = true
}
Just in case someone else comes across this problem.
I created two modules, test-test and depend-test.
The depend-test project is test-test 's dependency.
I tried to call the parameters of depend-test, but it failed to compile and package.
Env
gradle-5.2.1
Kotlin 1.3.31
Springboot 2.1.4
java 1.8
step one
Edit settings.gradle
rootProject.name = 'demo'
include ":depend-test"
include ":test-test"
project(":depend-test").projectDir = file("depend/depend-test")
project(":test-test").projectDir = file("test/test-test")
I used the 1.3.31 version of the kotlin plug-in. The build.gradle file reads as follows
buildscript {
ext {
kotlinVersion = '1.3.31'
}
repositories {
mavenCentral()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/'}
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion"
}
}
plugins {
id 'org.springframework.boot' version '2.1.4.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.2.71'
id 'org.jetbrains.kotlin.plugin.spring' version '1.2.71'
}
allprojects {
apply plugin: 'idea'
apply plugin: 'kotlin'
repositories {
mavenCentral()
}
}
subprojects {
apply plugin: 'kotlin'
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: "application"
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
repositories {
mavenLocal()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/'}
maven { url "https://plugins.gradle.org/m2/" }
mavenCentral()
jcenter()
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
maven { url 'http://maven.springframework.org/release' }
maven { url 'http://maven.springframework.org/milestone' }
}
version = '1.0'
apply plugin: 'io.spring.dependency-management'
group = 'com.mutil.test'
sourceCompatibility = '1.8'
compileKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ['-Xjsr305=strict']
jvmTarget = '1.8'
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
implementation 'org.jetbrains.kotlin:kotlin-reflect'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
}
dependencies {
subprojects.forEach {
archives(it)
}
}
repositories {
mavenCentral()
}
step two
build jar for test-test project ,I used two ways, but the results were the same.
terminal use cmd is ./gradlew :test-test:bootJar
user IDEA gradle tool
result
The class file written by kotlin in the submodule cannot be found.
I do not know if the lack of necessary plug-ins caused the failure to package properly.

java.lang.NoClassDefFoundError in Intellij Plugin

I'm trying to build a plugin for Intellij but I'm getting a java.lang.NoClassDefFoundError at runtime every time my code point to a class in another module or to an external library.
Everything works fine in my tests and in the sandbox via runIde.
I also managed to reproduce the error by creating a new project with just an action and a module with a class and an empty method.
root gradle:
buildscript {
ext.kotlin_version = '1.2.31'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id 'org.jetbrains.intellij' version '0.3.12'
}
group 'test'
version '1.0-SNAPSHOT'
apply plugin: 'kotlin'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile project(':testmodule')
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
intellij {
version '2018.1.6'
}
patchPluginXml {
changeNotes """
Add change notes here.
most HTML tags may be used"""
}
action:
package action
import com.intellij.openapi.actionSystem.*
import packages.OtherModuleClass
class TestAction : AnAction() {
override fun actionPerformed(e: AnActionEvent?) {
OtherModuleClass().otherModuleMethod()
}
}
other module class:
package packages
class OtherModuleClass {
fun otherModuleMethod() {}
}
I found out what my problem was.
I was installing in my IDE the jar in build/libs instead of the zip in build/distributions.
If someone else is looking for a solution for similar problem, I fixed it by adding the java plugin in build.gradle
apply plugin "java"

Spring boot executable jar can not resolve freemarker template

I am learning web application building with spring boot and java. I've got my app working when I run it through Spring Tool Suite but after I build executable jar using bootRepackage and run it, It's not able to resolve the freemarker views.
I am not sure what's wrong. Any help would be appreciated.
Following is my application.properties related to freemarker,
spring.http.encoding.charset=UTF-8
spring.freemarker.cache=false
spring.freemarker.charset=utf-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.enabled=true
spring.freemarker.suffix=.html
spring.freemarker.template-loader-path=classpath:/templates/,classpath:/templates/web/
My jar structure,
BOOT-INF
classes
com
scss
static
templates
web
story.html
app
application.properties
log4j2.xml
META-INF
org
my controller,
#Controller
public class HomeController {
#Autowired
private AppLog appLogger;
#RequestMapping("/")
public ModelAndView Index(HttpServletRequest request) {
appLogger.log(Level.ERROR,AppLogSource.Web, "Reached Controller", null);
String testAttribute = request.getAttribute("com.demo.test").toString();
Map<String, String> vm = new HashMap<String, String>();
vm.put("testAttribute", testAttribute);
return new ModelAndView("/web/story", vm);
}
}
I verified that I am hitting the log step so I think issue is in resolving the view but I could be wrong and missing something else. So let me know if you need more info.
Thanks again!
Best,
Mrunal
edit
Gradle File,
buildscript {
ext {
springBootVersion = '1.4.1.RELEASE'
}
repositories {
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("com.moowork.gradle:gradle-node-plugin:1.2.0")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
apply plugin: 'com.moowork.node'
apply plugin: 'com.moowork.grunt'
jar {
baseName = 'testDemo'
version = '0.0.1'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
node {
version = '6.11.3'
npmVersion = '3.10.10'
download = true
}
task gruntMinifyJs(type: GruntTask){
args=['minifyJs', '--debug']
}
task gruntMinifyCss(type: GruntTask){
args=['minifyCss', '--debug']
}
task buildFrontEnd(type: GruntTask) {
args = ['default', '--debug']
}
npmInstall.dependsOn(nodeSetup)
buildFrontEnd.dependsOn(npmInstall)
gruntMinifyCss.dependsOn(npmInstall)
gruntMinifyJs.dependsOn(npmInstall)
build.dependsOn(buildFrontEnd)
configurations {
all*.exclude group: 'ch.qos.logback', module:'logback-classic'
all*.exclude group: 'ch.qos.logback', module:'logback-core'
}
dependencies {
compile('org.springframework.boot:spring-boot-devtools')
compile('org.springframework.boot:spring-boot-starter-freemarker')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter:1.4.1.RELEASE'){
exclude group:'org.springframework.boot', module:'spring-boot-starter-logging'
}
compile('org.springframework.boot:spring-boot-starter-jdbc'){
exclude group:'org.apache.tomcat', module:'tomcat-jdbc'
}
compile('mysql:mysql-connector-java')
compile('com.zaxxer:HikariCP-java6:2.3.13')
compile('org.springframework.boot:spring-boot-starter-log4j2:1.4.1.RELEASE')
compile('com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.8')
compile('com.google.zxing:core:3.3.0')
compile('org.antlr:antlr4-runtime:4.5')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
edit 3,
further updates,
So I attached remote debugger and I found that spring is using ContentNegotiatingViewResolver to resolve the view as InternalResourceView but when I execute through spring tool suite it resolves properly to FreemarkerView.
I hope this helps someone to narrow down my issue. I'll see if I can get anywhere else in mean time by stepping through debugger.
Perhaps the freemarker jar file is not specified as a dependency in your spring boot application module. Unsure if you are running maven or gradle but do make sure you have the freemarker library included in your build.
See downloads # https://mvnrepository.com/artifact/org.freemarker/freemarker

Resources