I have the following folder structure:
-bin
-build/build.gradle (the gradle script)
-lib/[*.jar] (libraries that the project is using)
-src/folder/folder/[*.java] (project's source code)
The following content for the build.gradle script:
plugins {
id 'java'
id 'groovy'
}
buildDir = new File('../bin')
sourceCompatibility = JavaVersion.VERSION_1_8
sourceSets {
main {
java {
allJava.srcDirs = [ '../src/folder/folder/ ']
compileClasspath = fileTree('../bin')
}
}
}
repositories {
flatDir {
dirs '../lib'
}
}
dependencies {
implementation fileTree('../lib')
}
tasks.register('javac', JavaCompile) {
println 'Call javac'
source.forEach { e -> println e}
classpath = sourceSets.main.compileClasspath
destinationDirectory = file('../bin')
source sourceSets.main.allJava.srcDirs
includes.add('*.java')
sourceCompatibility = JavaVersion.VERSION_1_8
}
When running gradle javac I got the error: error: cannot find symbol import com...
The documentations clearly says:
dependencies {
.
.
.
//putting all jars from 'libs' onto compile classpath
implementation fileTree('libs')
}
I'm using Gradle 7.3.1
Allow me to give you some general advice first.
I can strongly recommend using the Kotlin DSL instead of the Groovy DSL.
You instantly get strongly typed code in the build scripts and much better IDE support.
Also you should imho consider changing your project layout to be more like most other Java projects out there and especially not use a libs directory, but use normal dependencies in a repository where transitive dependencies are then handled automatically and so on.
But to answer your actual question, this is the build complete build script in Groovy DSL that you want:
plugins {
id 'java'
}
buildDir = '../bin'
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(8))
}
}
sourceSets {
main {
java {
srcDirs = ['../src/folder/folder']
}
}
}
dependencies {
implementation fileTree('../lib')
}
And this is the matching Kotlin DSL version:
plugins {
java
}
setBuildDir("../bin")
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(8))
}
}
sourceSets {
main {
java {
setSrcDirs(listOf("../src/folder/folder"))
}
}
}
dependencies {
implementation(fileTree("../lib"))
}
Related
I am trying to build some java 1.6 application with aspects after migrating the build from some older gradle version to gradle 6.3. Because of the newer gradle version, I am using java 9.
The aspect compiler throws ClassCastException (link to log below), which, if I understand correctly, is caused by compiler not finding java.lang.Object class. I am only guessing it might something to do with using java 9 to run the build, but targeting java 1.6 compatibility. If this is the case, how do I tell the compiler where to find it? I tried to pass the -1.6 argument to ajc, but nothing changed.
I also include my build.gradle contents - I apologize it is not fully in gradle 6.3, because I got stuck on this aspectj compilation problem, before migrating it fully.
Thanks in advance for every response.
build.gradle contents:
buildscript {
repositories {
maven {
url "${artifactoryURL}/libs-releases"
}
}
dependencies {
classpath "io.freefair.gradle:aspectj-plugin:5.0.0-rc6"
classpath "gradle.plugin.org.myire:quill:2.3.1"
}
}
apply plugin: 'java'
apply plugin: 'io.freefair.aspectj.post-compile-weaving'
apply plugin: 'org.myire.quill.cobertura'
apply from: 'https://localnet/public/gradle/trunk/repositories.gradle'
java {
sourceCompatibility = JavaVersion.VERSION_1_6
}
group = "cz.svt"
version = "${version}"
aspectj {
version = "1.6.8"
}
configurations.all {
transitive = false
}
dependencies {
compile('avalon:avalon:4.2.0')
compile('cglib:cglib-nodep:2.2')
compile('commons-beanutils:commons-beanutils:1.7.0')
compile('commons-codec:commons-codec:1.3')
compile('commons-collections:commons-collections:3.1')
compile('org.apache.commons:commons-compress:1.4.1')
compile('commons-digester:commons-digester:1.6')
compile('commons-fileupload:commons-fileupload:1.1')
compile('commons-io:commons-io:1.3.1')
compile('commons-lang:commons-lang:2.0')
compile('commons-logging:commons-logging:1.0.4')
compile('commons-net:commons-net:2.0')
compile('commons-pool:commons-pool:1.2')
compile('commons-validator:commons-validator:1.1.3')
compile('com.ibm.db2:jdbc3-driver:9.5')
compile('dom4j:dom4j:1.6.1')
compile('org.codehaus.groovy:groovy-all:1.5.7')
compile('org.apache.xmlgraphics:fop:0.94')
compile('com.google.guava:guava:13.0.1')
compile('org.codehaus.groovy:groovy-all:1.5.7')
compile('cz.svt:hibernate-svt:3.6.8.Final')
compile('com.itextpdf:itextpdf:5.0.2')
compile('joda-time:joda-time:2.1')
compile('javax.servlet:jstl:1.0.6')
compile('junit:junit:3.8.1')
compile('log4j:log4j:1.2.15')
compile('mail:mail:1.0.3')
compile('org.springframework:spring-core:1.2.9')
compile('org.springframework:spring-beans:1.2.9')
compile('org.springframework:spring-mock:1.2.9')
compile('taglibs:standard:1.0.6')
compile('struts:struts:1.2.4')
compile('struts:struts-el:1.2.4')
compile('strutstest:strutstest:2.1.3-1.2-2.3')
compile('velocity:velocity:1.4')
compile('org.apache.ant:ant:1.7.1')
compile('org.apache.tomcat:jsp-api:6.0.18')
compile('org.apache.tomcat:servlet-api:6.0.18')
compile('org.apache.tomcat:catalina:6.0.18')
compile('org.apache.tomcat:dbcp:6.0.18')
compile('org.easymock:easymock:3.0')
compile('cz.svt:easymock-propeq:1.3')
compile('org.testng:testng:5.11:jdk15')
testCompile('org.apache.ftpserver:ftplet-api:1.0.0')
testCompile('org.apache.ftpserver:ftpserver-core:1.0.0')
testCompile('org.apache.mina:mina-core:2.0.0-M4')
testRuntime('org.slf4j:slf4j-api:1.6.1')
testRuntime('org.slf4j:slf4j-log4j12:1.6.1')
testRuntime('org.uncommons:reportng:1.0')
testRuntime('asm:asm:3.0')
testRuntime('asm:asm-tree:3.0')
testRuntime('org.hibernate:hibernate-commons-annotations:3.2.0.Final')
testRuntime('org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final')
testRuntime('javax.transaction:jta:1.1')
testRuntime('antlr:antlr:2.7.6')
testRuntime("org.objenesis:objenesis:1.2")
testRuntime("oro:oro:2.0.7")
}
test {
useTestNG() {
suites 'src/test/resources/testng.xml'
listeners << 'org.uncommons.reportng.HTMLReporter'
listeners << 'org.testng.reporters.XMLReporter'
}
}
task reports {
dependsOn coberturaTestReport, javadoc
}
here is link to aspectj compiler output 1
I've been asked to implement some gRPC classes for a college course, and have run into some problems when generating the java classes from one source proto file.
Some background first: it's a fairly basic service, with a simple method that receives an id and returns a phone and an email. This is the proto file (BuscarData means FetchData, sorry for the leftover non translation!):
syntax = 'proto3';
option java_multiple_files=true;
option java_generic_services= true;
package uy.edu.um.sd20;
message DataRequest {
int32 id = 1;
}
message DataResponse {
string phone = 1;
string email = 2;
}
service DataRepo {
rpc BuscarData (DataRequest) returns (DataResponse);
}
The idea I had was to generate the classes with gradle plugins. My build.gradle:
plugins {
id 'java'
id "com.google.protobuf" version '0.8.8'
}
apply plugin: 'java'
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.11.4'
implementation 'io.grpc:grpc-netty-shaded:1.29.0'
implementation 'io.grpc:grpc-protobuf:1.29.0'
implementation 'io.grpc:grpc-stub:1.29.0'
}
sourceSets {
main {
proto {
srcDir 'src/main/proto'
}
java {
srcDirs 'src/main/java', 'generated-sources/main/java'
}
}
}
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.11.0'
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.29.0'
}
}
generateProtoTasks.generatedFilesBaseDir = 'generated-sources'
generateProtoTasks {
all().each { task ->
// Here you can configure the task
}
ofSourceSet('main')
}
}
From what I understood, everything's there: the grpc and protoc dependencies, and the plugin which enables protoc to compile grpc (protoc-gen-grpc), and where to deposit the generated files.
However, there are two problems:
the generated-sources are not marked as source or anything like that, meaning they cannot be imported from other classes
if I'm not mistaken, the generated-sources should generate a skeleton of DataRepoImpl so that I can add the code needed for BuscarData. However, it didn't. Or maybe I should create it, extending from DataRepo.java, but I couldn't test it, due to problem n°1.
I've added a screenshot of the project file structure:
img
As you can see, quite a lot (if not all) of the gradle settings are copy-pasted and scavenged from many different web-sites. I hope I was careful enough not to repeat any imports. There are similar questions, and I tried the solutions there, but no luck there. One example, with which I knew I had to include the gen grpc plugin: another SO question
Any tip regarding anything else is welcome! I'm new to stackoverflow question-asking, so I may have made mistakes regarding the question specificity or aim of the question.
Thanks!
Franri.
For 1), the plugin should put the generated files are the input for java compile tasks even if you do not explicitly add 'generated-sources/main/java' in the sourceSets configuration. Version 0.8.8 has been a while, you can try with newer versions. There might have been some minor fixes for things you may hit.
For 2), you did not add grpc plugin to each generateProto task. It should be
generateProtoTasks {
all().each { task ->
task.plugins { grpc{} }
}
ofSourceSet('main')
}
I am trying to generate classes from multiple .xsds in gradle. Tried like below, but it does not work and i get error that file not exists.
buildscript {
ext {
springBootVersion = '1.5.4.RELEASE'
}
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("com.github.jacobono:gradle-jaxb-plugin:1.3.6")
}
}
apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin: 'org.springframework.boot'
apply plugin: 'war'
apply plugin: 'com.github.jacobono.jaxb'
version = '0.0.1-SNAPSHOT'
repositories {
mavenCentral()
}
configurations.all {
exclude module: 'spring-boot-starter-logging'
}
configurations {
jaxb
}
task createDirs {
file("$buildDir/generated-sources").mkdirs()
}
xjc.dependsOn createDirs
jaxb {
xsdDir = "src/main/resources/xsd"
xjc {
destinationDir = "$buildDir/generated-sources"
taskClassname = "org.jvnet.jaxb2_commons.xjc.XJC2Task"
generatePackage = "com.test.generated1"
args = ["-Xinheritance", "-Xannotate"]
}
}
compileJava {
dependsOn(xjc)
}
compileTestJava {
dependsOn(xjc)
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-log4j2')
compile('org.springframework.boot:spring-boot-starter-actuator')
jaxb('org.jvnet.jaxb2_commons:jaxb2-basics-ant:0.6.5')
jaxb('org.jvnet.jaxb2_commons:jaxb2-basics:0.6.4')
jaxb('org.jvnet.jaxb2_commons:jaxb2-basics-annotate:0.6.4')
jaxb('com.sun.xml.bind:jaxb-xjc:2.2.7-b41')
jaxb('com.sun.xml.bind:jaxb-impl:2.2.7-b41')
}
If i remove destinationDir = file("build/generated-sources"), it generates classes inside src/main/java which i do not want.
I get error .../build/generated-sources: non-existent directory
Any help is appreciated :)
NOTE: Gradle Version 3.2.1
Try using a variable for build directory "$buildDir/generated-sources"
Like vampire noticed you need to create the directory first.
I would suggest creating a task for it with doFirst() which will execute sooner on the execution phase.
task createDirs {
doFirst{
file("$buildDir/generated-sources").mkdirs()
}
}
and then run if before xjc:
xjc.dependsOn createDirs
And in this task particular task try to just pass the raw /build path because it seems like destinationDir already points to the root. Not sure what is going on here. Other than that I strongly sugest usign the variables $buildDir
jaxb {
xsdDir = "src/main/resources/xsd"
xjc {
destinationDir = "build/generated-sources"
taskClassname = "org.jvnet.jaxb2_commons.xjc.XJC2Task"
generatePackage = "com.test.generated1"
args = ["-Xinheritance", "-Xannotate"]
}
}
Another thing is you could watch on the directory changes if you don't want to run expensive xjc task all the time.
xjc {
inputs.dir ("$projectDir/src/main/resources/xsd")
outputs.dir ("$buildDir/generated-sources")
}
One point is that you should use the variable buildDir instead of using hard-coded 'build'.
That's not your problem though. Your problem is, that the plugin you are using does not create a non-existent target directory. So add the creation action to the task like
jaxb {
doFirst {
file("$buildDir/generated-sources").mkdirs()
}
}
Or if you prefer, create a separate task that does only the directory creation and then add a dependency from jaxb to your directory creation task.
I have a gradle build script. I want said script to generate QueryDSL-Metadata. Those metadata should be generated under the build/generated-sources/metamodel Folder.
The problem I am facing at the moment is that the metamodel is not only being generated once, but twice. Along with the desired target it is also being generated in the "default" buld/classes/... resulting in a "duplicate class"-error.
sourceSets {
generated.java.srcDirs=['build/generated-sources/metamodel']
main {
java { srcDir 'src/main/java' }
}
test {
java { srcDir 'src/main/test' }
}
}
configurations { querydslapt }
dependencies {
compile 'org.hibernate:hibernate-entitymanager:5.2.3.Final',
'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final-redhat-1',
'com.querydsl:querydsl-jpa:4.1.3',
// ... others, non-hibernate/querydsl ...
querydslapt 'com.querydsl:querydsl-apt:4.1.3'
}
task generateSources(type: JavaCompile, group: 'build', description:'Generates the QueryDSL query types') {
source = sourceSets.main.java
classpath = configurations.compile + configurations.querydslapt
options.compilerArgs = ['-proc:only',
'-processor', 'com.querydsl.apt.hibernate.HibernateAnnotationProcessor']
destinationDir = sourceSets.generated.java.srcDirs.iterator().next()
}
compileJava {
dependsOn generateSources
source generateSources.destinationDir
}
According to the gradle trace, the Problem appears to be that there are two AnnotatioProcessors in the mix. First, the HibernateAnnotationProcessor. Second, a JPAAnnotationProcessor, eventually generating the duplicate class. And I can't figure out why, the build script looks ok-ish. I know, it might be guesswork, but I am grateful for any suggestions. I even cleaned my gradle-cache, just in case. It might not even be a pure build-script related issue, but the behavior persists even if I run the script via console.
Gist, basically exactly what I "should" need
(older) Post regarding this issue
This thread's solution works for me, the idea is to hook the Annotation Processor into the javac, the HibernateAnnotationProcessor can be declared via compilerArgs, roughly like:
dependencies {
compile 'org.hibernate:hibernate-entitymanager:5.2.3.Final',
'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final-redhat-1',
'com.querydsl:querydsl-jpa:4.1.4',
'com.querydsl:querydsl-apt:4.1.4',
// other
}
ext {
generatedSourcesDir = file("build/generated-sources/metamodel")
}
sourceSets {
main {
java {
srcDir 'src/main/java'
srcDir generatedSourcesDir
}
}
test {
java { srcDir 'src/main/test' }
}
}
compileJava {
doFirst {
generatedSourcesDir.mkdirs()
}
options.compilerArgs += ['-s', generatedSourcesDir,
'-processor', 'com.querydsl.apt.hibernate.HibernateAnnotationProcessor']
}
But I still wonder why the first approach does not work (runs two annotation processors), so any idea is still highly appreciated.
Lombok makes Java great, gradle's an awesome, flexible build tool, Eclipse simplifies development significantly, and Javadocs make the world go round.
So when I started a new project, I wanted to figure out how to merge all this magic. Attached is the buildscript I wrote for this purpose, isolated from the other concerns of the project Save it somewhere accessible and include it using apply from: "path/to/lombok.gradle"
/**
* Project Lombok, Eclipse, Javadocs and Gradle
*/
// Doing this twice (once here, once in your main project) has no effect on Gradle, but
// this script depends on the Java and Eclipse plugins
apply plugin: 'java'
apply plugin: 'eclipse'
// Create a configuration to hold the lombok jar as a dependency
configurations {
lombok
}
// Add the lombok jar to the configuration
dependencies {
lombok 'org.projectlombok:lombok:+'
}
// Add the lombok configuration to all of the compile classpaths
sourceSets.each{ sourceSet ->
sourceSet.compileClasspath += configurations.lombok
sourceSet.ext.delombok = new File(buildDir, "generated-src/delombok/" + sourceSet.name);
}
// This task will download lombok and install it in your eclipse instance
task installLombok() {
dependsOn configurations.lombok
} << {
File jarFile = null;
configurations.lombok.resolvedConfiguration.resolvedArtifacts.find {
if ("lombok".equals(it.name)) {
jarFile = it.file;
}
}
javaexec {
main="-jar"
args = [
jarFile,
"install",
"auto"
]
}
}
// Install lombok into eclipse when you set up the project (optional line)
eclipseProject.dependsOn installLombok
// Javadoc doesn't handle lombok'd code, so we have to "delombok" it - that is, expand the
// neat annotations so that Javadoc can do something with them.
task delombok() {
dependsOn configurations.compile
dependsOn configurations.lombok
} << {
File jarFile = null;
configurations.lombok.resolvedConfiguration.resolvedArtifacts.find {
if ("lombok".equals(it.name)) {
jarFile = it.file;
}
}
sourceSets.each{ sourceSet ->
def classPath = sourceSet.compileClasspath.files.join(";")
def delombokPath = sourceSet.ext.delombok
delombokPath.mkdirs();
javaexec {
main = "-jar"
args jarFile, "delombok"
if (!classPath.empty) {
args "-c", classPath
}
args "-d", delombokPath
args sourceSet.allJava.srcDirs
}
}
}
javadoc {
dependsOn delombok
// At your discretion; I actually use ext.apiDelombok in my case
source = sourceSets.main.ext.delombok
}