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

5.0.x fix graalvm resolution #370

Open
wants to merge 22 commits into
base: 5.0.x
Choose a base branch
from

Conversation

codeconsole
Copy link
Contributor

@codeconsole codeconsole commented Feb 1, 2025

This addresses

java.lang.ClassNotFoundException: org.graalvm.polyglot.Context
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)

This exception occurs because org.graalvm.polyglot:polyglot is not present in the classpath, but this is expected because that dependency is not part of graalvm 22.0.0.2. So if an application is using a later version of graalvm, they will get an exception asset-pipeline-gradle uses 22.0.0.2 and the plugin does not automatically look for an include the polygot dependency.

Currently, dependencies are added to the bootRun task if the dependency starts with a particular string, but this is actually resulting in unwanted dependencies being added such as findbugs jsr305 and jspecify which aren't even needed simply because file.name.startsWith('js').

if (file.name.startsWith('graal') || file.name.startsWith('js') || file.name.startsWith('rhino-') || file.name.startsWith('closure-compiler-unshaded-')) {
additionalFiles.add(file)
}

All these things are done in the background and there is no way to know that they are being resolved in the final bootRun classpath.

This PR simplifies everything, makes it more maintainable, and provides better exposure to understand what exactly is being added to the bootRun classpath.

  1. It simply adds the asset-pipeline-gradle plugin as a dependency to bootRun and provide a mechanism for listing the resolved dependencies which are those propagated through the api scope. If more dependencies are needed, they can be added as api to the asset-pipeline-gradle project.
gradle dependencies --configuration assetDevelopmentRuntime

assetDevelopmentRuntime
\--- com.bertramlabs.plugins:asset-pipeline-gradle:5.0.6
     +--- com.bertramlabs.plugins:asset-pipeline-core:5.0.6
     |    \--- org.slf4j:slf4j-api:1.7.28 -> 2.0.16
     +--- com.google.javascript:closure-compiler-unshaded:v20240317
     |    +--- args4j:args4j:2.33
     |    +--- com.google.code.gson:gson:2.9.1 -> 2.11.0
     |    |    \--- com.google.errorprone:error_prone_annotations:2.27.0 -> 2.28.0
     |    +--- com.google.errorprone:error_prone_annotations:2.18.0 -> 2.28.0
     |    +--- com.google.guava:failureaccess:1.0.1 -> 1.0.2
     |    +--- com.google.guava:guava:32.1.2-jre -> 33.3.1-jre
     |    |    +--- com.google.guava:failureaccess:1.0.2
     |    |    +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
     |    |    +--- com.google.code.findbugs:jsr305:3.0.2
     |    |    +--- org.checkerframework:checker-qual:3.43.0
     |    |    +--- com.google.errorprone:error_prone_annotations:2.28.0
     |    |    \--- com.google.j2objc:j2objc-annotations:3.0.0
     |    +--- com.google.protobuf:protobuf-java:3.21.12
     |    +--- com.google.re2j:re2j:1.3
     |    \--- org.jspecify:jspecify:0.2.0 -> 1.0.0
     +--- org.graalvm.sdk:graal-sdk:24.1.2
     |    +--- org.graalvm.sdk:collections:24.1.2
     |    +--- org.graalvm.sdk:nativeimage:24.1.2
     |    |    \--- org.graalvm.sdk:word:24.1.2
     |    +--- org.graalvm.polyglot:polyglot:24.1.2
     |    |    +--- org.graalvm.sdk:collections:24.1.2
     |    |    \--- org.graalvm.sdk:nativeimage:24.1.2 (*)
     |    \--- org.graalvm.sdk:word:24.1.2
     +--- org.graalvm.js:js:24.1.2
     |    \--- org.graalvm.truffle:truffle-enterprise:24.1.2
     |         +--- org.graalvm.truffle:truffle-compiler:24.1.2
     |         +--- org.graalvm.truffle:truffle-runtime:24.1.2
     |         |    +--- org.graalvm.sdk:jniutils:24.1.2
     |         |    |    +--- org.graalvm.sdk:collections:24.1.2
     |         |    |    \--- org.graalvm.sdk:nativeimage:24.1.2 (*)
     |         |    +--- org.graalvm.truffle:truffle-api:24.1.2
     |         |    |    +--- org.graalvm.sdk:collections:24.1.2
     |         |    |    +--- org.graalvm.sdk:nativeimage:24.1.2 (*)
     |         |    |    \--- org.graalvm.polyglot:polyglot:24.1.2 (*)
     |         |    \--- org.graalvm.truffle:truffle-compiler:24.1.2
     |         +--- org.graalvm.sdk:jniutils:24.1.2 (*)
     |         \--- org.graalvm.sdk:nativebridge:24.1.2
     |              \--- org.graalvm.sdk:jniutils:24.1.2 (*)
     +--- org.graalvm.js:js-language:24.1.2
     |    +--- org.graalvm.regex:regex:24.1.2
     |    |    +--- org.graalvm.truffle:truffle-api:24.1.2 (*)
     |    |    \--- org.graalvm.shadowed:icu4j:24.1.2
     |    +--- org.graalvm.truffle:truffle-api:24.1.2 (*)
     |    +--- org.graalvm.polyglot:polyglot:24.1.2 (*)
     |    \--- org.graalvm.shadowed:icu4j:24.1.2
     \--- org.graalvm.js:js-scriptengine:24.1.2
          \--- org.graalvm.polyglot:polyglot:24.1.2 (*)
  1. asset dependencies are also added and can be listed via the assets configuration
gradle dependencies --configuration assets 

assets
\--- com.bertramlabs.plugins:less-asset-pipeline:5.0.6
     +--- com.bertramlabs.plugins:asset-pipeline-core:5.0.6
     |    \--- org.slf4j:slf4j-api:1.7.28 -> 2.0.16
     +--- org.mozilla:rhino:1.7R4
     +--- org.slf4j:slf4j-api:1.7.28 -> 2.0.16
     +--- com.github.sommeri:less4j:1.17.2
     |    +--- org.antlr:antlr-runtime:3.5.2
     |    +--- commons-io:commons-io:2.3
     |    +--- commons-beanutils:commons-beanutils:1.8.3
     |    |    \--- commons-logging:commons-logging:1.1.1
     |    +--- com.google.code.gson:gson:2.5 -> 2.11.0
     |    |    \--- com.google.errorprone:error_prone_annotations:2.27.0
     |    \--- com.google.protobuf:protobuf-java:2.5.0
     \--- com.github.sommeri:less4j-javascript:0.0.1
          +--- junit:junit:4.11 -> 4.13.2
          |    \--- org.hamcrest:hamcrest-core:1.3 -> 2.2
          |         \--- org.hamcrest:hamcrest:2.2
          +--- com.github.sommeri:less4j:1.5.2 -> 1.17.2 (*)
          \--- ro.isdc.wro4j:rhino:1.7R5-20130223-1
  1. updates graalvm to 24.1.2
  2. updates gradle to 8.12.1

Pros

Simple
Makes class path resolution understood
Simplifies code
Imports dependencies as expected
Allows maintaining of dependencies via build.gradle

Cons

Adds a single gradle plugin asset-pipeline-gradle jar to the bootRun classpath, but this has the added advantage of not needing to hard code graalvm versions inside the plugin code.

@codeconsole codeconsole marked this pull request as draft February 1, 2025 16:35
@codeconsole
Copy link
Contributor Author

grails/grails-core#13992

@codeconsole
Copy link
Contributor Author

codeconsole commented Feb 1, 2025

Previous behavior

runtimeOnly "com.bertramlabs.plugins:asset-pipeline-grails:$assetPipeline"
assets "com.bertramlabs.plugins:less-asset-pipeline:$assetPipeline"

results in:

asset-pipeline: Adding build dependency ~/.gradle/caches/modules-2/files-2.1/com.google.javascript/closure-compiler-unshaded/v20240317/99d0e978e433293899988a8e40c98af3732dd518/closure-compiler-unshaded-v20240317.jar to bootRun
asset-pipeline: Adding build dependency ~/.gradle/caches/modules-2/files-2.1/org.graalvm.js/js/22.0.0.2/82e4e3e2cf84a883275f5768dd9c5010b459b3a3/js-22.0.0.2.jar to bootRun
asset-pipeline: Adding build dependency ~/.gradle/caches/modules-2/files-2.1/org.graalvm.js/js-scriptengine/22.0.0.2/d1897f2b0b4c93d79a6267498fd43af7e2be824f/js-scriptengine-22.0.0.2.jar to bootRun
asset-pipeline: Adding build dependency ~/.gradle/caches/modules-2/files-2.1/org.graalvm.sdk/graal-sdk/22.0.0.2/3e6a30de6d2e3ea94ec5976ab37a850f96d78ee3/graal-sdk-22.0.0.2.jar to bootRun
asset-pipeline: Adding build dependency ~/.gradle/caches/modules-2/files-2.1/org.jspecify/jspecify/1.0.0/7425a601c1c7ec76645a78d22b8c6a627edee507/jspecify-1.0.0.jar to bootRun
asset-pipeline: Adding build dependency ~/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/3.0.2/25ea2e8b0c338a877313bd4672d3fe056ea78f0d/jsr305-3.0.2.jar to bootRun
Resolving global dependency management for project 'test'
asset-pipeline: Adding asset dependency ~/.m2/repository/com/bertramlabs/plugins/less-asset-pipeline/5.0.6/less-asset-pipeline-5.0.6.jar to bootRun
asset-pipeline: Adding asset dependency ~/.m2/repository/com/bertramlabs/plugins/asset-pipeline-core/5.0.6/asset-pipeline-core-5.0.6.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/org.mozilla/rhino/1.7R4/e982f2136574b9a423186fbaeaaa98dc3e5a5288/rhino-1.7R4.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/2.0.16/172931663a09a1fa515567af5fbef00897d3c04/slf4j-api-2.0.16.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/com.github.sommeri/less4j-javascript/0.0.1/33331ee5198840394bd7ff02a8a7ef506c0f4975/less4j-javascript-0.0.1.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/com.github.sommeri/less4j/1.17.2/fc3ebef050a46839593b2e6f22ab43850f189923/less4j-1.17.2.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/org.antlr/antlr-runtime/3.5.2/cd9cd41361c155f3af0f653009dcecb08d8b4afd/antlr-runtime-3.5.2.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/commons-io/commons-io/2.3/cd8d6ffc833cc63c30d712a180f4663d8f55799b/commons-io-2.3.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/commons-beanutils/commons-beanutils/1.8.3/686ef3410bcf4ab8ce7fd0b899e832aaba5facf7/commons-beanutils-1.8.3.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.11.0/527175ca6d81050b53bdd4c457a6d6e017626b0e/gson-2.11.0.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/com.google.protobuf/protobuf-java/2.5.0/a10732c76bfacdbd633a7eb0f7968b1059a65dfa/protobuf-java-2.5.0.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/junit/junit/4.13.2/8ac9e16d933b6fb43bc7f576336b8f4d7eb5ba12/junit-4.13.2.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/ro.isdc.wro4j/rhino/1.7R5-20130223-1/83f4a63640881f9ac0d18eb6f17b94c090ccc8d/rhino-1.7R5-20130223-1.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/commons-logging/commons-logging/1.1.1/5043bfebc3db072ed80fbd362e7caf00e885d8ae/commons-logging-1.1.1.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/com.google.errorprone/error_prone_annotations/2.27.0/91b2c29d8a6148b5e2e4930f070d4840e2e48e34/error_prone_annotations-2.27.0.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/2.2/3f2bd07716a31c395e2837254f37f21f0f0ab24b/hamcrest-core-2.2.jar to bootRun
asset-pipeline: Adding asset dependency ~/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest/2.2/1820c0968dba3a11a1b30669bb1f01978a91dedc/hamcrest-2.2.jar to bootRun

@codeconsole
Copy link
Contributor Author

#352

@matrei
Copy link

matrei commented Feb 3, 2025

@codeconsole I have many comments about this project, but for this PR:

grails-web-taglib is needed for taglib compilation in asset-pipeline-grails as dependencies have been cleaned up in grails-gsp:

compileOnly 'org.grails:grails-web-taglib' // For taglib compilation

I think these are the only js-related dependencies needed in asset-pipeline-core:

// Library consumers should be provide engines if they need them, to not bloat other consumers
// This could possibly be refactored to use javax.script.ScriptEngine API (JSR-223), and/or pluggable implementations
compileOnly "org.graalvm.polyglot:polyglot:$graalvmVersion"
compileOnly 'com.google.javascript:closure-compiler-unshaded:v20240317'

And these in asset-pipeline-gradle:

runtimeOnly "org.graalvm.js:js-community:$graalvmVersion"
runtimeOnly 'com.google.javascript:closure-compiler-unshaded:v20240317'

Now, using js-community will fix the java.util.zip.ZipException: zip END header not found in the https://github.com/codeconsole/grails-resource-bug project.

@codeconsole
Copy link
Contributor Author

codeconsole commented Feb 3, 2025

@matrei other than fixing the spacing on the gradle files, this pull request is only to address the dependency resolution issue in bootRun. This PR is not for java.util.zip.ZipException: zip END header not found. Please look specifically at AssetPipelinePlugin.groovy

Rather than using startsWith and adding jars individually by text search, it leverages gradle dependency management and only adds the jars exposed by the asset-pipeline-gradle plugin via api.

js-community is a pom file and is being transitively resolved by org.graalvm.js:js Adding it is a compileOnly will not change that behavior. It only adds 1 net dependency which can be accounted for separately.

The end result of this PR is it stops resolving jsr305 and jspeciify from being added to the bootRun classpath and it resolves the missing transitive dependencies that were previously needed.

In versions of this plugin < 5.0, there were never api dependencies on asset-pipeline-core.

@matrei
Copy link

matrei commented Feb 3, 2025

@codeconsole Sorry for not being explicit, I think the change to AssetPipelinePlugin is good.

But in addition, my suggestions are focused on cleaning up the dependencies. org.graalvm.js:js is what is bringing the org.graalvm.js:js-community pom file into the runtime dependencies, and by going directly to js-community instead we don't have that problem any more. Also there is no need to set the js dependencies in asset-pipeline-gradle to api. They are only needed at runtime.

Also, without the addition of the org.grails:grails-web-taglib to asset-pipeline-grails the asset taglib is not going to work.

asset-pipeline-core/build.gradle Outdated Show resolved Hide resolved
asset-pipeline-core/build.gradle Outdated Show resolved Hide resolved
asset-pipeline-core/build.gradle Outdated Show resolved Hide resolved
asset-pipeline-gradle/build.gradle Outdated Show resolved Hide resolved
asset-pipeline-gradle/build.gradle Outdated Show resolved Hide resolved
asset-pipeline-gradle/build.gradle Outdated Show resolved Hide resolved
asset-pipeline-gradle/build.gradle Outdated Show resolved Hide resolved
@codeconsole
Copy link
Contributor Author

@matrei I don't have the time to burn on this. I just wanted to get the plugin working correctly. We can clean it up in a separate PR. I didn't add any dependencies, I just made graalvm version a property.

@codeconsole
Copy link
Contributor Author

@matrei I added you as a collaborator to my repository. Feel free to add to my PR if you want.

@matrei
Copy link

matrei commented Feb 4, 2025

@codeconsole OK, I'll give it a swing.

Minor cleanup of unused imports and changing `@Commons` to `@Slf4j`.
… Groovy idioms

- Adopt more up-to-date Gradle API usage for better compatibility and maintainability.
- Refactor to leverage Groovy language features for cleaner and more idiomatic code.
@matrei
Copy link

matrei commented Feb 5, 2025

@codeconsole OK, I'm done!

@codeconsole
Copy link
Contributor Author

codeconsole commented Feb 5, 2025

Sweet, thanks @matrei !

@codeconsole
Copy link
Contributor Author

@matrei I am impressed, you really cleaned this up!
@davydotcom please merge and release ASAP

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

Successfully merging this pull request may close these issues.

2 participants