I am facing a problem that code generated using gradle-swagger-generator-plugin is not compiling due to unresolved dependencies.
I have a multimodule gradle project with the following folder structure. parent is the parent project with three subprojects named modules:apis, modules:api-client, and modules:common
.
├── parent
│ ├── build.gradle
│ ├── gbuild
│ ├── gradle
│ │ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── modules
│ │ ├── apis
│ │ │ ├── build.gradle.kts
│ │ │ ├── gbuild
│ │ │ └── src
│ │ ├── api-client (generated)
│ │ │ ├── README.md
│ │ │ ├── build.gradle
│ │ │ ├── build.sbt
│ │ │ ├── docs
│ │ │ ├── gbuild
│ │ │ ├── git_push.sh
│ │ │ ├── gradle
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ ├── pom.xml
│ │ │ ├── settings.gradle
│ │ │ └── src
│ │ └── common
│ │ ├── build.gradle.kts
│ │ ├── gbuild
│ │ └── src
│ ├── project_version.properties
│ └── settings.gradle.kts
Module :modules:apis is the spring boot REST service for which I want to generate client SDK. Module :modules:api-client is the placeholder project wherein the client code is generated.
Relevant sections from the modules/apis/build.gradle.kts are as given below.
plugins {
// Some plugins omitted for clarity
java
id("org.springframework.boot")
id("io.spring.dependency-management")
id("org.hidetake.swagger.generator") version "2.18.2"
}
dependencies {
// Other dependencies omitted
implementation (Libs.io_swagger_core)
swaggerCodegen("io.swagger.codegen.v3:swagger-codegen-cli:3.0.27")
}
swaggerSources {
create("testcode") {
// File api-spec is already generated and placed at the right location.
setInputFile(file("$projectDir/src/main/resources/swagger/api-spec.json"))
code(
closureOf<org.hidetake.gradle.swagger.generator.GenerateSwaggerCode> {
wipeOutputDir = true
language = "java"
configFile = file("$projectDir/src/main/resources/swagger/api-config.json")
outputDir = file(
"$rootDir/modules/client"
)
}
)
}
}
tasks.named("build") { dependsOn("generateSwaggerCode") }
What works: I can generate client code using gradle clean build in modules\apis and build it using .\gradle.bat clean build or using gradle clean build in modules\api-client.
What does not work: When I build the parent project using .\gradlew build --no-daemon --stacktrace --info in the parent folder, the task :modules:api-client:compileJava fails with compiler errors only for the first run. Compilation fails because gradle fails to resolve dependencies from modules\api-client\build.gradle. Compiler errors can be found in the attached file.
However, subsequent builds using the same command succeed without problem until modules\api-client folder is deleted manually.
Gradle version used by the parent project
\path\to\parent> .\gradlew.bat --version
------------------------------------------------------------
Gradle 6.7
------------------------------------------------------------
Build time: 2020-10-14 16:13:12 UTC
Revision: 312ba9e0f4f8a02d01854d1ed743b79ed996dfd3
Kotlin: 1.3.72
Groovy: 2.5.12
Ant: Apache Ant(TM) version 1.10.8 compiled on May 10 2020
JVM: 1.8.0_181 (Oracle Corporation 25.181-b13)
OS: Windows 10 10.0 amd64
Gradle version used by :modules:api-client subproject
\path\to\parent\modules\api-client> .\gradlew.bat --version
------------------------------------------------------------
Gradle 2.6
------------------------------------------------------------
Build time: 2015-08-10 13:15:06 UTC
Build number: none
Revision: 233bbf8e47c82f72cb898b3e0a96b85d0aad166e
Groovy: 2.3.10
Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM: 1.8.0_181 (Oracle Corporation 25.181-b13)
OS: Windows 10 10.0 amd64
I have tried this with all four combinations of options --build-cache and --no-parallel but got the same result. I am relatively new to gradle and took a wild guess that these two options may be playing role in this problem.
Any help in resolving this issue will be highly appreciated.
Thanks
Anand
You should put the generated classes in the buildDir (since you don't want to modifiy them as they get regenerated at each build) and then you need to add the generated class to your sourceSet.
In your build.gradle.kts add this:
configure<SourceSetContainer> {
named("main") {
java.srcDir("$buildDir/generated/src/main/java")
}
}
With the path being the one you specify in your swagger generation task.
Also on my case I set the dependency on the KotlinCompile task:
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
dependsOn("generateSwaggerCode")
kotlinOptions.jvmTarget = "11"
}
Make sure that this "generateSwaggerCode" does generate the code you need though (./gradlew generateSwaggerCode)
Related
I am trying to run a simple hello world spark application
This is my code
package com.sd.proj.executables
import org.apache.spark.sql.functions.lit
import org.apache.spark.sql.{DataFrame, SparkSession}
class SparkConn {
def getSparkConn(caller:String) : SparkSession = {
val conf = new SparkConf().setAppName(caller)
val spark: SparkSession = SparkSession.builder.config(conf).getOrCreate()
spark
}
}
object HelloSpark {
def sparkDF()(implicit spark:SparkSession):DataFrame = {
spark.emptyDataFrame
.withColumn("Title",lit("Hello World!!!"))
}
def main(args:Array[String]):Unit ={
val sparkConn = new SparkConn()
implicit val spark = sparkConn.getSparkConn(this.getClass.getName)
val df = sparkDF()
df.show(false)
spark.stop()
}
}
This is my build.gradle
plugins {
id 'scala'
id 'idea'
id 'org.scoverage' version '7.0.0'
}
repositories {
mavenCentral()
}
sourceSets{
main{
scala.srcDirs = ['src/main/scala']
resources.srcDirs = ['src/main/resources']
}
test{
scala.srcDirs = ['src/test/scala']
resources.srcDirs = ['src/test/resources']
}
}
dependencies {
//scala
implementation 'org.scala-lang:scala-library:2.12.15'
implementation 'org.scala-lang:scala-reflect:2.12.15'
implementation 'org.scala-lang:scala-compiler:2.12.15'
//spark
implementation 'org.apache.spark:spark-core_2.12:3.2.0'
implementation 'org.apache.spark:spark-sql_2.12:3.2.0'
//junit
testImplementation 'junit:junit:4.12'
testImplementation 'org.scalatestplus:scalatestplus-junit_2.12:1.0.0-M2'
}
scoverage{
scoverageVersion = "1.4.11"
minimumRate=0.01
}
task fatJar(type:Jar){
zip64 true
manifest {
attributes 'Implementation-Title': 'Gradle Fat Jar',
'Implementation-Version': '0.1',
'Main-Class': 'com.sd.proj.executables.HelloSpark'
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
baseName = project.name + '-fat'
from {
configurations.runtimeClasspath.collect {
it.isDirectory() ? it : zipTree(it)
}
}
with jar
}
and this is the project structure
.
├── README.md
├── build
│ ├── classes
│ │ └── scala
│ │ └── main
│ │ └── com
│ │ └── sd
│ │ └── proj
│ │ └── executables
│ │ ├── HelloSpark$.class
│ │ └── HelloSpark.class
│ ├── generated
│ │ └── sources
│ │ └── annotationProcessor
│ │ └── scala
│ │ └── main
│ ├── libs
│ │ ├── HelloSpark-fat.jar
│ │ └── HelloSpark.jar
│ └── tmp
│ ├── compileScala
│ ├── fatJar
│ │ └── MANIFEST.MF
│ ├── jar
│ │ └── MANIFEST.MF
│ └── scala
│ ├── classfileBackup
│ └── compilerAnalysis
│ ├── compileScala.analysis
│ └── compileScala.mapping
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
├── spark_submit.sh
└── src
├── main
│ ├── resources
│ └── scala
│ └── com
│ └── sd
│ └── proj
│ └── executables
│ └── HelloSpark.scala
└── test
├── resources
└── scala
my spark-submit script is
#!/bin/bash
echo "Running spark-submit..."
SPARK_HOME=/opt/homebrew/Cellar/apache-spark/3.2.1
export PATH="$SPARK_HOME/bin/:$PATH"
JARFILE=`pwd`/build/libs/HelloSpark-fat.jar
# Run it locally
echo "cmd : ${SPARK_HOME}/bin/spark-submit --class \"com.sd.proj.executables.HelloSpark\" --master local $JARFILE"
${SPARK_HOME}/bin/spark-submit --class "com.sd.proj.executables.HelloSpark" --master local $JARFILE
both scala and spark are installed on my mac
% type spark-submit
spark-submit is /opt/homebrew/bin/spark-submit
% type scala
scala is /opt/homebrew/opt/scala#2.12/bin/scala
When I run above spark-submit it fails saying
**Error: Failed to load class com.sd.proj.executables.HelloSpark.
**
% bash spark_submit.sh
Running spark-submit...
cmd : /opt/homebrew/Cellar/apache-spark/3.2.1/bin/spark-submit --class "com.sd.proj.executables.HelloSpark" --master local /Users/dsam05/IdeaProjects/HelloSpark/build/libs/HelloSpark-fat.jar
22/11/12 14:35:14 WARN Utils: Your hostname, Soumyajits-MacBook-Air.local resolves to a loopback address: 127.0.0.1; using 192.168.2.21 instead (on interface en0)
22/11/12 14:35:14 WARN Utils: Set SPARK_LOCAL_IP if you need to bind to another address
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.spark.unsafe.Platform (file:/opt/homebrew/Cellar/apache-spark/3.2.1/libexec/jars/spark-unsafe_2.12-3.2.1.jar) to constructor java.nio.DirectByteBuffer(long,int)
WARNING: Please consider reporting this to the maintainers of org.apache.spark.unsafe.Platform
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Error: Failed to load class com.sd.proj.executables.HelloSpark.
log4j:WARN No appenders could be found for logger (org.apache.spark.util.ShutdownHookManager).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
I have never run spark on a mac before, can someone please guilde what am I doing incorrectly here
this is on a M1 mac, macOS 13
Solved this problem, posting as it might help someone else
Removed task fatJar from my build.gradle
then added this config
plugins {
//added this entry on top of what is already present
id 'com.github.johnrengelman.shadow' version '7.1.2'
}
//...
//same config as in question above
//...
shadowJar{
zip64 true
}
now the jar is created as HelloSpark-all.jar
but runs perfectly
22/11/19 23:25:12 INFO CodeGenerator: Code generated in 88.62025 ms
22/11/19 23:25:12 INFO CodeGenerator: Code generated in 8.248958 ms
+--------------+
|Title |
+--------------+
|Hello World!!!|
+--------------+
22/11/19 23:25:12 INFO SparkUI: Stopped Spark web UI at http://localhost:4040
We have a gradle multi module project. api-1 is a dropwizard legacy project, and api-2 is the spring-boot project.
root-project
├── api-1
│ ├── build.gradle
│ ├── config
│ ├── libs
│ ├── src
│ │ ├── main
│ │ │ ├── java
│ │ │ └── resources
│ │ │ ├── META-INF
│ │ │ └── services
│ │ │ └── org.hibernate.integrator.spi.Integrator
├── api-2
│ ├── build.gradle
│ └── src
│ ├── main
│ │ └── resources
│ └── test
│ └── resources
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
We have our entities in api-1 which we are trying to use in api-2. So in api-2's build.gradle file I included implementation project(':api-2'). It feels a lil bit coarse to import the module along with all its transitive dependencies in to this module; but for now I does the trick.
The Issue:
The problem here is that api-1 has hibernate 5.2 dependency and it has this org.hibernate.integrator.spi.Integrator file in the resource folder. It references org.hibernate.jpa.event.spi.JpaIntegrator. Apparently this class was removed from hibernate from version 5.3 (ref: https://github.com/hibernate/hibernate-orm/blob/5.3/migration-guide.adoc#jpaintegrator-removed )
Now when I run (task bootRun) my api-2 module, I it fails with the below exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.util.ServiceConfigurationError: org.hibernate.integrator.spi.Integrator: Provider org.hibernate.jpa.event.spi.JpaIntegrator not found
What I Already Tried:
However if I delete this file (org.hibernate.integrator.spi.Integrator) from api-2, then api-2 runs and also api-1 seems to be running without any issues. But api-1 is a legacy project, and I am wary that it is wreck-less to simply remove the file without understanding it's implication fully.
I am trying to figure out if there is a safer way to get around this issue; maybe exclued that particular file in api-2. Or any better alternative?
I am having troubles with seting up 3 level gradle multi-project:
Level_1_Proj
│
├── Level_2_Proj_A
│ │
│ ├── Level_3_Proj_C
│ └── Level_3_Proj_D
│
└── Level_2_Proj_B
│
├── Level_3_Proj_E
└── Level_3_Proj_F
I would like to be able to:
set up dependencies between projects of the same level in the build script, like:
dependencies {
project('Level_2_Proj_A') {
dependencies {
implementation project('Level_2_Proj_B')
}
}
}
also want to be able to build (the subtree) starting the bash command [$gradle build] at any level [then build down the projects' subtree]
I have achieved building from the middle and bottom levels, but I cannot setup the build from the top level. Getting error:
A problem occurred evaluating project ‘Level_2_Proj_A’.
Project with path ‘Level_3_Proj_C’ could not be found in project ‘Level_2_Proj_A’.
Is it possible? If so, how to configure?
Thanks
Alright, here's how I managed to get it working. Given the following directory structure:
.
├── A
│ ├── C
│ │ └── build.gradle.kts
│ ├── D
│ │ └── build.gradle.kts
│ └── build.gradle.kts
├── B
│ ├── E
│ │ └── build.gradle.kts
│ ├── F
│ │ └── build.gradle.kts
│ └── build.gradle.kts
├── build.gradle.kts
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle.kts
The settings.gradle.kts has the following content:
rootProject.name = "multi-module-build"
include(":A")
include(":A:C")
include(":A:D")
include(":B")
include(":B:E")
include(":B:F")
Each build.gradle.kts has a call task that prints the name path of the project, e.g.
Inside the C project:
tasks.register("call") {
println(":A:C")
}
Inside the A project:
tasks.register("call") {
dependsOn(":A:C:call")
dependsOn(":A:D:call")
println(":A")
}
tasks["build"].dependsOn(":A:call")
The tasks["build"].dependsOn(":A:call") tells Gradle to invoke :A:call when building. The two dependsOn inside the call definition for A invoke the subproject call tasks.
There is a similar structure available for B.
When running gradle build at root level, this is the output I get:
:A
:B
:A:C
:A:D
:B:E
:B:F
When running gradle build inside the A subproject, I get:
:A
:A:C
:A:D
When running it inside :A:C, I don't get any output because I haven't specified that C's build task should depend on call, but that could easily be done.
Let me know if this doesn't work for you. I've used the Kotlin DSL for gradle, but you're perfectly free to change it to the Groovy variant.
I am following the book 'Gradle in Action' page 67 attempting to call:
$ gradle jettyRun
...
* What went wrong:
Execution failed for task ':jettyRun'.
> org/eclipse/jetty/http/HttpField
...
With the --stacktrace option I obtain the following message:
...
* Exception is:
org.gradle.api.tasks.TaskExecutionException:Execution failed for task ':jettyRun'
...
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.http.HttpField
...
My project is todo-webapp as per the book page 67:
$ tree
├── build.gradle
├── src
│ └── main
│ ├── java
│ │ └── com
│ │ └── manning
│ │ └── gia
│ │ └── todo
│ │ ├── model
│ │ │ └── ToDoItem.java
│ │ ├── repository
│ │ │ ├── InMemoryToDoRepository.java
│ │ │ └── ToDoRepository.java
│ │ └── web
│ │ └── ToDoServlet.java
│ └── webapp
│ ├── css
│ │ ├── base.css
│ │ └── bg.png
│ ├── jsp
│ │ ├── index.jsp
│ │ └── todo-list.jsp
│ └── WEB-INF
│ └── web.xml
and my build file is as follows:
$ cat build.gradle
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'jetty'
repositories {
mavenCentral()
}
dependencies {
providedCompile 'javax.servlet:servlet-api:2.5',
'javax.servlet.jsp:jsp-api:2.1'
runtime 'javax.servlet:jstl:1.1.2',
'taglibs:standard:1.1.2'
}
following various threads online I have been trying to add a dependency to my build file such as:
jettyRun {
dependencies {
providedRuntime 'org.eclipse.jetty:jetty-http:9.4.0.RC0'
}
}
or indeed add the jar directly /usr/share/java/jetty9-http with runtime files(...). None of these worked. I am not too sure what to try next. Any suggestion is greatly appreciated.
EDIT: As indicated by Vampire, all I had to do is remove apply plugin: 'jetty' and instead following the line apply plugin: 'war', add the line:
apply from: 'https://raw.github.com/akhikhl/gretty/master/pluginScripts/gretty.plugin'
Then use gradle appRun instead of gradle jettyRun. All this is coming from the page Getting started of the gretty plugin.
As you can see at https://docs.gradle.org/current/userguide/userguide_single.html#jetty_plugin, the Jetty plugin is deprecated. Maybe you should try the Gretty plugin as suggested in the docs. :-)
So I have:
buildSrc/
├── build.gradle
└── src
├── main
│ ├── groovy
│ │ └── build
│ │ ├── ExamplePlugin.groovy
│ │ └── ExampleTask.groovy
│ └── resources
│ └── META-INF
│ └── gradle-plugins
│ └── build.ExamplePlugin.properties
└── test
└── groovy
└── build
├── ExamplePluginTest.groovy
└── ExampleTaskTest.groovy
Question:
It seems like build.ExamplePlugin.properties maps directly to the build.ExamplePlugin.groovy. Is this the case? Seems terribly inefficient to have only one property in the file. Does it have to be fully qualified, i.e. does the name have to exactly match the full qualification of the class?
Now in the example, I see:
project.pluginManager.apply 'build.ExamplePlugin'
...however if I have that in my test, I get an error to the effect that the simple task the plugin defines, is already defined.
Why bother with test examples that require 'apply' when that is inappropriate for packaging?