Hej everyone,
I am trying to migrate a small spring boot project from java 8 to kotlin.
I ran into an issue where i have the following configuration class
#EnableCaching
#Configuration
open class CacheConfiguration : CachingConfigurer {
#Bean
override fun cacheManager(): CacheManager {
return ConcurrentMapCacheManager()
}
#Bean
override fun cacheResolver(): CacheResolver {
return SimpleCacheResolver(cacheManager())
}
/**
* Simple Key Generator
* #return not null
*/
#Bean
override fun keyGenerator(): KeyGenerator {
return SimpleKeyGenerator()
}
#Bean
override fun errorHandler(): CacheErrorHandler {
return SimpleCacheErrorHandler()
}
}
This is the actual class. This is literaly the first and only kotlin class in my project.
Starting the project now with gradle bootRun results in a Nullpointer exception in
AutoProxyRegistrar.java#L63
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
Object mode = candidate.get("mode"); <-- candidate is null
It tries to retrieve Annotation Attributes, which works well for the 2 Annotations i provided
#EnableCaching
#Configuration
Though it seems that kotlin adds a new annotation called kotlin.Metadata
which seemingly can not be processed.
build.gradle
buildscript {
ext {
ext.kotlin_version = '1.0.5-2'
springBootVersion = '1.4.3.RELEASE'
asciiDoctorVersion = '1.5.2'
snippetsDir = file('build/generated-snippets')
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("org.asciidoctor:asciidoctor-gradle-plugin:${asciiDoctorVersion}")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}")
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
apply plugin: 'kotlin'
apply plugin: 'org.asciidoctor.convert'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
task wrapper(type: Wrapper) {
gradleVersion = '2.14'
}
test {
outputs.dir snippetsDir
testLogging {
events "passed", "skipped", "failed", "standardError"
}
}
task stage {
dependsOn build
}
asciidoctor {
attributes 'snippets': snippetsDir
inputs.dir snippetsDir
dependsOn test
}
// Force ./gradlew cleanTest
allprojects {
tasks.matching { task -> task.name == "test" }.all {
outputs.upToDateWhen { false }
}
}
dependencies {
compile(group: 'org.springframework.boot', name: 'spring-boot-starter')
compile(group: 'org.springframework.boot', name: 'spring-boot-starter-web')
compile(group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa')
compile(group: 'org.springframework.boot', name: 'spring-boot-starter-actuator')
compile(group: 'org.springframework.boot', name: 'spring-boot-starter-security')
compile(group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: '2.0.10.RELEASE')
compile(group: 'org.springframework.security', name: 'spring-security-jwt', version: '1.0.4.RELEASE')
compile(group: 'org.postgresql', name: 'postgresql', version: '9.4.1209.jre7')
testCompile(group: 'com.jayway.restassured', name: 'rest-assured', version: '2.9.0')
testCompile(group: 'org.springframework.boot', name: 'spring-boot-starter-test')
}
Reproducible Sample
I have created a small repository to reproduce this issue.
https://github.com/spring-projects/spring-framework-issues/pull/145
And This https://jira.spring.io/browse/SPR-15055
This was an actual bug which was fixed here https://jira.spring.io/browse/SPR-15055
Related
I was following here. I used postgresql instead of h2. I was able to build the project with some additional fields.
I created a package database under com.example.demo, but it was still empty after project was built.
build.gradle:
buildscript {
ext {
springBootVersion = '2.4.2'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath 'org.jooq:jooq-codegen:3.14.4'
classpath 'org.postgresql:postgresql:42.2.18'
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '15'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-jooq'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.flywaydb:flyway-core'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
import org.jooq.codegen.GenerationTool
import org.jooq.meta.jaxb.*
task generate {
def configuration = new Configuration()
configuration
.withJdbc(new Jdbc()
.withDriver('org.postgresql.Driver')
.withUrl('jdbc:postgresql://localhost:5432/vertx')
.withUser('postgres')
.withPassword('postgres'))
.withGenerator(new Generator()
.withDatabase(new Database().withInputSchema('public'))
.withGenerate(new Generate()
.withPojos(true)
.withDaos(true))
.withTarget(new Target()
.withPackageName('com.example.demo.database')
.withDirectory('src/main/java')))
doLast {
GenerationTool.generate(configuration)
}
}
Is there something I am missing? Why can I not see pojos and daos in database package? My database has only one table with 2 columns.
BUILD SUCCESSFULL when I type ./gradlew generate, but nothing gets generated.
You can try ./gradlew generate --info command, which will give you more information about the build process.
My gradle script is quite similar to yours. By using above command, I find out that the classes are actually generated, but in a different folder /Users/{MyUserName}/.gradle/daemon/7.1.1/src/main/java.
So I have to explicitly set the output directory with def outputDirectory = projectDir.toString() + '/src/main/java'.
This works for me
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'org.jooq:jooq-codegen:3.16.2'
classpath 'mysql:mysql-connector-java:8.0.27'
}
}
plugins {
id 'org.springframework.boot' version '2.6.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
if(JavaVersion.current() != JavaVersion.VERSION_11){
throw new GradleException("This build must be run with java 11")
}
repositories {
mavenCentral()
}
group = 'snorlax'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
//create a fat Jar with all dependencies
jar {
duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
from {
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
manifest {
attributes "Main-Class": "com.snorlax.userservice.MainApplication"
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
dependencies {
// Spring boot
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// Swagger
implementation group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// RDS Connection
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'mysql:mysql-connector-java:8.0.27'
// AWS secretes manager
implementation 'com.amazonaws.secretsmanager:aws-secretsmanager-jdbc:1.0.6'
// JOOQ
implementation 'org.springframework.boot:spring-boot-starter-jooq'
implementation 'org.jooq:jooq-meta:3.16.2'
compileOnly 'org.jooq:jooq-codegen:3.16.2'
}
test {
useJUnitPlatform()
}
/************************
jooq code generation
*************************/
import org.jooq.codegen.GenerationTool;
import org.jooq.meta.jaxb.*;
task generate {
def outputDirectory = projectDir.toString() + '/src/main/java'
def configuration = new Configuration()
.withJdbc(new Jdbc()
.withDriver('com.mysql.cj.jdbc.Driver')
.withUrl('jdbc:mysql://127.0.0.1:3306/snorlaxRds')
.withUser('root')
.withPassword('123456'))
.withGenerator(new Generator()
.withDatabase(new Database().withInputSchema("snorlaxRds"))
.withGenerate(new Generate()
.withPojos(true)
.withDaos(true))
.withTarget(new Target()
.withPackageName('snorlax.userservice.database')
.withDirectory(outputDirectory)));
doLast {
GenerationTool.generate(configuration)
}
}
Your file looks okay. I had a similar issue (while using maven). Try three things (that worked for me):
check case of the schema in "withInputSchema" property. Try to pass uppercase PUBLIC.
try to change 'src/main/java' to './src/main/java'
add "includes" and pass .* in it (to generate for all tables in the schema)
so I've added a png img to my resources, since I want to use it in my project.
But Gradle seems not to let me build the project anymore, it's giving me the following error:
* What went wrong:
Execution failed for task ':processResources'.
> Could not copy file 'C:\workspace\Java\Utilities\EmailService\src\main\resources\img\watermark.png' to 'C:\workspace\Java\Utilities\EmailService\build\resources\main\img\watermark.png'.
Important part of Stacktrace is:
Caused by: groovy.lang.GroovyRuntimeException: Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): startup failed:
SimpleTemplateScript28.groovy: 4: illegal string body character after dollar sign;
solution: either escape a literal dollar sign "\$5" or bracket the value expression "${5}" # line 4, column 99.
o¿dHÌIDATx^Ý?╝$Eı┼Ù¥Ö┘]r♫↕$-↓$g%(êê
^
My setup of the project:
build.gradle:
import java.text.SimpleDateFormat
import org.apache.tools.ant.filters.ReplaceTokens
buildscript {
ext {
springBootVersion = '2.1.5.RELEASE'
set('springCloudVersion', 'Greenwich.RELEASE')
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
plugins {
id 'com.palantir.git-version' version '0.11.0'
}
def appName = 'EmailService'
version = '1.1.5'
group = 'dk.xx.email'
if (!hasProperty('mainClass')) {
ext.mainClass = 'dk.xx.email.EmailApplication'
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'maven-publish'
apply plugin: 'com.palantir.git-version'
sourceCompatibility = 1.8
repositories {
maven {
credentials {
username XXX
password XXXXXXX
}
url 'http://maven01.local:8080/repository/XX/'
}
mavenCentral()
maven { url 'https://jitpack.io' }
}
bootJar {
baseName = "${appName}"
version = "${version}"
}
dependencies {
compile('net.sf.jt400:jt400:9.5:jt400_jdk8')
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-actuator')
compile group: 'org.springframework', name: 'spring-mock', version: '2.0.8'
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-eureka-client', version: '2.1.0.RELEASE'
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '2.1.0.RELEASE'
compile group: 'xx', name: 'NhoData-Entities', version: '0.1.99'
compile group: 'xx', name: 'xx-Entities', version: '2.1.7'
compile('dk.xx.stakeholder.document.archive:DocumentArchive:1.1.10:proxy')
compile group: 'com.itextpdf', name: 'itext7-core', version: '7.0.4'
compile('dk.xx.gui.start:EngagementGui:1.2.2:proxy')
compileOnly("org.projectlombok:lombok:1.18.6")
annotationProcessor group: 'org.springframework.boot', name: 'spring-boot-configuration-processor'
annotationProcessor 'org.projectlombok:lombok:1.18.6'
testCompile('org.springframework.boot:spring-boot-starter-test')
compile('org.springframework.boot:spring-boot-starter-mail')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
// Auto-produce swagger
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
}
task versionTxt() {
doLast {
def versionFile = new File("$projectDir/.ci/version.txt");
versionFile.getParentFile().mkdir();
versionFile.text = """
Version=$version
BuildTime=${new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date())}
ApplicationName=${appName}
"""
}
}
def dependencyName = "${appName}-proxy-${version}"
task tJar(type: Jar, dependsOn: compileJava) {
archiveName = "${dependencyName}.jar"
classifier = 'proxy'
from(sourceSets.main.output) {
includeEmptyDirs=false
include '**/feign/*'
include '**/domain/*'
include '**/entities/*'
}
}
task sourcesJar(type: Jar) {
classifier = 'sources'
from sourceSets.main.allJava
}
publishing {
publications {
maven(MavenPublication) {
artifacts {
groupId "${group}"
artifactId "${appName}"
version "${version}"
}
artifact tJar
artifact sourcesJar
}
repositories.maven {
url 'http://maven01.local:8080/repository/xx/'
credentials {
username xx
password xxxxxxxx
}
}
}
}
processResources {
filter(ReplaceTokens, tokens:[gitVersion: gitVersion()])
expand(project.properties)
}
static def buildTime() {
final dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
dateFormat.timeZone = TimeZone.getTimeZone('UTC')
dateFormat.format(new Date())
}
springBoot {
// This statement tells the Gradle Spring Boot plugin to generate a file
// build/resources/main/META-INF/build-info.properties
// that is picked up by Spring Boot to display via /actuator/info endpoint.
buildInfo {
// Generate extra build info.
properties {
def details = versionDetails()
additional = [
by : System.properties['user.name'],
time : buildTime(),
operatingSystem : "${System.properties['os.name']} (${System.properties['os.version']})",
machine : InetAddress.localHost.hostName,
ci_enabled : System.getenv('CI') ? true : false,
ci_buildNumber : System.env.'BUILD_NUMBER' ?: 'UNKNOWN',
ci_jobName : System.env.'JOB_NAME' ?: 'UNKNOWN',
appVersion : version
]
}
}
}
I think it's the filter statement in your processResources config. You're asking Gradle to replace text inside the PNG, but it can't make sense of the text in the PNG (which is because there is no text in it; probably doesn't conform to any reasonable character encoding).
I have a project in the Eclipse IDE that using the gradle plugin and its working and running successfully within the IDE, However, when I export the project into a jar file using eclipse and run it via cmd, java -jar test1.jar, I get this reoccurring error:
"Caused by: java.lang.NoSuchMethodError:org.apache.log4j.Logger.getLoggerRepository()Lorg/apache/log4j/spi/LoggerRepository;"
From my understanding the log4j-1.2.17.jar file is being retrieved by gradle and is packaged when exported to a runnable jar, using eclipse, but I still get this error.
build.gradle:
buildscript {
ext {
springBootVersion = '1.5.6.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.7
repositories {
mavenCentral()
flatDir {
dirs 'F:/flatRepo'
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.session:spring-session')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
runtime('org.springframework.boot:spring-boot-devtools')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
runtime('org.hsqldb:hsqldb')
runtime('mysql:mysql-connector-java')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.security:spring-security-test')
//
// Dimensions dependencies
// log4j
compile group: 'log4j', name: 'log4j', version: '1.2.17'
// https://mvnrepository.com/artifact/javax.mail/mail
compile group: 'javax.mail', name: 'mail', version: '1.4.1'
// https://mvnrepository.com/artifact/commons-codec/commons-codec
compile group: 'commons-codec', name: 'commons-codec', version: '1.4'
// https://mvnrepository.com/artifact/javax.inject/javax.inject
compile group: 'javax.inject', name: 'javax.inject', version: '1'
}
task setHttpProxyFromEnv {
def map = ['HTTP_PROXY': 'http', 'HTTPS_PROXY': 'https']
for (e in System.getenv()) {
def key = e.key.toUpperCase()
if (key in map) {
def base = map[key]
def url = e.value.toURL()
println " - systemProp.${base}.proxy=${url.host}:${url.port}"
System.setProperty("${base}.proxyHost", url.host.toString())
System.setProperty("${base}.proxyPort", url.port.toString())
}
}
}
build.dependsOn setHttpProxyFromEnv
Gradle project
Tying to implement grpc - unary API using java-gradle project
Build.gradle
group = "com.kaushik.grpc"
version = "1.0-SNAPSHOT"
apply plugin: 'java'
apply plugin: 'com.google.protobuf'
apply plugin: 'idea'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
}
}
repositories {
mavenCentral()
}
description = "gRPC Java Examples"
dependencies {
compile 'io.grpc:grpc-all:0.13.1'
}
protobuf {
protoc {
// The version of protoc must match protobuf-java. If you don't depend on
// protobuf-java directly, you will be transitively depending on the
// protobuf-java version that grpc depends on.
artifact = "com.google.protobuf:protoc:3.0.0-beta-2"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:0.13.1'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
greet.proto
syntax = "proto3";
package greet;
option java_package = "com.proto.greet";
option java_multiple_files = true;
message Greeting {
string first_name = 1;
string last_name = 2;
}
message GreetRequest {
Greeting greeting = 1;
}
message GreetResponse {
string result = 1;
}
service GreetService {
//unary
rpc Greet(GreetRequest) returns (GreetResponse) {};
}
while trying to extend GreetServiceGrpc
import com.proto.greet.GreetServiceGrpc;
public class GreetServiceImpl extends GreetServiceGrpc.GreetServiceImplBase{
}
Cannot resolve symbol GreetServiceImplBase.
There is no class with GreetServiceImplBase even in build path.
GreetServiceImplBase is generated based on the configuration(depedencies, generated source directories) in the gradle file. Sample entry in the gradle file :
dependencies {
compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.6.1'
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'io.grpc', name: 'grpc-stub', version: '1.16.1'
compile group: 'io.grpc', name: 'grpc-protobuf', version: '1.16.1'
compile group: 'io.grpc', name: 'grpc-netty', version: '1.16.1'
compile "io.grpc:grpc-all:1.16.1"
compile group: 'com.github.os72', name: 'protoc-jar', version: '3.6.0'
compile group: 'org.projectlombok', name:'lombok', version: '1.18.4'
compile 'com.google.protobuf:protobuf-java-util:3.6.1'
}
sourceSets {
main {
java {
srcDirs = ["src/main/java/", "src/generated/main/grpc/", "src/generated/main/java/"]
}
}
test {
java {
srcDirs = ["src/test/"]
}
}
}
idea {
module {
sourceDirs += file("${projectDir}/src/generated/main/java");
sourceDirs += file("${projectDir}/src/generated/main/grpc");
}
}
clean {
delete "$projectDir/src/generated"
}
Now execute the gradle task "generateProto"
I am trying to create implement client-server communication with the help of grpc
proto file -
syntax="proto3";
package com.project.grpc.roleservice;
message UserRequest {
string userName=1;
}
message RoleReply {
string userRole=1;
}
service UserRoleFromServer{
rpc getRoleUser(stream UserRequest) returns (stream RoleReply);
}
Gradle build -
buildscript {
ext {
springBootVersion = '2.0.4.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("com.google.protobuf:protobuf-gradle-plugin:0.8.5")
}
}
plugins {
id 'java'
}
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.google.protobuf'
group 'com.project.grpc.roleservice'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.5.1-1"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.16.1'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-web')
compile( 'io.grpc:grpc-netty-shaded:1.16.1')
compile('io.grpc:grpc-protobuf:1.16.1')
compile('io.grpc:grpc-stub:1.16.1')
compile 'io.github.lognet:grpc-spring-boot-starter:3.0.0'
runtime('org.springframework.boot:spring-boot-devtools')
runtime('mysql:mysql-connector-java')
testCompile (group: 'junit', name: 'junit', version: '4.12')
}
After building the project all the files are generated in a build folder and a UserRoleFromServerGrpc is generated which I want to extend and implement in my server-service file
But The UserRoleFromServerGrpc has a lot of errors it asks for following dependencies
Streamobserver needs io.grpc:grpc-stub:1.16.1 ,grpc-core
Add io.grpc:grpc-stub:1.16.1 to classpath
but I have already defined these dependencies in gradle build
How to resolve this issue
Screenshot of IDE