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

Pico CLI runtime issue on Graal 23 - picocli.CommandLine$InitializationException Cannot instantiate the class has no constructor #2357

Open
Hakky54 opened this issue Dec 30, 2024 · 3 comments

Comments

@Hakky54
Copy link

Hakky54 commented Dec 30, 2024

I noticed that Pico CLI is working on Graal 22 but not on Graal 23 anymore when creating/running a native image. I wasn't quite sure where to create this issue as I am not sure where it could be fixed. So I was in doubt whether Graal has caused an issue and has regression. I wanted to raise this issue first here as you are the library maintainer and maybe can easily find the issue and if it is caused by the Graal changes itself we can provide context to them to resolve it on their side if that is the case.

I am using Pico CLI alongside with Graal to create a native image for Certificate Ripper. Recently I added VersionProvider class which implements CommandLine.IVersionProvider to provide the version. On Graal 22 this works, however on version 23 it gives me the following error:

❯ ./target/crip
Exception in thread "main" picocli.CommandLine$InitializationException: Cannot instantiate nl.altindag.crip.command.VersionProvider: the class has no constructor
        at picocli.CommandLine$DefaultFactory.create(CommandLine.java:5689)
        at picocli.CommandLine$DefaultFactory.createVersionProvider(CommandLine.java:5675)
        at picocli.CommandLine$Model$CommandSpec.updateVersionProvider(CommandLine.java:7494)
        at picocli.CommandLine$Model$CommandSpec.updateCommandAttributes(CommandLine.java:7459)
        at picocli.CommandLine$Model$CommandReflection.extractCommandSpec(CommandLine.java:11845)
        at picocli.CommandLine$Model$CommandSpec.forAnnotatedObject(CommandLine.java:6392)
        at picocli.CommandLine.<init>(CommandLine.java:230)
        at picocli.CommandLine.<init>(CommandLine.java:224)
        at picocli.CommandLine.<init>(CommandLine.java:199)
        at nl.altindag.crip.App.main(App.java:25)
        at [email protected]/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)
Caused by: java.lang.NoSuchMethodException: nl.altindag.crip.command.VersionProvider.<init>()
        at [email protected]/java.lang.Class.checkConstructor(DynamicHub.java:1171)
        at [email protected]/java.lang.Class.getConstructor0(DynamicHub.java:1365)
        at [email protected]/java.lang.Class.getDeclaredConstructor(DynamicHub.java:3004)
        at picocli.CommandLine$DefaultFactory.create(CommandLine.java:5660)
        at picocli.CommandLine$DefaultFactory.create(CommandLine.java:5687)
        ... 10 more

How to reproduce?

  1. Install Graal 22 and 23 from https://www.graalvm.org/downloads/
  2. Make sure your java home is configured to point to version Graal 22
  3. Install maven
  4. run git clone https://github.com/Hakky54/certificate-ripper.git
  5. run mvn clean install -Pnative-image
  6. run ./target/crip (it does not give a runtime exception)
  7. configure java home to graal 23
  8. repeat step 5 and 6 and the runtime exception will be shown

Any idea what the root cause could be? Adding a default constructor to the VersionProvider did not work.

@remkop
Copy link
Owner

remkop commented Dec 30, 2024

This sounds like a bug in GraalVM 23, but just to double check, can you provide the contents of your reflect.json config file?

@Hakky54
Copy link
Author

Hakky54 commented Dec 30, 2024

I had that feeling as well, but wasn't sure.

my graalvm config files looks like:

[
  {
    "name": "nl.altindag.crip.command.CertificateRipper",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true
  },
  {
    "name": "nl.altindag.crip.command.SharedProperties",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "fields": [
      {
        "name": "urls"
      },
      {
        "name": "proxyHost"
      },
      {
        "name": "proxyPort"
      },
      {
        "name": "proxyUser"
      },
      {
        "name": "proxyPassword"
      },
      {
        "name": "timeoutInMilliseconds"
      },
      {
        "name": "resolveRootCa"
      }
    ]
  },
  {
    "name": "nl.altindag.crip.command.PrintCommand",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "fields": [
      {
        "name": "sharedProperties"
      },
      {
        "name": "format"
      }
    ]
  },
  {
    "name": "nl.altindag.crip.command.export.ExportCommand",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true
  },
  {
    "name": "nl.altindag.crip.command.export.FileExport",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "fields": [
      {
        "name": "sharedProperties"
      },
      {
        "name": "destination"
      }
    ]
  },
  {
    "name": "nl.altindag.crip.command.export.CombinableFileExport",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "fields": [
      {
        "name": "combined"
      }
    ]
  },
  {
    "name": "nl.altindag.crip.command.export.KeyStoreExportCommand",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "fields": [
      {
        "name": "password"
      }
    ]
  },
  {
    "name": "nl.altindag.crip.command.export.Pkcs12ExportCommand",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true
  },
  {
    "name": "nl.altindag.crip.command.export.JavaKeyStoreExportCommand",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true
  },
  {
    "name": "nl.altindag.crip.command.export.DerExportCommand",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true
  },
  {
    "name": "nl.altindag.crip.command.export.PemExportCommand",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "fields": [
      {
        "name": "includeHeader"
      }
    ]
  }
]

I also attempted to add:

{
  "name": "nl.altindag.crip.command.VersionProvider",
  "allDeclaredConstructors": true,
  "allPublicConstructors": true,
  "allDeclaredMethods": true,
  "allPublicMethods": true
}

However that resulted in

Exception in thread "main" picocli.CommandLine$InitializationException: picocli.CommandLine$AutoHelpMixin@1e293ee2 is not a command: it has no @Command, @Option, @Parameters or @Unmatched annotations
        at picocli.CommandLine$Model$CommandReflection.validateCommandSpec(CommandLine.java:12029)
        at picocli.CommandLine$Model$CommandReflection.extractCommandSpec(CommandLine.java:11859)
        at picocli.CommandLine$Model$CommandSpec.forAnnotatedObject(CommandLine.java:6392)
        at picocli.CommandLine$Model$CommandSpec.mixinStandardHelpOptions(CommandLine.java:7389)
        at picocli.CommandLine$Model$CommandReflection.extractCommandSpec(CommandLine.java:11854)
        at picocli.CommandLine$Model$CommandSpec.forAnnotatedObject(CommandLine.java:6392)
        at picocli.CommandLine.<init>(CommandLine.java:230)
        at picocli.CommandLine.toCommandLine(CommandLine.java:3635)
        at picocli.CommandLine.access$16700(CommandLine.java:148)
        at picocli.CommandLine$Model$CommandReflection.initSubcommands(CommandLine.java:11884)
        at picocli.CommandLine$Model$CommandReflection.extractCommandSpec(CommandLine.java:11850)
        at picocli.CommandLine$Model$CommandSpec.forAnnotatedObject(CommandLine.java:6392)
        at picocli.CommandLine.<init>(CommandLine.java:230)
        at picocli.CommandLine.<init>(CommandLine.java:224)
        at picocli.CommandLine.<init>(CommandLine.java:199)
        at nl.altindag.crip.App.main(App.java:25)
        at [email protected]/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)

@Hakky54
Copy link
Author

Hakky54 commented Dec 30, 2024

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

No branches or pull requests

2 participants