How to make gradle / intellij / play framework work together? - scala

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

Related

In Eclipse: Could not find or load main class org.testng.remote.RemoteTestNG

Configuration
I have version 2019-12 (4.14.0) of Eclipse (having recently upgraded from 2019-03) with the following plugins installed (amongst others):
TestNG 6.14.3.201902250526
TestNG M2E (Maven) Integration (Optional) 6.14.3.201902250526
TestNG P2 Features 6.14.3.r201802240500
Eclipse is running against jdk1.8.0_152.
In Eclipse, my Java Build Path includes testng-6.14.3. I've tried to match the Eclipse plugin version against the version using in the project.
Under Properties -> TestNG I have all the default settings. There is no setting here for "Use Project TestNG.jar".
What Works
When I run tests from the command line with Gradle they all pass with no issue.
There are no complile errors showing in Eclipse.
What Does Not Work
When I run a test from Eclipse (by right clicking on a class) the console shows:
Error: Could not find or load main class org.testng.remote.RemoteTestNG
It appears I need a copy of testng-remote.jar. Should this have been installed as part of the plug-in, or am I meant to have included that in my build.gradle as a dependency?
Why can't I run tests from Eclipse? Do I need to install something further to resolve this error?
What I have Tried
I have tried removing and re-installing the TestNG plugin.
It seems you hit the bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=558495 in Windows.
I reverted my version back to 2019-09 because of it.
The bug causes jars which should be on the classpath not to be on the classpath. This affects projects with long classpaths.
Can you try adding it in your build.gradle.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:1.0.3.RELEASE"
classpath group: 'org.testng', name: 'testng', version: '6.8.+'
} }
Change the testng version as per your usage.
I don't remember such problem for gradle but it looks similar to the problem with testing on maven(with auto-build turned off). The soultion is to rebuild project (for maven it ia alt +f5) and because of such rebuilding - cache is updated.
You have detailed TestNG gradle tutorial
By default, Gradle will run all tests that it detects, which it does by inspecting the compiled test classes. When we specify useTestNG(), Gradle scans for all the methods annotated with #Test and execute them.
Example 1. Below is the basic configuration for the 'test' task
plugins {
id 'java'
}
group 'com.test'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.testng', name: 'testng', version: '6.14.3'
}
test {
useTestNG()
}
For Gradle use testCompile dependencies:
repositories {
jcenter()
}
dependencies {
testCompile 'org.testng:testng:6.10'
}
For specific version you have options,
Install from update site
Select Help / Install New Software...
Enter the update site URL in "Work with:" field:
Update site for release: http://dl.bintray.com/testng-team/testng-eclipse-release/.
Make sure the check box next to URL is checked and click Next.
Eclipse will then guide you through the process.
You can also install older versions of the plug-ins here. Note that the URL's on this page are update sites as well, not direct download links.
Build TestNG from source code
you can download the source and build the distribution yourself:
git clone git://github.com/cbeust/testng.git
cd testng
./build-with-gradle

How to build an Xtext Eclipse plug-in with Gradle?

I have written a DSL with Xtext 2.12 and my Xtend 2.12 code generator produces Java 8 code from it. I am using Eclipse Oxygen.3a. I started by creating an Xtext project as an Eclipse plug-in and all works fine, but I would like to have everything built by Gradle now.
For that purpose, I have added the Gradle nature to my Xtext project and launched 'gradle init' to generate the build.gradle and settings.gradle files. I have discovered the existence of Xtext Gradle Plugins (Xtext Builder and Xtend Compiler), and used the documentation of these plugins to write the build.gradle script content, but I did not understand everything and, not surprisingly, my builder does not work. Could you help me please to set this builder up correctly?
plugins {
id 'org.xtext.builder' version '2.0.3'
id "org.xtext.xtend" version "2.0.3"
}
apply plugin: 'java'
apply plugin: 'org.xtext.xtend'
apply plugin: 'eclipse'
sourceSets {
main.java.srcDirs = ['src','xtend-gen']
main.xtendOutputDir = 'xtend-gen'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile group: 'org.eclipse.xtend', name: 'org.eclipse.xtend.lib', version: '2.16.0'
compile group: 'org.eclipse.xtext', name: 'org.eclipse.xtext', version: '2.16.0'
compile group: 'org.eclipse.emf', name: 'org.eclipse.emf.codegen.ecore', version: '2.15.0'
compile group: 'org.eclipse.xtext', name: 'org.eclipse.xtext.xtext.generator', version: '2.16.0'
testCompile group: 'org.eclipse.xtext', name: 'org.eclipse.xtext.xbase.testing', version: '2.16.0'
}
xtext {
languages {
mapy {
setup = 'com.mchp.mapy.MapyStandaloneSetup'
generator.outlet.producesJava = true
}
}
sourceSets {
main {
srcDirs 'src','xtend-gen'
output {
dir(xtext.languages.mapy.generator.outlet, 'src-gen')
}
}
}
}
xtend {
}
Where should the sourceSets block be located (inside or outside the
xtext block)?
Is the xtext block content correct?
What should I write into the xtend block? Should it even be declared?
What is the Gradle task to be run to start the MWE2 launcher and
then the code generator?
Following is a snapshot of my Eclipse project organization.
Thanks in advance for your time!
It is also possible to build the Xtext plugins using Eclipse PDE. I created a dedicated Eclipse deployment to keep the size down (minimal then install the PDE, JDT and Xtext projects) which is published to an artifact repository. It's then just a matter of writing Gradle tasks (or a plugin) to pull down the Eclipse, extract it to the build directory, copy in the Xtext Eclipse projects (use the Xtext Gradle plugin to build the DSL before copying) and finally call the Ant PDE task(s) using the Java command and the AntRunner inside the Eclipse. The output should be a basic update site from which you can either install the plugins from locally or publish to the Artifact repository to share.
A good understanding of Eclipse PDE build process is required. I found most of what I needed in the Eclipse help (https://help.eclipse.org/2020-06/index.jsp) under section "Plug-in Development Environment Guide > Tasks > PDE Build"
I have encountered some issues during Xtext version upgrades with various dependency conflicts and Eclipse bugs. These can usually be resolved with the help of the Xtext dev team and then forcing certain dependencies in Gradle.
Unfortunately I can't share any of the build as it's a proprietary code, but I hope the explanation above is enough for anyone who needs to automate the process. It's certainly not a simple thing to set up though.

How to setup JUnit testing in Gluon Project with Gradle

I am trying to setup JUnit testing in my Gluon JavaFX Application. I am using the Gluon Eclipse Plugin with Gradle and Java 8.
My build.gradle file looks like this:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.0.0-b10'
}
}
apply plugin: 'org.javafxports.jfxmobile'
repositories {
jcenter()
}
dependencies {
compile 'com.gluonhq:ignite-dagger:1.0.0'
compile 'org.elasticsearch:elasticsearch:1.6.0'
compile 'ch.qos.logback:logback-classic:1.1.5'
testCompile 'junit:junit:4.12'
}
mainClassName = 'com.me.MyApplication'
jfxmobile {
android {
manifest = 'src/android/AndroidManifest.xml'
}
ios {
infoPList = file('src/ios/Default-Info.plist')
}
}
Resolving the dependency is no problem, but when running the 'test' task, gradle throws an error like this:
When running gradle with java 8, you must set the path to the old jdk, either with property retrolambda.oldJdk or environment variable JAVA6_HOME/JAVA7_HOME
Could not execute build using Gradle distribution 'https://services.gradle.org/distributions/gradle-2.2.1-all.zip'.
I already tried to add the retrolambda plugin to gradle according to the plugin's README on GitHub, but it doesn't work so far. Could someone tell me what to do to configure my Gluon project so that I am able to run my JUnit tests with Gradle?
Some important addidtions:
For the plugin version it says: Gluon Tools 1.0.0.201508201514
I think I fogot to mention that I want to use Dagger dependency injection with Gluon Ignite which might be the real problem in my case as it requires Java 8 and might conflict with javafxports or something else. However, I'm not able to make full sense of the various error messages I've seen.
My tests are empty, but they aren't even run, because it fails before.
Your problem seems like a retroLambda configuration issue. If you go through the configuration page for the plugin, it states that if you don't have an environment variable set for JAVA6_HOME or JAVA7_HOME than you need to explicitly define oldJdk for the plugin to work properly.

IntelliJ overrides Scala additional compiler options when synced from Gradle

I'm working on a Scala project in IntelliJ IDEA, and using Gradle for configuration and dependency management.
Every time I add some new dependency and sync it into IDEA, it rewrites Additional compiler options into -target:jvm-1.8, what results in a error when I try to make it with IDEA:
Error:scalac: 'jvm-1.8' is not a valid choice for '-target'
Error:scalac: bad option: '-target:jvm-1.8'
So I need to fix it manually.
Can I set target JVM version or compiler parameters (need also -feature option) in my build.gradle, so it would take them from there?
Thanks!
You can add sourceCompatibility = '1.7' to your gradle build file and then refresh, the project will build normally. Note that this way you cannot have Java 8 source in your code, this is a temporary hack until Gradleware or JetBrains solve the issue.
You can also tamper with the IDEA project XML that is generated when running gradle idea. That would give you the option to include additional flags as well. You can check your current xml by opening the project .iml file and identifying what needs to be changed, then use the following code:
apply plugin: 'idea'
idea {
module {
iml {
withXml {
def node = it.asNode()
//modify xml
}
}
}
}
Would not recommend it though, as you will have to stick with using gradle idea and won't be able to properly import straight from the IDEA, but currently there is no better way to have additional flags. Documentation - idea plugin and idea module
I was searching for a solution for this for ages, finally found it - sharing for anyone else reading this.
Taken from: https://devnet.jetbrains.com/message/5523902
subprojects {
tasks.withType(ScalaCompile) {
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
}
}

Can JetGradle Be Used In IntelliJ 12 Alongside Gradle Generated Project Files That Have Scala Facets?

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.