Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Gradle 5.0 Dependency #552

Closed
JoelProminic opened this issue May 16, 2019 · 10 comments
Closed

Remove Gradle 5.0 Dependency #552

JoelProminic opened this issue May 16, 2019 · 10 comments

Comments

@JoelProminic
Copy link
Contributor

I noticed previously that Moonshine was creating Gradle 5.0 daemon instances on macOS even though the configured Gradle was 5.4.1: #547 (comment)

This will leave hanging Java processes for Moonshine that will not be cleaned up by #550.

I can trigger the behavior like this. Note that it only seems to trigger on new projects.

  1. Open at least one Gradle project
  2. Close Moonshine
  3. Check the Gradle daemons with "ps -ef | grep GradleDaemon"
  4. Kill all running daemons with "kill -9 "
  5. Start Moonshine
  6. Check the daemons again. You should see only daemons for 5.4.1
  7. Create a new Java Gradle project
  8. Check the daemons again. BUG: a Gradle 5.0 daemon starts.

@rat-moonshine found that a Gradle 5.0.0 JAR is referenced here (and in the config.ini for other environments): https://github.com/prominic/Moonshine-IDE/blob/master/ide/MoonshineSharedCore/src/elements/jdt-language-server/config_mac/config.ini

reference\:file\:org.gradle.toolingapi_5.0.0.v20181217-1554.jar@4,

That jar is included in the language server plugins.

I see some JARs with similar names in the Gradle installation:

$ find ~/Downloads/MoonshineSDKs/Gradle/gradle-5.4.1-bin/ -name "*.jar" | grep -i tool
~/Downloads/MoonshineSDKs/Gradle/gradle-5.4.1-bin//lib/gradle-kotlin-dsl-tooling-models-5.4.1.jar
~/Downloads/MoonshineSDKs/Gradle/gradle-5.4.1-bin//lib/gradle-tooling-api-5.4.1.jar
~/Downloads/MoonshineSDKs/Gradle/gradle-5.4.1-bin//lib/plugins/gradle-kotlin-dsl-tooling-builders-5.4.1.jar
~/Downloads/MoonshineSDKs/Gradle/gradle-5.4.1-bin//lib/plugins/gradle-tooling-api-builders-5.4.1.jar
~/Downloads/MoonshineSDKs/Gradle/gradle-5.4.1-bin//lib/plugins/gradle-tooling-native-5.4.1.jar

Also see the documentation here.

To investigate:

  • Can we use a JAR from the current Gradle installation instead? Will this work for older or newer versions of Grails?
  • Why does this only trigger for new projects?
@rat-moonshine
Copy link
Collaborator

rat-moonshine commented May 21, 2019

Gradle executable now referencing as "$GRADLE_HOME/bin/gradle eclipse" instead of "gradle eclipse" while running the command by setting local-environment to Moonshine. However, I found this specific referencing to Gradle didn't eliminate 5.0.0 inclusion in above test process.

The new referencing way now applicable to language-server start, project compilation, clean etc.

@JoelProminic JoelProminic added this to the v2.3.0 milestone May 21, 2019
@JoelProminic
Copy link
Contributor Author

I haven't had much time to look into this. @rat-moonshine, can you point me to where I can find the code for the different cases where Gradle is called? I want to understand why project creation behaves differently:

  • gradle eclipse
  • gradle
  • Launch the language server.

@rat-moonshine
Copy link
Collaborator

I'm executing 'gradle' call in three areas at this moment:

  1. Prior to language-server start (conditions: if Grails path present and build.gradle file exists to the project directory): JavaLanguageServerManager
  2. Gradle project build: GradleBuildPlugin
  3. Clean project: CleanProject

In all the above cases EnvironmentSetupUtils calls to setup local environments first (based on different SDKs existence) and therefore run the given command(s) at the same time.

@JoelProminic
Copy link
Contributor Author

I checked the Java Language Server processes created by Refresh Gradle Classpath to the copy that is created when a new Java Gradle project is created. I found that the commands were identical (except for the unique hash based on the project name), and the environment was also identical.

The environment did not include any of the installed SDKs, but the Java path was generated from the configured Java SDK.

My next theory is that Moonshine is sending a command to the language server on project creation, which triggers a Gradle instance.

I tried to debug Moonshine in order to find which call to the send methods in https://github.com/prominic/Moonshine-IDE/blob/bba84eadf6cf0e86f69d39f601dff8bc35e08645/ide/MoonshineDESKTOPevolved/src/actionScripts/languageServer/LanguageClient.as#L266

  • sendNotification
  • sendRequest
  • sendResponse

However, I had some trouble the debugger to work correctly. I'll check with @rat-moonshine on this tomorrow.

@joshtynjala, do you have any insight on which action would cause the language server to call a Gradle task for a new Java Gradle project? If this is an action to generate the classpath, we can use the "gradle eclipse" action instead. If this is something more fundamental, we may need to explore how to make the language server use a different Gradle version (a Gradle 5.0.0 JAR is hard-coded here: https://github.com/prominic/Moonshine-IDE/blob/master/ide/MoonshineSharedCore/src/elements/jdt-language-server/config_mac/config.ini).

@joshtynjala
Copy link
Collaborator

joshtynjala commented May 23, 2019

@JoelProminic We're not doing anything manually in Moonshine to tell the Java language server to run Gradle, as far as I know. That's probably just happening automatically as part of the language server's normal launch process.

As I've mentioned, the Java language server automatically searches for and reads the Maven pom.xml or Gradle build.gradle files to configure itself. As part of this process, it automatically creates .project and .classpath files for Eclipse. This is because the language server is basically running a headless version of Eclipse.

I don't think it's possible to tell the language server that we don't want it to create these files.

I was actually surprised that the language server doesn't automatically update the Gradle classpath when the build.gradle file changes, considering it basically does that on startup. Perhaps it's because Moonshine does not currently send "didChangeWatchedFiles" notifications over the language server protocol yet (Adobe AIR doesn't have built in file watchers that would make this easy). Maybe if we sent those notifications, it would automatically update itself without a restart, and we wouldn't need to manually run gradle eclipse at all...

@JoelProminic
Copy link
Contributor Author

I did some more investigation into this today. I see that the config.ini dependencies come from the jdt-language-server build, so I think it is probably a bad idea to try to change them.

The other idea is to try to use this environment variable to prevent the language server from creating a daemon:

set GRADLE_OPTS="-Dorg.gradle.daemon=false"

@rat-moonshine, can you give this a test? This will hurt the performance, but it seems that the language server is not regularly calling Gradle. If it becomes a problem, we can undo this change and look for a different solution.

@JoelProminic
Copy link
Contributor Author

Ah, I keep forgetting that NativeProcess does not have built-in support for environment variables. I see that Moonshine communicates with the language server with the process standardInput and standardOutput, so it may be tricky to keep this working if we set the environment with a separate command.

@rat-moonshine
Copy link
Collaborator

rat-moonshine commented May 24, 2019

I also think the above execution (set GRADLE_OPTS="-Dorg.gradle.daemon=false") could be troublesome to fit in the current language-server initiation structure.

To make the command work we need to execute it inside a local-environment setting batch process. Current language-server initiation also requires to modify to run by the same batch command to accept effect of the GRADLE_OPTS command. The problem is, once the batch process executes the NativeProcess running the batch process also exit.

For language-server I think it requires the NativeProcess to being alive so the language-server can communicate through its channel. So running the language-server through batch process could be problematic.

@JoelProminic
Copy link
Contributor Author

I had the idea to add the .classpath, .project, and .settings files to the Java Gradle template so that they would exist before the language server started the first time on a new project.

This didn't help, and I confirmed that 5.4.1 "gradle eclipse" is running before the language server starts and launches Gradle 5.0.

@joshtynjala
Copy link
Collaborator

Closing because the Java language server provides its own Gradle dependency, with no option to use ad different one, and that's the correct behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants