Make IntelliJ resolve dependencies from modules in same project - java

Using IntelliJ 2016.2.5, I seem to be unable to make it resolve Gradle dependencies which are in the same project.
Project structure is as follows:
firstModule
-> build.gradle // 1
-> settings.gradle // 2
secondModule
-> build.gradle // 3
-> settings.gradle // 4
Contents of first build.gradle (1):
group 'de.test'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {mavenCentral()}
dependencies {}
And settings.gradle (2):
rootProject.name = 'test'
The contents of the second build.gradle (4) are:
group 'de.test'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {mavenCentral()}
dependencies {
compile ('de.test:test:1.0-SNAPSHOT')
}
And second settings.gradle (4):
rootProject.name = 'testdep'
Both modules are imported as Gradle projects and are set to auto-import enabled.
I know from maven projects, that IntelliJ - as well as Eclipse - does resolve those dependencies to the respective modules in the project/workspace. But with Gradle it seems to not recognize the dependencies. After every change in the module test I need to run the explicit gradle tasks clean and build before the module testdep seems to pick up the changes. And this process is not even reliable, if I don't change the version. This is most likely because of the gradle caching, but it is annoying, nevertheless.
Using the command line argument --refresh-dependencies is not a real solution because it makes the build times of our project (the one above is only for demo purposes) unbearable. Also, I would love to not having to use the gradle calls explicitly.
Any ideas/improvements how to handle such a situation?
Does it work with Eclipse, any experiences?
Will this be fixed in IntelliJ 2016.3 (I saw some improvements in the gradle area for that release).

What you are trying to do will be possible using the new Composite Builds functionality in Gradle. Support for IntelliJ IDEA is coming soon.

Related

Gradle: find resolved version of a dependency imported with +

I want to print the last version of a dependency in gradle.
I added my dependency in this way :
compile 'test:test:+'
now I want to print the version of my dependency, because I want to know which version I'm using.
I'm using it in this way :
gradle dependencyInsight --configuration compile --dependency test:test
But my output is this :
+--- test:test:+ -> project : (*)
Is there anyway I can get the real version of my dependency and not the +?
Within app module's build.gradle I've imported Square's Moshi library as follows:
dependencies {
compile 'com.squareup.moshi:moshi:+'
}
Then I executed following command in terminal:
./gradlew app:dependencyInsight --configuration compile --dependency com.squareup.moshi:moshi
Here's the output that I've received:
All easy, open hierarchy of view Project and see External Libraries
If you want to check the overview for all your dependencies, you can check with this command -
Solution 1-
./gradlew app:dependencies
Or
Solution 2-
If you want to check for any specific dependency.you can use gradles' build-in 'dependencyInsight : -
gradle dependencyInsight --configuration compile --dependency compile 'test:test:+'
or
Solution 3-
You can check your project .idea folder
inside your project -> .idea/libraries
there also you can see the final version of dependencies used.
You can do the following:
Use the configuration that contains your jar file
Filter for the the jar file's name
Print the results
This will print the full path as well as the version. You can extract just the jar name if needed.
task printPmdVersion << {
FileTree pmdJar = zipTree(configurations.pmd.filter {
dep -> dep.name.contains("pmd-core")
}.singleFile)
println pmdJar
}
Example of output:
ZIP '/home/user/java/gradle_user_home/caches/modules-2/files-2.1/net.sourceforge.pmd/pmd-core/5.4.1/28715c2f768b58759bb5b373365997c30ac35899/pmd-core-5.4.1.jar'
Once you have added your dependency as "compile 'test:test:+'" build the project.
Then within the "Project" folder structure hierarchy find that dependency within "External Libraries" at the bottommost of folder structure , it will along with its version there. Use that version with your dependency and re-sync/build project again.
It's not a best practice use the '+' sign to always use the latest library version because you could not be able to have a repeatable build if you need one.
I mean, if you have to checkout your previous version of your APK from your Source Control Management system (e.g. Git) that you know it works fine, if you compile today (new library version could have been release)... maybe your old friend APK that was working fine... now it doesn't work fine like your latest one.
That said I suggest you using a gradle plugin like that:
https://github.com/ben-manes/gradle-versions-plugin
You will install in your build.gradle at project level like that:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply plugin: 'com.github.ben-manes.versions'
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.github.ben-manes:gradle-versions-plugin:0.17.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
And you'll find a new gradle task named dependencyUpdate that if you lunch it it will report you all your library versions compared with the latest ones:
------------------------------------------------------------
: Project Dependency Updates (report to plain text file)
------------------------------------------------------------
The following dependencies are using the latest milestone version:
- com.github.ben-manes:gradle-versions-plugin:0.17.0
- junit:junit:4.12
The following dependencies have later milestone versions:
- com.android.support:appcompat-v7 [26.1.0 -> 27.0.2]
- com.android.support.constraint:constraint-layout [1.0.2 -> 1.1.0-beta5]
- com.android.support.test.espresso:espresso-core [3.0.1 -> 3.0.2-alpha1]
- com.android.tools.build:gradle [3.0.1 -> 3.2.0-alpha03]
- org.jacoco:org.jacoco.agent [0.7.4.201502262128 -> 0.8.0]
- org.jacoco:org.jacoco.ant [0.7.4.201502262128 -> 0.8.0]
- com.android.support.test:runner [1.0.1 -> 1.0.2-alpha1]

Gradle - Add JavaFX SDK to classpath

I am using gradle in Eclipse, and my gradle.build is pretty basic (adds java plugin, sets repos and not alot more) and I am building a JavaFX program. All my code compiles and run correctly with my build scripts with 0 errors.
I am just annoyed at the fact when I add the JavaFX SDK to my build path libraries, I can see my project has it listed. When I sync my project with Gradle, gradle removes this SDK from my classpath file.
What do I need to add to my build script to stop this from happening and gradle to normally inject it into my .classpath as it does with anything else I add?
Cheers,
P.S. I'm really new to gradle and groovy and this is my first 'project' working with it. Apart from this one annoyance, it's been smooth going.
Solved this issue: completely forgot classpath is todo witth eclipse and not java/gradle.
Adding:
apply plugin: 'eclipse'
eclipse {
classpath.containers 'org.eclipse.fx.ide.jdt.core.JAVAFX_CONTAINER'
}
to my gradle.build file solved this issue.
I actually found a solution for this via https://groups.google.com/forum/#!topic/javafxports/Fn92C5ysC60 'android forum' while looking up how I could automate the building of eclipse.
Cheers if anyone looked into this.
As a side note, as I was confused about this first: A JavaFX project is no different from a Java project and you don't need to specify the fact you're using JavaFX to your ide to be able to execute JavaFX code. So I was confused why my IDE had a 'Start a new JavaFX project' and 'Start a new Gradle Project' but no JavaFX/Gradle project.
You don't 'need' a JavaFX plugin like my project originally had either.
To solve your problem, you need JavaFX-Gradle-plugin, it's a plugin that enable JavaFX support on Gradle project.
This is the link of plugin: https://github.com/FibreFoX/javafx-gradle-plugin, where you can find all infos and example...
All of you need is to start a new Gradle project, then add to your file build.gradle this code:
buildscript {
dependencies {
classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: '8.8.2'
}
repositories {
mavenLocal()
mavenCentral()
}
}
apply plugin: 'java'
repositories {
mavenLocal()
mavenCentral()
}
dependencies{
// put here your project dependencies
}
apply plugin: 'javafx-gradle-plugin'
// these values are the examples and defaults
// you won't need them all
// configure javafx-gradle-plugin
jfx {
// minimal requirement for jfxJar-task
mainClass = 'YOUR.MAIN.CLASS'
// minimal requirement for jfxNative-task
vendor = 'YOUR NAME OR COMPANY'
// some optional task
jfxAppOutputDir = 'build'
jfxMainAppJarName = 'YOUR APPLICATION NAME.jar'
manifestAttributes = [
"Specification-Version": 1.0,
"Implementation-Version": 1,
"Built-By": "YOUR NAME OR COMPANY",
]
// for a full list of available settings, look the class "JavaFXGradlePluginExtension" on plugin project
}
This is the only plugin that I've found for use JavaFX with Gradle.
I'm working with Eclipse on project with same problem, and I've solved it a few days ago.
Hope this help,
BoGnY

Unable to resolve generated classes

I'm using Dagger 2 with Gradle and have everything setup and code generation is working properly.
My build.gradle:
task wrapper(type: Wrapper) {
gradleVersion = '2.11'
}
subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
... omitted as irrelevant to question ...
compile 'com.google.dagger:dagger:2.0.2'
compile 'com.google.dagger:dagger-compiler:2.0.2'
compile 'javax.inject:javax.inject:1'
}
}
My problem is that I am unable to resolve the classes and use them in my source, any solutions I've found are targeted towards Android which I am not using. How would I be able to resolve these generated classes as dependencies?
I had a similar issue some time ago. In your case I would say that you need the apt plugin. Check this question where I explained how I resolved it
I fixed this issue by enabled annotation processing in my IDE as well as adding Dr. Pelocho's answer.
Apply this answer: https://stackoverflow.com/a/33445767/1787084 to your build.gradle
Add apply plugin: 'eclipse' in your build.gradle
Enable annotation processing to the apt directory created by the ltgt gradle apt plugin in Eclipse by navigating to project properties -> Java compiler -> Annotation processing -> Enable project specific settings -> Enable annotation processing
Change generated source directory to build/generated/source/apt/main to match the ltgt default directory
Click "OK" or "Apply"
This added the Dagger generated classes to my build path and classpath

Intellij IDEA can't import Gradle project - "Could not initialize class javax.crypto.SunJCE_b"

I'm working on a Gradle project. The project downloads dependencies and runs perfectly fine when I do gradle run. Here's my build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'application'
mainClassName = 'myProject.MyMainClass'
repositories {
mavenCentral()
}
dependencies {
// The production code uses the SLF4J logging API at compile time
compile 'org.slf4j:slf4j-api:1.7.7'
compile 'org.jsoup:jsoup:1.7.2'
testCompile "junit:junit:4.11"
}
jar {
baseName = 'myproject-service'
version = '0.1.0'
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
Now I want to import the project in Intellij IDEA.
Import Gradle project >> Use default gradle wrapper (recommended) >> OK
However, when I hit OK it comes up with a dialogue saying:
Could not initialize class javax.crypto.SunJCE_b
Looking in the logs, it says
org.gradle.tooling.GradleConnectionException: Could not run build action using Gradle distribution 'https://services.gradle.org/distributions/gradle-2.3-bin.zip'.
...
Caused by: java.lang.NoClassDefFoundError: Could not initialize class javax.crypto.SunJCE_b
at javax.crypto.KeyGenerator.a(DashoA13*..)
...
2015-03-18 21:31:17,751 [2354198] WARN - nal.AbstractExternalSystemTask - Could not initialize class javax.crypto.SunJCE_b
com.intellij.openapi.externalSystem.model.ExternalSystemException: Could not initialize class javax.crypto.SunJCE_b
at org.jetbrains.plugins.gradle.service.project.AbstractProjectImportErrorHandler.createUserFriendlyError(AbstractProjectImportErrorHandler.java:106)
...
I have no idea how to get this project to work. None of my imports from external repositories work inside IDEA without this (they all appear red). Any help would be appreciated. I'm on:
Intellij IDEA 13.1.6
Java EE 7 (jdk1.7.0_75.jdk)
Gradle 2.3
Mac OS X
SOLUTION:
Still have no idea what the issue is. I tried all the suggestions I could find online and everything I could think of: Install a different version of java, install a different IDEA, try using the original cryptography policy files, try using the unlimited strength policy files and more. None of these worked.
What did work, however, was selecting "Use a local gradle distribution", instead of using the default wrapper. I gave it my gradle install path (/usr/local/gradle-2.3), found by running which gradle (that will give you the path to the executable, namely /usr/local/gradle-2.3/bin/gradle, but I just took the directory part). Now I can build using gradle!!
My best guess is that the gradle plugin installed some other distribution of gradle that wasn't set up properly for my project.
I hope this is helpful to anyone else struggling with using gradle in Intellij IDEA.

Gradle Multi-Module Project Setup

I've recently started using Gradle and replacing my existing Maven-based projects. I have had many issues in the past with handling multi-module builds with Maven. Gradle has been a breath of fresh air when handling multi-module buils, but it's not perfect yet.
I have the following folder layout for my projects:
-- Projects
---- EnterpriseApp1
------ EarProject
-------- build.gradle
------ EjbProject
-------- build.gradle
------ WarProject
-------- build.gradle
------ properties.gradle
------ build.gradle
---- CommonLib
------ build.gradle
---- ClientApplication
------ build.gradle
The problem I am having is that the "EnterpriseApp1" and "ClientApplication" both depend on the CommonLib project. I don't know how to configure my "EnterpriseApp1" build file to use the CommonLib project as dependency for the "EjbProject". I have come very close to getting this to work, but not quite working yet. I have had success by copying the CommonLib folder inside "EnterpriseApp1", but that's not a long term solution.
Here's my current properties.gradle file in "EnterpriseApp1":
include "EarProject", "EjbProject", "WarProject"
includeFlat "CommonLib"
According to the Gradle documentation the "includeFlat" command in the "settings.gradle" file will include projects on the same level as the folder where the "settings.gradle" file resides (desired behavior).
EnterpriseApp1/build.gradle file:
subprojects {
apply plugin: 'java'
sourceCompatibility = 1.6
group = 'org.example'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
...
}
dependencies {
}
}
EnterpriseApp1/EjbProject/build.gradle:
apply plugin: 'java'
sourceCompatibility = 1.6
repositories {
mavenCentral()
...
}
dependencies {
compile project(':CommonLib')
compile group: 'org.restlet.jee', name: 'org.restlet', version: '2.0.11'
compile group: 'ma.glasnost.orika', name: 'orika-core', version: '1.0'
...
compile group: 'javax.jmdns', name: 'jmdns', version: '3.4.1'
}
When I execute "gradle clean build" from the EnterpriseApp1 folder all the dependencies are downloaded as expected and the projects begin to compile (including the CommonLib project), but the EjbProject project fails during the build due to the fact it's missing the CommonLib jar reference. Gradle is not smart enough (or I'm completely clueless ;)) to configure my EjbProject to use the Jar generated from the CommonLib project build stage.
I apologize for the long and complicated setup. I have been working on trying to figure this out for some time now, but have nearly ran out of ideas. I would really appreciate any help for the community.
Thanks!
The directory layout that you've chosen already hints at a good solution. I suggest to have three separate builds: EnterpriseApp1, CommonLib, and ClientApplication. I'd publish CommonLib to a Maven or Ivy repository so that the other two builds can consume it from there. For local development you can publish CommonLib to the local Maven repo (easiest) or a file-based Ivy repo.

Categories