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

Use provided configuration for optional language dependencies #411

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

jevanlingen
Copy link
Contributor

What's changed?

Groovy, Kotlin and CSharp dependencies are changed to compileOnly. The filechecker-classes have been adjusted with a reflection check

What's your motivation?

Checklist

  • I've added unit tests to cover both positive and negative cases
  • I've read and applied the recipe conventions and best practices
  • I've used the IntelliJ IDEA auto-formatter on affected files

…s and add file-checkers with a reflection-class-exists-check
build.gradle.kts Outdated Show resolved Hide resolved
Co-authored-by: Tim te Beek <[email protected]>
@jevanlingen jevanlingen marked this pull request as ready for review December 23, 2024 12:06
@jevanlingen jevanlingen self-assigned this Dec 23, 2024
@jevanlingen jevanlingen added the enhancement New feature or request label Dec 23, 2024
@jkschneider
Copy link
Member

I'd like to use the old nebula provided configuration plugin instead here, such that the dependency winds up with a provided scope. Most of the tooling we have that executes recipes have runtime dependencies on language bindings and "provide" them in a parent classloader scheme that is highly similar to the original intent of the provided scope in Maven (in the old days when J2EE containers provided servlet types, etc.).

https://github.com/nebula-plugins/gradle-extra-configurations-plugin?tab=readme-ov-file#using-the-provided-plugin

public class ClassPathUtils {
public static boolean isAvailable(String className) {
try {
Class.forName(className);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one thing I'm wondering here but I'm not sure about, is if the classloader used here would contain the C# / Groovy / Kotlin classes we are likely to parent class load in the CLI & Platform. Something to keep an eye on I suppose.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only just now saw this comment; indeed makes most sense to add those <provided> dependencies, which are missing right now after a publish to Maven local.

  <dependencies>
    <dependency>
      <groupId>org.jetbrains</groupId>
      <artifactId>annotations</artifactId>
      <version>26.0.1</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.openrewrite</groupId>
      <artifactId>rewrite-java</artifactId>
      <version>8.43.0-SNAPSHOT</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.openrewrite.meta</groupId>
      <artifactId>rewrite-analysis</artifactId>
      <version>2.15.0-SNAPSHOT</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-text</artifactId>
      <version>1.13.0</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.openrewrite</groupId>
      <artifactId>rewrite-templating</artifactId>
      <version>1.21.0-SNAPSHOT</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should always use this form and set the initialize boolean to false so that static initializers etc don't get executed unintentionally.

image

is if the classloader used here would contain the C# / Groovy / Kotlin classes we are likely to parent class load in the CLI & Platform

@timtebeek yes it would, because by default forName uses the classloader of ClassPathUtils, which will be in the same classloader as the recipe whose parent classloader contains the language specific classes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would much prefer this utility goes in openrewrite/rewrite's ReflectionUtils as it is likely to be used in other recipe modules.

image

@jkschneider jkschneider changed the title Use compileOnly configuration for optional language dependencies Use provided configuration for optional language dependencies Dec 23, 2024
}
apply(plugin = "com.netflix.nebula.provided-base")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't have both a plugin id block above and also an apply call. This apply mechanism is an old way of applying plugins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Ready to Review
Development

Successfully merging this pull request may close these issues.

Use compileOnly configuration for optional language dependencies
3 participants