How do I configure my compile task to depend on the spring-boot-configuration-processor library?
The official documentation gives an example using Gradle's dependsOn function for the compileJava task:
...
dependencies {
optional "org.springframework.boot:spring-boot-configuration-processor"
}
compileJava.dependsOn(processResources)
}
Can someone show me how a similar task could be created for an SBT build file? Can this even work with Scala source code?
EDIT:
The spring-boot-annotation-processor reads metadata on Classes annotated with #ConfigurationProperties and generates meta-data to help with IDE code completion and documentation reading. i.e. Saves you from manually typing out well formed JSON docs that describe each of your configuration properties.
To answer #Haspemulator the library generates resources from source code.
sourceGenerators in Compile <+= Def.task {
run processor code
return list of generated files
}
Here is a Gradle build as advised here for using play web framework.
plugins {
id 'play'
id 'idea'
}
repositories {
jcenter()
maven {
name "typesafe-maven-release"
url "https://repo.typesafe.com/typesafe/maven-releases"
}
ivy {
name "typesafe-ivy-release"
url "https://repo.typesafe.com/typesafe/ivy-releases"
layout "ivy"
}
}
It works fine when building, launching etc... from command line but once the project is imported in intellij (idea's project files generated with gradle idea), dependencies (from the play plugin) don't show up in the project view/external libraries (even after having hit "refresh all gradle projects" in the gradle panel).
Thanks :)
PS: intellij 15.0.2 / gradle 2.6 / play plugin
Answer found here. Apparently the gradle idea plugin needs to be told explicitely how to wire the dependencies.
To sum up :
Create a typical play layout
Add a build.gradle (as below)
Type gradle idea to generate idea's project files
Open the project in intellij
plugins {
id 'play'
id 'idea'
}
repositories {
jcenter()
maven {
name "typesafe-maven-release"
url "https://repo.typesafe.com/typesafe/maven-releases"
}
ivy {
name "typesafe-ivy-release"
url "https://repo.typesafe.com/typesafe/ivy-releases"
layout "ivy"
}
}
idea {
module {
sourceDirs += file("app")
testSourceDirs += file("test")
scopes.COMPILE = [plus: [configurations.play], minus: []]
scopes.RUNTIME = [plus: [configurations.playRun], minus:[configurations.play]]
scopes.TEST = [plus: [configurations.playTest], minus: [configurations.playRun]]
}
}
PS: tested with intellij 15.0.2 / gradle 2.10 / gradle play plugin
I'm using Intellij (2017 and 2018), Gradle (4.6), and Play (2.5). The three of these do not mix together out of the box.
Without help, IDEA won't recognize dependencies, and will be little more than Notepad -- no code completion, no navigation. This is because IDEA looks at the configuration model of the Java plugin, but the 'play' plugin uses the "new" software model. I don't think either side it going to change this to meet the other any time soon.
The 'idea' plugin writes file-based project files that do not work very well, and have to be refreshed manually. I would advise that you not use the 'idea' plugin at all.
Using 'java' and 'play' plugins, you can help IDEA understand what you want by:
(1)
Moving your Play source files around to follow the pattern expected by the 'java' plugin:
app -> src/main/java
test -> src/test/java
You can make a symbolic link from ./test to src/test/java, or muck with the play model with plugin code. The path ./test is hardcoded (!) in the 'play' plugin, but I find IDEA works better if it finds it in src/test/java.
(2)
Configure the play plugin to get its input from the Java plugin source directories. Something like this:
model {
components {
play {
sources {
java {
source.setSrcDirs files("src/main/java")
}
resources {
source.setSrcDirs files("src/main/resources")
}
routes {
// leave in ./conf
}
}
}
}
}
(3)
Configure the java plugin to put its output in the play plugin output directories. Something like this:
sourceSets {
main {
java.outputDir = file('build/playBinary/classes')
}
test {
java.outputDir = file('build/playBinary/testClasses')
}
}
(4)
Give IDEA a bit more help to figure this out:
configurations {
compile.extendsFrom(play)
testCompile.extendsFrom(playTest)
implementation.extendsFrom(playRun)
implementation.extendsFrom(playPlatform)
}
If you do this, you can then import the Gradle project directly into IDEA, use the Gradle runner for tests, and refresh the gradle project at any time.
I realize this answer comes years late, but there is not a lot of information out there, and this answer may help people still searching for this in the distant future.
+-+-+-+-+-+-+-+-
EDIT: I've stopped using the above approach as it is too unreliable. Instead, I wrote my own plugin to replicate the twirl and routes compiler steps of sbt, and then just use the traditional scala (which uses java) gradle plugin, and also groovy (for spock tests). I use the application plugin to build the distribution. I import it as a gradle build in Intellij and everything "just works". I recommend not using the 'play' plugin at all.
Use the straight-forward gradle plugins. Avoid the 'idea' and 'play' plugins. Import the project into Intellij as a gradle build -- even the traditional JUnit runner works fine. Stay away from the "new" gradle software model in your plugins. Run and debug directly from Intellij as for any other Java application.
This means giving up the "development mode" of sbt, and always running the "ProdServerStart" main (but you can still run in dev or test "mode" of Play). But I'm not missing sbt. :^) When running ProdServerStart, for example, you always run out of a jar with a traditional classpath. You'll need to change the application secret from "changeme", and you will have to put your asset jar on the classpath. This is all straight-forward JVM and no sbt secret sauce (other then twirl and route compilers).
I'll come back with more details but for now:
#TaskAction
public void generate() {
getSource().forEach(sourceFile -> {
TwirlCompiler.compile(sourceFile,
getAppDir(),
getDestinationDir(),
FORMATTER,
ADDITIONAL_IMPORTS,
Codec.UTF8(),
false,
false);
});
}
and
#TaskAction
public void generate() {
getSource().forEach(sourceFile -> {
RoutesCompiler.RoutesCompilerTask routesCompilerTask = new RoutesCompiler.RoutesCompilerTask(sourceFile,
ADDITIONAL_IMPORTS,
true,
true,
false);
RoutesCompiler.compile(routesCompilerTask, INJECTED_ROUTES_GENERATOR, getDestinationDir());
});
}
should get you started if you are comfortable writing gradle plugins in Java.
First of all you have to change your project according to gradle play plugins. here is the links, how to change your sbt project to gradle and make sure that you can execute all the necessary commands(build, clean, runPlayBinary, etc) from command prompt or terminal. When you are able to build successfully then you can import in Intellj IDE. Here is the steps you have to follow. Add idea plugins and following config for idea source configuration in build.gradle file.
plugins {
....
id 'idea'
}
..
idea {
module {
sourceDirs += file("app")
testSourceDirs += file("test")
scopes.COMPILE = [plus: [configurations.play], minus: []]
scopes.RUNTIME = [plus: [configurations.playRun], minus:[configurations.play]]
scopes.TEST = [plus: [configurations.playTest], minus: [configurations.playRun]]
}
}
...
Type "./gradlew idea" to generate idea's necessary project files
Open the project in intellj(Don't import)
Setup sdk(java) from project structure
In IDE at the bottom, you will see message like "Unlinked Gradle project? Import Gradle project, this will also enable Gradle Tool Window. Don't want to see the message for the project again: press here."
click on this message an enable gradle fort this project and setup gradle home and JVM(not project jvm) for gradle
To Run(Run config)
Open run configuration window
Click on(+) and Select Gradle
Name: as you need
Gradle project: your root project or location of your root project
Tasks: runPlayBinary
Go to intellj preference
Go to [Build, Execution and Deployment] section
Select build tool as gradle
Set "Service diretory path" ex: "/Users/.../gradle/gradle-4.10.2"
uncheck "offline work"`
Tested with Grade 4.10.2, IntelliJ IDEA 2018.3.2 (Ultimate Edition) snd Play 2.5.2
I have a simple Scala command line App that I want to package using SBT.
object Transform extends App {
val source = scala.io.Source.fromFile(args(0))
...
}
I can't seem to find anything in the SBT docs or an online example of a SBT configuration/command that would allows me to create a standalone executable jar (java -jar ...) with the appropriate manifest and dependencies included.
I did find SBT Assembly, but it looks to be a plugin for SBT < 0.13.5.
sbt-onejar was created for exactly this use case.
I've got a Scala project that is built with Gradle. The Scala code is source compatible with scala 2.9 and 2.10 and I'd like to cross build it to both major Scala versions. Does Gradle support this?
For example, my gradle project will have a single module:
build.gradle
src/main/scala/foo.scala
and I'd like the resulting published jars to be:
org-foo_2.9-0.1.jar (with dependency on scala-library 2.9)
org-foo_2.10-0.1.jar (with dependency on scala-library 2.10)
Gradle's Scala plugin doesn't currently support cross-building. It's possible to implement it yourself, though. In my Polyglot Gradle talk, I presented a proof-of-concept.
I am searching for a good example of this. The Gradle manual doesn't mention how to specify Scala version but looking at the source code for the Scala plugin it seems to infer it from the Scala library jar that you specify.
The best example I could find is the Apache Kafka build system. It specifies the Scala version and then uses some additional logic to resolve the correct version of the Scala libraries. It also uses some logic to attach the correct label to the jars its builds to correspond to the correct Scala version.
This feels like a lot of work and something that the build system should do for you like in SBT.
I've been trying to make the switch to IntelliJ and Gradle for the Java/Scala projects at my company. From the command line Gradle has been great but I've run into a problem when using Gradle with IntelliJ and projects with Scala facets.
I've tried importing projects in both ways and the only one I've been able to get Scala facets working is to run:
gradle idea
using the Gradle IDEA plugin. After that all I need to do it open the ipr file for the project and the projects work fine.
However, there are some Gradle tasks that I would like to run from within IntelliJ for various things (code generation being the biggest one). I would like to be able to use JetGradle to run those tasks. The problem is when I link the Gradle project to JetGradle, the dependencies in each project break the Scala facet's compiler settings.
It's a multi-module project. Here is the build.gradle for the parent:
allprojects {
apply plugin: 'idea'
version = '1.0'
group = 'company-x'
repositories {
mavenCentral()
}
}
And here's the build.gradle for the scala modules:
apply plugin: 'scala'
dependencies {
compile 'org.scala-lang:scala-library:2.10.1',
'org.scala-lang:scala-reflect:2.10.1',
'org.scala-lang:scala-compiler:2.10.1',
'org.slf4j:slf4j-log4j12:1.7.2',
'com.typesafe.akka:akka-actor_2.10:2.1.4'
testCompile 'junit:junit:4.8.1',
'org.scalatest:scalatest:1.2'
}
Before linking the project to JetGradle the Scala facet is setup with a library called 'scala-compiler-2.10.1' that contains the Scala compiler, library, and reflect jars and src. After linking the project, the project libraries are replaced with all of the Gradle project dependencies. The Scala facet then gives the error:
Compiler library: no scala-library*.jar found
When I look at the libraries again, there is still a library called 'scala-compiler-2.10.1' but it's only the compiler. The library and reflect jars are now separated out.
Has anyone out there figured out how to get the Scala facet and JetGradle to play nicely with one another?
From this IntelliJ blog (Better Gradle Support in IntelliJ IDEA 12.1) it seems JetGradle is not ready to support Scala.
I'm waiting for IntelliJ 13.x and stick to Maven for the time being.