Gradle: cannot execute sql, driver not found - gradle

I have got the following gradle script. It results in No suitable driver found error which I found strange.
buildscript {
repositories{
maven {
url = 'http://localhost:8090/nexus/content/groups/public/'
}
}
dependencies {
classpath 'com.oracle:ojdbc6:11.2.0.4.0'
}
}
task sql << {
def url = 'jdbc:oracle:thin:#' + project.properties['db_hostname'] + ':' + project.properties['db_port'] + ':' + project.properties['db_sid']
println 'sql, db url:' + url
def driverName = 'oracle.jdbc.OracleDriver'
Class.forName(driverName).newInstance();
groovy.sql.Sql sql = groovy.sql.Sql.newInstance(
url,
project.properties['db_username'],
project.properties['db_password'],
driverName
)
}
The error is:
Tasks to be executed: [task ':sql']
:sql (Thread[main,5,main]) started.
:sql
Executing task ':sql' (up-to-date check took 0.0 secs) due to:
Task has not declared any outputs.
truncating, db url:jdbc:oracle:thin:#LOCALHOST:1521:orcl
:sql FAILED
:sql (Thread[main,5,main]) completed. Took 0.105 secs.
FAILURE: Build failed with an exception.
* Where:
Build file '/home/fran/projects/jua/build.gradle' line: 49
* What went wrong:
Execution failed for task ':sql'.
> No suitable driver found for jdbc:oracle:thin:#LOCALHOST:1521:orcl
* Try:
Run with --debug option to get more log output.

The driver jar is being loaded in a different classloader context than the Sql class. To fix it, try adding this:
// Add jars resolved by buildscript classpath configuration to the classloader which Sql will use
URLClassLoader loader = groovy.sql.Sql.class.classLoader
project.buildscript.configurations.classpath.each { File file ->
loader.addURL(file.toURL())
}
prior to the call to Sql.newInstance(). It will make all your classpath dependencies available to the Groovy classloader which loads the Sql class. The Class.forName() should not be neccesary.
See the discussion here for more information:
http://gradle.1045684.n5.nabble.com/using-jdbc-driver-in-a-task-fails-td1435189.html

For me that didn't work (Gradle 2.12).
But instead of performing:
Class.forName("org.h2.Driver")
I did:
groovy.sql.loadDriver("org.h2.Driver")
The Groovy Sql.loadDriver method does some nifty classloader stuff.

You should use something like this:
configurations {
db2database
}
buildscript {
dependencies {
classpath('com.ibm.db2:db2jcc4:10.5.5')//db2 driver for gradle task
}
}
dependencies {
db2database "com.ibm.db2:db2jcc4:10.5.5" //db2 driver for configuration
}
//load drivers for gradle tasks
configurations.db2database.each {
GroovyObject.class.classLoader.addURL(it.toURI().toURL())
}
....
Sql sql = Sql.newInstance(
envProps.getProperty('dbUri'),
envProps.getProperty('dbUsername'),
envProps.getProperty('dbPassword'),
envProps.getProperty('dbDriverClassName')
)
println sql.rows("SELECT * FROM TEST.TEST")

Related

How can I debug Gradle Worker Daemons in IntelliJ?

I am using Gradle Worker Daemons in a custom task to enable parallel work.
The Worker API can accommodate this using the processIsolation() method that causes the work to execute in a separate "worker daemon". These worker daemon processes will persist across builds and can be reused during subsequent builds. If system resources get low, however, Gradle will stop any unused worker daemons.
Note that this not the same as the Gradle Daemon.
I am using Gradle 7.5.1 and IntelliJ IDEA 2022.3.2 (Ultimate Edition).
Basic example - GenerateMD5 WorkAction
I have recreated the basic example in the Worker Daemon docs that will generate MD5 files, based on the example in the Gradle docs.
The exception is that I am using an external library, Apache Commons Codec, to generate the MD5.
// build.gradle.kts
import org.apache.commons.codec.digest.DigestUtils
buildscript {
repositories {
gradlePluginPortal()
mavenCentral()
}
dependencies {
classpath("commons-codec:commons-codec:1.15")
}
}
plugins {
`java-library`
}
repositories {
gradlePluginPortal()
mavenCentral()
}
abstract class GenerateMD5 : WorkAction<GenerateMD5.Parameters> {
interface Parameters : WorkParameters {
val sourceFile: RegularFileProperty
val md5File: RegularFileProperty
}
override fun execute() {
val sourceFile = parameters.sourceFile.asFile.get()
val md5File = parameters.md5File.asFile.get()
val md5Hex = DigestUtils.md5Hex(sourceFile.inputStream())
println("Generated MD5 for ${sourceFile.name}: $md5Hex")
md5File.writeText(md5Hex)
}
}
dependencies {
implementation("commons-codec:commons-codec:1.15")
}
abstract class CreateMD5 : DefaultTask() {
#get:InputFiles
abstract val source: ConfigurableFileCollection
#get:Classpath
abstract val codecClasspath: ConfigurableFileCollection
#get:OutputDirectory
abstract val destinationDirectory: DirectoryProperty
#get:Inject
protected abstract val workerExecutor: WorkerExecutor
#TaskAction
fun createHashes() {
val workQueue: WorkQueue = workerExecutor.processIsolation {
classpath.from(codecClasspath)
forkOptions {
maxHeapSize = "64m"
//debug = true
}
}
source.files.forEach { file ->
workQueue.submit(GenerateMD5::class) {
sourceFile.set(file)
md5File.set(destinationDirectory.file("${file.name}.md5"))
}
}
}
}
val createMd5 by tasks.registering(CreateMD5::class) {
group = "md5"
codecClasspath.from(configurations.runtimeClasspath)
destinationDirectory.set(temporaryDir)
source.from(
resources.text.fromString(
"""
blah
blah
some
file
""".trimIndent()
)
)
}
Running without debug
When I run ./gradlew createMd5, the task executes successfully.
Executing 'createMd5'...
> Task :createMd5
Generated MD5 for string12197505505076104021.txt: 7a55d3ab41f37979cd7cccc92b7fc8fa
BUILD SUCCESSFUL in 866ms
1 actionable task: 1 executed
Execution finished 'createMd5'.
Running with debug
I then try and enable debug mode:
#TaskAction
fun createHashes() {
val workQueue: WorkQueue = workerExecutor.processIsolation {
classpath.from(codecClasspath)
forkOptions {
maxHeapSize = "64m"
debug = true // enable debug
}
}
// ...
I put a breakpoint in DigestUtils.java
And I then run the task with the debug options enabled in Intellij
However, I get an error.
Executing 'createMd5'...
Starting Gradle Daemon...
Connected to the target VM, address: '127.0.0.1:59032', transport: 'socket'
Gradle Daemon started in 1 s 460 ms
ERROR: transport error 202: bind failed: Address already in use
ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)
JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports initialized [./src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c:735]
Could not write standard input to Gradle Worker Daemon 1.
java.io.IOException: Broken pipe
at java.base/java.io.FileOutputStream.writeBytes(Native Method)
at java.base/java.io.FileOutputStream.write(FileOutputStream.java:354)
at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)
at org.gradle.process.internal.streams.ExecOutputHandleRunner.forwardContent(ExecOutputHandleRunner.java:68)
at org.gradle.process.internal.streams.ExecOutputHandleRunner.run(ExecOutputHandleRunner.java:53)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
> Task :createMd5 FAILED
1 actionable task: 1 executed
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':createMd5'.
> A failure occurred while executing Build_gradle$GenerateMD5
> Failed to run Gradle Worker Daemon
> Process 'Gradle Worker Daemon 1' finished with non-zero exit value 2
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 6s
Disconnected from the target VM, address: '127.0.0.1:59032', transport: 'socket'
Execution finished 'createMd5'.
Attempts
I have tried killing the Gradle Daemon,
./gradlew --stop
but to no effect.
I have also tried killing the Gradle Daemon
pkill -f '.*GradleDaemon.*';
but this also did not work.
Please try attaching a remote debugger to the running gradlew command.
https://docs.gradle.org/current/userguide/troubleshooting.html#sec:troubleshooting_build_logic

jQAssistant command line stopped working after switching to 1.3.0

I'm used to configure the gradle build to use jQAssistent with (basically) this snippet in build.gradle:
project.ext["jqaversion"] = "1.3.0"
project.ext["jqacoreversion"] = "1.3"
configurations {
jqaRuntime
}
dependencies {
// jQA 1.2
// jqaRuntime("com.buschmais.jqassistant:commandline:${project.jqaversion}")
// jQA 1.3
jqaRuntime("com.buschmais.jqassistant:jqassistant-commandline:${project.jqaversion}")
jqaRuntime("com.buschmais.jqassistant.plugin:java:${project.jqacoreversion}")
jqaRuntime("com.buschmais.jqassistant.plugin:junit:${project.jqacoreversion}")
}
task removeJQAReport(type: Delete) {
delete 'jqassistant/report'
delete 'jqassistant/store'
}
task(jqascan, dependsOn: 'removeJQAReport', type: JavaExec) {
main = 'com.buschmais.jqassistant.commandline.Main'
classpath = configurations.jqaRuntime
args 'scan'
args '-p'
args 'jqassistant/jqassistant.properties'
args '-f'
args 'java:classpath::build/classes/main'
args 'java:classpath::build/classes/test'
}
task(jqaanalyze, type: JavaExec) {
main = 'com.buschmais.jqassistant.commandline.Main'
classpath = configurations.jqaRuntime
args 'analyze'
args '-r'
args 'jqassistant/jqassistant-rules'
}
task(jqa, dependsOn: ['jqascan', 'jqaanalyze']) {
jqaanalyze.mustRunAfter jqascan
}
task(jqs, type: JavaExec) {
main = 'com.buschmais.jqassistant.commandline.Main'
classpath = configurations.jqaRuntime
args 'server'
standardInput = System.in
}
This works fine until jQA 1.2.0. After updating to 1.3.0, I'm getting this exception:
2017-09-26 14:42:33.793 [main] INFO PluginConfigurationReaderImpl - Loaded jQAssistant plugins [Common, Core Analysis, JUnit, Java, XML].
2017-09-26 14:42:33.826 [main] INFO StoreFactory - Connecting to store at 'file:/C:/Users/jn/projects/jqa-with-gradle/jqassistant/store'
Exception in thread "main" java.lang.NoSuchFieldError: BOOLEAN
at org.neo4j.shell.ShellSettings.<clinit>(ShellSettings.java:42)
at sun.misc.Unsafe.ensureClassInitialized(Native Method)
at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:43)
at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:142)
at java.lang.reflect.Field.acquireFieldAccessor(Field.java:1088)
at java.lang.reflect.Field.getFieldAccessor(Field.java:1069)
at java.lang.reflect.Field.get(Field.java:393)
at org.neo4j.kernel.configuration.AnnotatedFieldHarvester.findStatic(AnnotatedFieldHarvester.java:47)
at org.neo4j.kernel.configuration.AnnotationBasedConfigurationMigrator.<init>(AnnotationBasedConfigurationMigrator.java:39)
at org.neo4j.kernel.configuration.Config.<init>(Config.java:106)
at org.neo4j.kernel.configuration.Config.<init>(Config.java:96)
at org.neo4j.kernel.impl.factory.PlatformModule.<init>(PlatformModule.java:127)
at org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.createPlatform(GraphDatabaseFacadeFactory.java:232)
at org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.initFacade(GraphDatabaseFacadeFactory.java:146)
at org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.newFacade(GraphDatabaseFacadeFactory.java:130)
at org.neo4j.graphdb.factory.GraphDatabaseFactory.newDatabase(GraphDatabaseFactory.java:101)
at org.neo4j.graphdb.factory.GraphDatabaseFactory.lambda$createDatabaseCreator$0(GraphDatabaseFactory.java:89)
at org.neo4j.graphdb.factory.GraphDatabaseBuilder.newGraphDatabase(GraphDatabaseBuilder.java:183)
at com.buschmais.xo.neo4j.embedded.api.FileDatastoreFactory.createGraphDatabaseService(FileDatastoreFactory.java:31)
at com.buschmais.xo.neo4j.embedded.api.FileDatastoreFactory.createGraphDatabaseService(FileDatastoreFactory.java:16)
at com.buschmais.xo.neo4j.embedded.api.EmbeddedNeo4jXOProvider.createDatastore(EmbeddedNeo4jXOProvider.java:24)
at com.buschmais.xo.impl.XOManagerFactoryImpl.<init>(XOManagerFactoryImpl.java:48)
m.buschmais.xo.impl.bootstrap.XOBootstrapServiceImpl.createXOManagerFactory(XOBootstrapServiceImpl.java:39)
at com.buschmais.xo.api.bootstrap.XO.createXOManagerFactory(XO.java:43)
at com.buschmais.jqassistant.core.store.impl.AbstractGraphStore.start(AbstractGraphStore.java:49)
at com.buschmais.jqassistant.commandline.task.AbstractTask.run(AbstractTask.java:67)
at com.buschmais.jqassistant.commandline.Main.executeTask(Main.java:253)
at com.buschmais.jqassistant.commandline.Main.interpretCommandLine(Main.java:205)
at com.buschmais.jqassistant.commandline.Main.run(Main.java:91)
at com.buschmais.jqassistant.commandline.Main.main(Main.java:62)
:jqascan FAILED
You may find a complete example at https://github.com/kontext-e/jqa-gradle
Maven projects work fine, a command line jQA version is not available to download for 1.3 (only 1.2 is there).
Any ideas? Do I have to specify the Neo4j Version explicitely for 1.3?
Apparently it is a Gradle classpath problem since the jQAssistant commandline distribution works fine. So I modified the build.gradle file the following way:
dependencies {
jqaRuntime("com.buschmais.jqassistant:jqassistant-commandline:${project.jqaversion}") {
// because jQA 1.3 comes with Neo4j 2 and 3 support, there would be a classpath conflict
exclude module: 'neo4j'
}
jqaRuntime("com.buschmais.jqassistant.plugin:java:${project.jqaversion.substring(0, 3)}")
jqaRuntime("com.buschmais.jqassistant.plugin:junit:${project.jqaversion.substring(0, 3)}")
}
The mentioned example at https://github.com/kontext-e/jqa-gradle is also updated this way.

ClassNotFoundException in buildscript when using the mysql-connector

I'm getting a ClassNotFoundException with the message java.lang.ClassNotFoundException: com.mysql.jdbc.Driver when i run the generateTestDatabaseJooqSchema task from this jooq plugin. I don't know why this would be, since I included mysql:mysql-connector-java:6.0.5 in the buildscript dependencies on line 7.
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'mysql:mysql-connector-java:6.0.5'
classpath 'nu.studer:gradle-jooq-plugin:2.0.0'
}
}
plugins {
id 'nu.studer.jooq' version '2.0.0'
id 'org.flywaydb.flyway' version '4.0.3'
}
apply plugin: 'java'
apply plugin: 'idea'
// database connection information
def database_name = 'cloudpass-api'
def database_url = 'jdbc:mysql://localhost:3306/cloudpass-api'
def database_user = 'root'
def database_pass = 'password'
jooq {
testDatabase(sourceSets.main) {
jdbc {
driver = 'com.mysql.jdbc.Driver'
url = database_url
user = database_user
password = database_pass
schema = database_name
}
generator {
name = 'org.jooq.util.JavaGenerator'
database {
name = 'org.jooq.util.mysql.MySQLDatabase'
inputSchema = database_name
}
generate {
relations = true
deprecated = false
records = true
immutablePojos = true
fluentSetters = true
}
target {
packageName = 'cloudpass.database'
}
}
}
}
flyway {
url = database_url
user = database_user
password = database_pass
}
repositories {
jcenter()
mavenCentral()
}
dependencies {
compile 'org.slf4j:slf4j-api:1.7.21'
compile 'mysql:mysql-connector-java:6.0.5'
compile 'org.jooq:jooq'
compile 'com.maxmind.geoip2:geoip2:2.8.0'
testCompile 'junit:junit:4.12'
}
This is the full output I get, when I run the task:
C:\Users\Thomas\Projects\cloudpass-api-java>gradle generateTestDatabaseJooqSchemaSource
Starting a Gradle Daemon (subsequent builds will be faster)
:generateTestDatabaseJooqSchemaSource
nov. 06, 2016 7:54:15 AM org.jooq.tools.JooqLogger info
INFO: Initialising properties : C:\Users\Thomas\Projects\cloudpass-api-java\build\tmp\jooq\config.xml
nov. 06, 2016 7:54:16 AM org.jooq.tools.JooqLogger error
SEVERE: Cannot read C:\Users\Thomas\Projects\cloudpass-api-java\build\tmp\jooq\config.xml. Error : com.mysql.jdbc.Driver
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.jooq.util.GenerationTool.loadClass(GenerationTool.java:591)
at org.jooq.util.GenerationTool.run(GenerationTool.java:248)
at org.jooq.util.GenerationTool.generate(GenerationTool.java:198)
at org.jooq.util.GenerationTool.main(GenerationTool.java:170)
:generateTestDatabaseJooqSchemaSource FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':generateTestDatabaseJooqSchemaSource'.
> Process 'command 'C:\Program Files\Java\jdk1.8.0_101\bin\java.exe'' finished with non-zero exit value -1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 7.831 secs
I'm still not really comfortable with gradle so this might be a noob question, so i appreciate any help you can give.
This does not work as according to the documentation you need to put the appropriate database drive class to the special jooqRuntime configuration:
Depending on which database you are connecting to, you need to put the
corresponding driver on the generator's classpath.
dependencies { jooqRuntime 'postgresql:postgresql:9.1-901.jdbc4' }

Grails gradle "a task with that name already exists"

I'm trying to create a test task rule using the example provided in the grails gradle doc but I keep getting "a task with that name already exists" error.
My build script is as follows:
import org.grails.gradle.plugin.tasks.* //Added import here else fails with "Could not find property GrailsTestTask"
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.grails:grails-gradle-plugin:2.0.0"
}
}
version "0.1"
group "example"
apply plugin: "grails"
repositories {
grails.central() //creates a maven repo for the Grails Central repository (Core libraries and plugins)
}
grails {
grailsVersion = '2.3.5'
groovyVersion = '2.1.9'
springLoadedVersion '1.1.3'
}
dependencies {
bootstrap "org.grails.plugins:tomcat:7.0.50" // No container is deployed by default, so add this
compile 'org.grails.plugins:resources:1.2' // Just an example of adding a Grails plugin
}
project.tasks.addRule('Pattern: grails-test-app-<phase>') { String taskName ->
println tasks //shows grails-test-app-xxxxx task. Why?
//if (taskName.startsWith('grails-test-app') && taskName != 'grails-test-app') {
// task(taskName, type: GrailsTestTask) {
// String testPhase = (taskName - 'grails-test-app').toLowerCase()
// phases = [testPhase]
// }
//}
}
Running $gradle grails-test-integration
or in fact anything of the form $gradle grails-test-app-xxxxxxxx yields the error "Cannot add task 'gradle grails-test-app-xxxxxxxx as a task with that name already exists".
Can someone please advise how I can resolve this error? Thanks.
If you don't mind overriding the task created by the plugin, you might want to try
task(taskName, type: GrailsTestTask, overwrite: true)
In general, when using task rules that can be called multiple times (for instance if you have multiple tasks depending on a task eventually added by your rules), I use the following test before actually creating the task:
if (tasks.findByPath(taskName) == null) {tasks.create(taskName)}
This will call the task() constructor only if this task name does not exists.

Gradle + Sonar - get ClassNotFound Exception

My gradle configuration contains:
apply plugin: 'sonar'
sonar {
server {
url = "http://localhost:9000"
}
database {
url = "jdbc:postgresql://localhost/sonar"
driverClassName = "org.postgresql.Driver"
username = "username"
password = "password"
}
}
When running gradle with stacktrace I get this Exception:
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task
':sonarAnalyze'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.ex
ecuteActions(ExecuteActionsTaskExecuter.java:72)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.ex
ecute(ExecuteActionsTaskExecuter.java:49)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExec
uter.execute(PostExecutionAnalysisTaskExecuter.java:34)
at org.gradle.api.internal.changedetection.CacheLockHandlingTaskExecuter
$1.run(CacheLockHandlingTaskExecuter.java:34)
at org.gradle.internal.Factories$1.create(Factories.java:22)
at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(Def
... 96 more
BUILD FAILED
Total time: 17.022 secs
What does this error mean and what am I doing wrong?
You are using the old sonar plugin, which doesn't support recent Sonar versions. Instead, you'll have to use the new sonar-runner plugin. For details, see the corresponding chapter in the Gradle User Guide.

Resources