Used kotlin-spring plugin, still getting class not open error - spring

I am getting a class cannot be final, needs to be open, despite adding the kotlin-spring plugin. The whole purpose of the plugin is to not manually add the open keyword to every class.
Please guide me on getting the Kotling-Spring plugin to work with code below.
build.gradle
buildscript {
ext.kotlin_version = "1.1.2"
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
}
}
apply plugin: "kotlin"
apply plugin: "kotlin-spring"
apply plugin: "kotlin-noarg"
apply plugin: "idea"
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
compile"org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
compile "org.springframework:spring-context:4.3.8.RELEASE"
testCompile "org.springframework:spring-test:4.3.8.RELEASE"
testCompile "junit:junit:4.11"
}
AppConfig.java
#Configuration
class AppConfig {
#Bean
fun game(): Game {
return BaseballGame(redSox(),cubs())
}
#Bean
fun redSox(): Team {
return RedSox()
}
#Bean
fun cubs(): Team {
return Cubs()
}
}
Error:
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: #Configuration class 'AppConfig' may not be final. Remove the final modifier to continue.
Offending resource: AppConfig
REF: https://kotlinlang.org/docs/reference/using-gradle.html#plugin-and-versions

Had the same problem. Enabling annotation processing in Intellij solved the issue:

Had similar problem. Couldn't run from IDE, but gradlew.bat build bootRun worked. Solved by updating Kotlin plugin in IDEA, from 1.2.40 to 1.2.41.

I too faced Similar Issue while Running Springboot Application . Finally I learnt that Kotlin Class are final by Default . You need to add open before class Name
So , you need to change class modifier as follows :
open class AppConfig {
Reference :
http://engineering.pivotal.io/post/spring-boot-application-with-kotlin/

Related

How resolve error injecting bean MapStruct in Spring

I'm trying to Inject my mapper using mapstruct, but spring doesn't recognize the bean.
There is my mapper
package com.api.gestioncartera.Services.Mappers;
import org.mapstruct.Mapper;
import org.springframework.stereotype.Component;
import com.api.gestioncartera.Entities.CollectionCompany;
import com.api.gestioncartera.Services.DTO.CollectionCompanyDto;
#Mapper(componentModel = "spring")
public interface CollectionCompanyMapper {
CollectionCompanyDto collectionCompanyToCollectionCompanyDto(CollectionCompany collectionCompany);
}
There is my Service where I'm trying to inject it
#Service
#Transactional
public class CollectionCompanyServiceImp implements CollectionCompanyService{
#Autowired
private CollectionCompanyMapper companyMapper;
}
My gradle config
plugins {
id 'org.springframework.boot' version '2.5.6'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
...
dependencies {
...
implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
compileJava {
options.compilerArgs += [
'-Amapstruct.suppressGeneratorTimestamp=true',
'-Amapstruct.suppressGeneratorVersionInfoComment=true',
'-Amapstruct.verbose=true',
'-Amapstruct.defaultComponentModel=spring'
]
}
I also enable enable annotation processing in the IDE
Properties in the IDE
The error is:
Consider defining a bean of type 'com.api.gestioncartera.Services.Mappers.CollectionCompanyMapper' in your configuration.
I noticed that I don't have any plugin referencing mapstruct, can be this the problem? Image:
I'm using Spring Tool Suite 4 (Eclipse) + Gradle 6.8 + SrpingBoot 2.5.6
Please help!!
Eclipse has its problems with annotation processing.
I solved the issue with my projects using this plugin:
https://plugins.gradle.org/plugin/
Add this to the top of your gradle plugins.
plugins {
id "eclipse"
id "com.diffplug.eclipse.apt" version "3.37.1"
}
then do a gradle refresh.
If it‘s still not working, run
./gradlew eclipse eclipseJdtApt eclipseFactorypath
Hope this helps!

Gradle not creating a Tomcat deployable war

I'm running into an issue with building a war with Gradle 4.8.1. Here is the build.gradle:
buildscript {
ext {
springBootVersion = '2.0.3.RELEASE'
}
repositories {
jcenter()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
}
}
apply plugin: 'idea'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'org.springframework.boot'
apply plugin: 'war'
archivesBaseName = 'sample'
//war {
// archiveName = 'sample.war'
// group = 'my.group'
// version = '2.0.0-SNAPSHOT'
//}
sourceCompatibility = 1.8
repositories {
jcenter()
maven { url "${nexusUrl}/content/groups/public" }
}
dependencies {
// Spring
compile 'org.springframework.boot:spring-boot-starter-actuator'
compile 'org.springframework.boot:spring-boot-starter-data-jpa'
compile 'org.springframework.boot:spring-boot-starter-log4j2'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
compile 'org.springframework.boot:spring-boot-starter-web'
testCompile 'org.springframework.boot:spring-boot-starter-test'
// Lombok
compile "org.projectlombok:lombok:1.18.0"
// Data
compile ('org.postgresql:postgresql') {
exclude module: 'slf4j-simple'
}
// Http
compile "org.apache.httpcomponents:httpclient:4.5.5"
}
configurations {
all*.exclude module: 'spring-boot-starter-logging'
}
uploadArchives {
repositories {
mavenDeployer {
repository(url: "${nexusUrl}/content/groups/public/") {
authentication(userName: nexusUsername, password: nexusPassword)
}
snapshotRepository(url: "${nexusUrl}/content/repositories/snapshots") {
authentication(userName: nexusUsername, password: nexusPassword)
}
pom.version = '2.0.0-SNAPSHOT'
pom.artifactId = 'sample'
pom.groupId = 'my.group'
}
}
}
I also tried removing the 'maven' plugin, archivesBaseName, and the uploadArchive task while uncommenting the war task and I get the same result. When using uploadArchive the war deploys to the nexus server fine and I get no errors. When deploying the war to tomcat (in both instances) tomcat 7 and 8 throw no errors and I receive no logs from either catalina or the project, although archiveName inside the war task does not properly rename the war. I have tried this on two other machines/tomcat instances with the same result. When building this as a fat jar, or running this in IntelliJ, everything works as expected (including the logging).
Any help or direction would be greatly appreciated.
It sounds like it is not initializing the servlet at all. Make sure to extend the SpringBootServletInitializer for WAR deployment.
Spring Boot Docs - Traditional Deployment
I was also facing the same issue. The issue is Spring application doesnt get initialized when the war is deployed on tomcat.
After a lot of struggle, I figured out that I needed to extend SpringBootServletInitializer in my application. So my effective code looks like
public class SyncApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SyncApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(SyncApplication.class, args);
}
}
Looks like this SpringBootServletInitializer directs war plugins generate bootstrapping code while building the war, and thus spring context is initialized while deploying the app.

Compilation fails using Gradle and Kotlin

I am going through the examples in Kotlin in Action book. The gradle buid script is as follows:
group 'kotlin-in-action'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.1.2-2'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
repositories {
mavenCentral()
}
apply plugin: 'java'
dependencies {
testCompile 'junit:junit:4.12'
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
compile "junit:junit:4.12"
compile 'junit:junit:4.12'
compile 'junit:junit:4.12'
}
sourceSets {
main.kotlin.srcDirs += 'src'
}
All the scripts compile except for two classes that uses junit.
package ch06.ex1_8_1_LateinitializedProperties
import org.junit.Before
import org.junit.Test
import org.junit.Assert
class MyService {
fun performAction(): String = "foo"
}
class MyTest {
private var myService: MyService? = null
#Before fun setUp() {
myService = MyService()
}
#Test fun testAction() {
Assert.assertEquals("foo",
myService!!.performAction())
}
}
The compiler says it can't find junit. I have tried adding the jar files in IntelliJ, but this has not resolved the problem. The jar files I have added are junit and hamscrest-core. This is all version 4.12.
I have resolved this. I had to add the Junit and hamcrest-core jar files from the mavan depository.

Gradle build with fatJar plugin and SpringBoot application gives 'Application startup failed'

Everything was working fine when starting my app using Intellij. But when I made fatJar (with gradle plugin: eu.appsatori.fatjar) and execute:
java -jar myapp.jar
I'm getting something like this:
11:41:01.224 [main] ERROR org.springframework.boot.SpringApplication - Application startup failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [my.testing.MyAppMain]; nested exception is java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.
at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:482)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:184)
...
It looks like it didn't found auto configuration classes in META-INF/spring.factories.
How to add this file? And what should be the content of it?
I've got following build script:
apply plugin: "java";
apply plugin: "idea";
apply plugin: 'application'
apply plugin: 'eu.appsatori.fatjar'
apply plugin: 'org.springframework.boot'
repositories {
mavenCentral()
}
buildscript {
ext {
springBootVersion = '1.4.3.RELEASE'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
}
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
resources {
srcDir 'src/main/resources'
}
}
test {
java {
srcDir 'src/test/java'
}
}
}
fatJar {
manifest {
attributes("Main-Class": 'my.testing.MyAppMain')
}
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.SF'
exclude 'META-INF/*.RSA'
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-jdbc'
runtime 'mysql:mysql-connector-java'
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
And my example code is:
package my.testing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
#SpringBootApplication
public class MyAppMain {
private ConfigurableApplicationContext springContext;
#Autowired
private SimpleDao dao;
public static void main(String[] args) throws Exception {
MyAppMain test = new MyAppMain();
try {
test.init();
test.doWhatYouGotToDo();
} finally {
test.stop();
}
}
private void doWhatYouGotToDo() {
System.out.println("Auto-wired dao: " + dao.hashCode());
System.out.println("Auto-wired jdbcTemplate: " + dao.jdbcTemplate.hashCode());
}
private void init() throws Exception {
springContext = SpringApplication.run(MyAppMain.class);
springContext.getAutowireCapableBeanFactory().autowireBean(this);
}
private void stop() throws Exception {
springContext.close();
}
}
#Component
class SimpleDao {
#Autowired
JdbcTemplate jdbcTemplate;
}
application.properties file:
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/some_db?useSSL=false&serverTimezone=UTC
spring.datasource.username = some_user
spring.datasource.password = some_pass
NOTE: This question is based on SpringBoot - making jar files - No auto configuration classes found in META-INF/spring.factories
where are all answers are referring to building with Maven. Please put only answers related to Gradle here.
Although I mostly use Maven for Spring and Gradle for Android, but here is the gradle way for a Spring project:
gradle clean build
gradle bootRepackage
Result:
Here is my build.gradle file:

Missing schema module for spring-cloud-stream

Trying to use the following example from Spring Docs
#Bean
public MessageConverter userMessageConverter() throws IOException {
AvroSchemaMessageConverter avroSchemaMessageConverter {
return new AvroSchemaMessageConverter(MimeType.valueOf("avro/bytes");
}
Using Gradle as follows
buildscript {
ext {
springBootVersion = '1.4.2.RELEASE'
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'org.springframework.boot'
dependencies {
compile('org.springframework.cloud:spring-cloud-stream')
compile('org.springframework.cloud:spring-cloud-starter-stream-kafka')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Camden.SR2"
}
}
Gradle is loading the correct version of spring-cloud-streams 1.1.0.RELEASE but it does not match with the Github Repo. The artifact is missing the org.springframework.cloud.stream.schema package/source.
Am I missing something here?
The artifact org.springframework.cloud:spring-cloud-starter-stream-kafka brings in spring-cloud-stream, spring-cloud-stream-codec and related dependencies like spring-integration. You would have to explicitly define org.springframework.cloud:spring-cloud-stream-schema.
Also, you don't need to specify 'org.springframework.cloud:spring-cloud-stream' as it will be part of org.springframework.cloud:spring-cloud-starter-stream-kafka via org.springframework.cloud:spring-cloud-stream-binder-kafka.

Resources