About Integrate Clojure into springboot framework - spring-boot

I'm currently trying to integrate clojure into gradle springboot project, even though it works, I do have to use RT.loadClassForName("au.edu.uq.core"); before the Clojure.var could access the function, if I comment the RT.loadClassForName("au.edu.uq.core");, there will be an error like:
Exception in thread "main" java.lang.IllegalStateException: Attempting to call unbound fn: #'au.edu.uq.core/hello-from-clojure.
But in the build.gradle I already include classes.dependsOn compileClojure.
There are screenshots of build.gradle, Main Java Class and the clojure namespace. This is a tiny demo project for me to learn gradle, any suggestions to make this build process more elegant?
Starting script is ./gradlew bootRun and ./gradlew run
//This is the Java Main Class
//This is the clojure namespace
//This is the build.gradle

From what I got from the screenshot of the Main class, it seems you are using Clojure.lang.RT to load your function, while the official reference documentation suggests otherwise:
Functions in clojure.core are automatically loaded. Other namespaces
can be loaded via require:
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("clojure.set"));
My suggestion would be to try something like:
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("au.edu.uq.core"));
IFn helloFunction = Clojure.var("au.edu.uq.core", "hello-from-clojure");
helloFunction.invoke();

Related

Gradle test library in multi module project

I want to create a library that other modules in my project can depend on, but only for tests. I've read the Gradle documentation extensively and couldn't find how to do it. This is my project structure:
gradle-example:
app:
src/main/kotlin ...
src/test/kotlin <- this is supposed to use 'com.example.SomeTestUtil'
testlib:
src/test/kotlin/com.example.SomeTestUtil
settings.gradle.kts:
rootProject.name = "gradle-example"
include("app")
include("testlib")
In the app module I tried adding
dependencies {
testImplementation(project(:testlib"))
}
But I get compilation error trying to import the SomeTestUtil in the app module test classes.
What is the correct way to declare dependency on a module in the same project that allows to use test sources in test code?
To clarify, we want to create a library that can only be used by other modules under src/test and not src/main.
Apparently this can be done by using the https://docs.gradle.org/current/userguide/java_testing.html#sec:java_test_fixtures
they can see the main source set classes
test sources can see the test fixtures classes
So changes to the example in the question are:
changing the src/test to src/testFixtures
declaring the dependency as testImplementation(testFixtures(project(":testlib")))
Adding java-test-fixtures plugin to the build.gradle.kts for the testlib module

Use Groovy app and test code in combination with jlink solution for bundling JavaFX

This follows on from this excellent solution to the question of how to get Gradle to bundle up JavaFX with your distributions.
NB specs: Linux Mint 18.3, Java 11, JavaFX 13.
That stuff, involving jlink and a module-info.java, is beyond my pay grade (although I'm trying to read up on these things).
I want to move to using Groovy in my app and test code (i.e. Spock) rather than Java. The trouble is, the minute I include the "normal" dependency in my build.gradle i.e.
implementation 'org.codehaus.groovy:groovy-all:2.5.9'
and try to build, I get multiple errors:
mike#M17A ~/IdeaProjects/TestProj $ ./gradlew build
> Configure project :
Found module name 'javafx.jlink.example.main'
> Task :compileTestJava FAILED
error: the unnamed module reads package org.codehaus.groovy.tools.shell.util from both org.codehaus.groovy.groovysh and org.codehaus.groovy
[...]
error: the unnamed module reads package groovy.xml from both org.codehaus.groovy and org.codehaus.groovy.xml
[...]
error: module org.codehaus.groovy.ant reads package groovy.lang from both org.codehaus.groovy and org.codehaus.groovy.test
error: module org.codehaus.groovy.ant reads package groovy.util from both org.codehaus.groovy.xml and org.codehaus.groovy.ant
100 errors
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileTestJava'.
Yes, 100 errors... probably more! By commenting out various things I think I've come to the conclusion that some Groovy dependency is being injected by the jlink stuff. Fine, I can live with that (although it'd be nice to know what version of Groovy it is).
The trouble is, even if I omit the Groovy dependency line, the same errors occur when I try to introduce the Spock dependency:
testImplementation 'org.spockframework:spock-core:1.2-groovy-2.5'
Has anyone got any idea what's going on here and what to do about it?
I searched for an answer. I didn't find a good solution.
According to this, it seems that Groovy is currently not really compatible with Java modules. It is due to the fact that some packages are contained by multiple jars of the library (not compatible with modules). You will have to wait for Groovy 4 for a compatible version.
I discovered that the JavaFX plugin use this plugin internally. This plugin seems to consider that all dependencies are modules (it is not the default Gradle behaviour).
To make your application works, it seems that you have to:
force Gradle to put Groovy in the classpath instead of the modulepath (it will not be considerered as a module, but seems impossible if you use the javafx plugin)
use the "patch-module" system: it allows Gradle to make a fusion of the library jars into a single module, to prevent the problem of packages that are in different jars
I searched the Groovy jars with IDEA (Project structure/Libraries), and I tried to use the syntax offered by the plugin to use "patch-module":
patchModules.config = [
"org.codehaus.groovy=groovy-ant-3.0.1.jar",
"org.codehaus.groovy=groovy-cli-picocli-3.0.1.jar",
"org.codehaus.groovy=groovy-console-3.0.1.jar",
"org.codehaus.groovy=groovy-datetime-3.0.1.jar",
"org.codehaus.groovy=groovy-docgenerator-3.0.1.jar",
"org.codehaus.groovy=groovy-groovydoc-3.0.1.jar",
"org.codehaus.groovy=groovy-groovysh-3.0.1.jar",
"org.codehaus.groovy=groovy-jmx-3.0.1.jar",
"org.codehaus.groovy=groovy-json-3.0.1.jar",
"org.codehaus.groovy=groovy-jsr-3.0.1.jar",
"org.codehaus.groovy=groovy-macro-3.0.1.jar",
"org.codehaus.groovy=groovy-nio-3.0.1.jar",
"org.codehaus.groovy=groovy-servlet-3.0.1.jar",
"org.codehaus.groovy=groovy-sql-3.0.1.jar",
"org.codehaus.groovy=groovy-swing-3.0.1.jar",
"org.codehaus.groovy=groovy-templates-3.0.1.jar",
"org.codehaus.groovy=groovy-test-junit-3.0.1.jar",
"org.codehaus.groovy=groovy-test-3.0.1.jar",
"org.codehaus.groovy=groovy-testng-3.0.1.jar",
"org.codehaus.groovy=groovy-xml-3.0.1.jar"
]
It only works with a single line "org.codehaus.groovy=X.jar", but a bug prevents it to work with all of the library jars (Look at this issue on Github).
So you have multiple choices:
Use Java instead of Groovy
Wait for a new Groovy release, or new releases of plugins (modules-plugin, and a version of javafx-plugin that use this one internally)
Use old javafx configuration: dependencies are not module by default, and you have to specify manually in build.gradle that JavaFX dependencies should be considered as a module (check my "obsolete" answer to this question)

Can't find ParameterizedTest and ValueSource

I had done a simple project, trying to understand how ParameterizedTest and ValueSource works.
From the below picture it finds the import path, but it throws an error when I try to run the code:
Also the gradle file:
Here is a link to the entire project.
You need to put junit-jupiter-params in the testCompile source set.
junit-jupiter-params exports types like #ParameterizedTest and #ValueSource that are needed at compile (and run~) time.
See also: Missing org.junit.jupiter.params from JUnit5
Starting with version 5.4.0-M1 JUnit Jupiter provides an aggregator artifact that bundles all available Jupiter-defining artifacts for easy consumption. See https://sormuras.github.io/blog/2018-12-26-junit-jupiter-aggregator.html for details.

Spring Boot "unable to resolve class" with Groovy

I'm new to Groovy, Spring Boot, and Gradle (using gradle as well) and am trying to build a small test program.
I have a main class EvalMain and a InputObj class in a com.eval package.
#Controller
class EvalMain {
#RequestMapping("/")
#ResponseBody
public static String textTest() {
def iO = new InputObj("dsa", "dasdsa", "U1dBRw==");
return iO.xorString();
}
}
when running "spring run EvalMain.groovy" I get the following error:
startup failed:
file:<filepath>EvalMain.groovy: 14: unable to resolve class InputObj
# line 14, column 18.
def iO = new InputObj("dsa", "dasdsa", "U1dBRw==");
I tried throwing an import at the top but then spring boot complained about this too? What am I missing here? Any help would be much appreciated, thanks!
after adding the import:
import com.eval.InputObj;
I get this error:
file:/<filePath>/EvalMain.groovy: 2: unable to resolve class com.eval.InputObj
# line 2, column 1.
import com.eval.InputObj
^
1 error
Not sure if this is a good way to do it, but I was able to run it with "spring run .groovy .groovy" I wonder if there's the equivalent of a makefile?
Try to run spring run *.groovy.
Spring Boot CLI is for quick prototyping a single Groovy script. It tries to autoload all Spring Boot dependencies, but its your responsibility to include your additional dependencies
If you have just multiple source files you have to pass it to the CLI.
If it is an external dependency, include it with a #Grab, see here.
However, you have Gradle and more than one source file. Therefor it might be the time to switch from the Spring Boot CLI to a normal Gradle project.
Just go to the guides and choose "Build with Gradle". Then you will see an example Gradle build file. Also the Gradle Spring Boot plugin documentation provides samples.
You can start your application with gradlew bootRun.

Exception in compiling groovy & java using maven

My groovy file contains:
#Grapes([
#Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7'),
#Grab('org.apache.httpcomponents:httpmime:4.5.1')
])
.......code
I am trying to compile groovy and java code. But I am getting below error:
java.lang.RuntimeException: Transform groovy.grape.GrabAnnotationTransformation#69bda33a cannot be run
This works for me, note that I did change HttpBuilder to v.0.7.1:
#Grapes([
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1'),
#Grab(group='org.apache.httpcomponents', module='httpmime', version='4.5.1')
])
Likely way too late for you to care, but I saw the same error just now.
I suspect the problem is that the #Grab annotation can't take effect because Maven is controlling the dependencies, or perhaps because Maven is trying to compile both Groovy and Java code, and the class loader created by the #Grab annotation can't influence the Java code.
Upshot is, I suspect you (and I) need to move the dependency out of the Groovy class in question, and put it into the pom.xml file Maven is using.

Resources