Calicoder Calicoder - 4 months ago 60
Groovy Question

intellij grails unable to resolve external library at groovy compile time

I'm writing a simple etrade programmatic trading program that needs to authenticate with etrade oauth. I'm using IntelliJ Ultimate with Grails 3.1.9.

I added a folder full of jars to Project Settings->Libraries and Project Settings->Modules->main project (accessible by pressing "command ;") and selected "export." The classes resolve fine in the groovy editor in my controller class but they don't resolve at groovy compile time. Why is that?

~/IdeaProjects/<project name>/grails-app/controllers/etradescripter/ETradeUserController.groovy: 8: unable to resolve class com.etrade.etws.sdk.client.ClientRequest
@ line 8, column 1.
import com.etrade.etws.sdk.client.ClientRequest;

Answer

Grails use the Gradle build system, which is comparable (superior IMHO) to maven. It is completely external to the IDE itself and not dependend to any IDE. It is a very powerfull external build tool which has it's own tooling, dependency management, library cache and logs.

The libraries and SDK you declare in Intellij project structure settings are for IntelliJ internal support (intellisense, code assist, decompiling etc) not for building and/or debugging

The gradle tooling support for your project (found in File/Settings/Gradle) can be:

  • a gradlew declaration in the project : the project will use it's own build system version downloaded from the specifications in gradle/wrapper/gradle-wrapper.properties file with the accompanying gradle-wrapper.jar downloader - this is the recommended way to go if you are not comfortable with the system to avoid problems but disk consuming and not the fastest build. There will be a gradle binary distribution download for the first build
  • a Gradle version bundled with Intellij (2.13 for the last IntelliJ version I think)
  • one you can declare in the project settings (ie your own Gradle installation root, you have to install it before and set the right environment variables to make it work) for the last one it can be a "daemon" version which speeds up thing notably but is very cpu and memory expensive for a large project (be prepared for 100% cpu and memory hogs for a large project whatever computer you have).

The main file for build where you declare the build and debug dependencies is "Build.gradle" file at the root of your project.

Dependencies are declared with lines (Groovy syntax, gradle is a groovy tool) like:

dependencies {
    assets "com.craigburke.angular:angular-template-asset-pipeline:2.2.6"
    assets "com.craigburke.angular:angular-annotate-asset-pipeline:2.4.0"
    assets "com.craigburke:js-closure-wrap-asset-pipeline:1.2.0"
    compile "org.springframework.boot:spring-boot-starter-logging"
    compile "org.springframework.boot:spring-boot-autoconfigure"

etc...

This is where you have to add your own dependencies, not in IntelliJ SDK/lib settings. This is comparable to the maven system with a different syntax (groovy).

For jars comming from an external repo or local dependencies, you should see lines that you can copy/paste and modify. If not look at gradle docs especially 23.3 and 23.4, how to declare you dependencies.

There can be other gradle files in gradle directory and/or subprojects directory. It depend on your project.

To build your project, you can open the Gradle tool window in IntelliJ (View/Tool Windows/Gradle), select the build task (Task/build/build), double click on it and it will launch the build. This will change the run/debug configuration in the IntelliJ IDE so you can build it again with the IDE toolbar by clicking on the Run button

Note: the run button runs the currently selected gradle task, not the application, this is a bit confusing at the beginning

To run or debug you app, you select the appropriate task, in case of Grails task, application/bootrun and double click on it. This will launch your application (after a build if needed), and if it is a web app, you can browse you application in your browser.

When you run the Run task (not the build task) you can also click on 'Debug' icon to debug your application

If you select another task and click debug, you will have a socket exception because IntelliJ thinks you are launching a jvm and tries to connect to it for debugging. (they are lots of predefined task in Gradle : assembling jars, building docs etc... and the Run task may be specific to a project

Generally Build tasks are under the build category and run task under the application category)