GraalVM: Error Reading License File

I have a Kotlin application and am trying to compile to a native binary using GraalVM using these versions:

Java version: 22.0.1+8, vendor version: GraalVM CE 22.0.1+8.1

We are using Aspose.Cells.Java version 24.1 and we’re locked into that version for a while due to other factors.

The native compilation completes successfully.

The app attempts to load the Aspose license like this:

License().setLicense(clazz.getResourceAsStream("/Aspose.Cells.Java.lic"))

But it fails with this error:

Cannot find black listed licenses resource or black list is invalid. Please report this error to Aspose.

I know the license file is in the native image. This code reads the license file contents and dumps it to the console, so I know it’s there:

val licenseText = clazz.getResource("/Aspose.Cells.Java.lic").readText()
println("*** licenseText  ***\n$licenseText")

I can see the license text in the console.

Since I can read the license file contents, I tried using a StringReader the wrap the license file text, and pass that to the setLicense method:

License().setLicense(StringReader(clazz.getResource("/Aspose.Cells.Java.lic").readText()))

But it throws the same error as before:

Cannot find black listed licenses resource or black list is invalid. Please report this error to Aspose.

So I know the license file is there as I can read it and dump it to the console, but when using multiple methods to have Aspose read the license file, it fails.

What’s the problem?

Thank you!!

@coyote58

It seems that you are encountering an issue with loading the Aspose license file in your Kotlin application when compiling to a native binary using GraalVM. The error message indicates that the license resource cannot be found or that the blacklist is invalid.

Here are a few suggestions to troubleshoot and resolve this issue:

  1. Check License File Location: Ensure that the license file (Aspose.Cells.Java.lic) is correctly placed in the resources directory of your project. The path you are using (/Aspose.Cells.Java.lic) should correspond to the actual location of the file in your compiled native image.

  2. Use InputStream: Since you are able to read the license file contents, you can try passing the InputStream directly to the setLicense method. Here’s an example of how to do this:

    val inputStream = clazz.getResourceAsStream("/Aspose.Cells.Java.lic")
    if (inputStream != null) {
        License().setLicense(inputStream)
    } else {
        println("License file not found.")
    }
    
  3. Verify Native Image Configuration: GraalVM native images require specific configurations for resource inclusion. Make sure that your native image build configuration includes the license file. You may need to specify resource inclusion in your native-image command or configuration file.

  4. Check for Blacklist Issues: The error message mentions a blacklist. Ensure that there are no issues with the license file itself, such as it being blacklisted or invalid. You may want to contact Aspose support if you suspect this is the case.

  5. Debugging: Since you can print the license text to the console, it confirms that the file is accessible. However, if the above steps do not resolve the issue, consider adding more logging to understand where the process fails.

If you continue to face issues, it may be helpful to consult the Aspose documentation or reach out to their support for further assistance.

Sources:

I’ve done all that. It must be a problem somewhere inside Aspose and I don’t know how to work around it or fix it.

@coyote58,

There can be two possibilities we can think for your licensing issue. The original jar file of Aspose.Cells has been changed or you set the license in multi-threads. So, you should take care of the first and make sure the Aspose.Cells.jar should not been changed. Moreover, if you are using/setting your license in multi-threaded application. Please make sure licensing code is processed only once and at first for the whole application life cycle, no need to get/set it multiple times. Please check whether the code of setting license are being executed repeatedly and concurrently, so you should fix it on your end. Also, if you restart the application, does it remove the issue for a while or not?

Hello,

Thank you for the response!

We aren’t trying to set the license in multiple threads. My small test case runs as soon as the app is starting up, before it is even accepting any HTTP requests, so that’s not it.

Regarding changing the jar file: I know the ShadowJar process (which bundles our app and all dependent apps into a single “uber” jar) reads the Aspose jar into our single jar. The resulting “uber” jar runs successfully when run as on the JVM as a “normal” Kotlin app.

The GraalVM native compile takes that “uber” jar and compiles it to native, so it’s reading the “uber” jar and compiling to native.

Are there static files (like text files or something else) from the Aspose jar that I need to make sure make it into the native image? Like any signing files, or anything like that? If you know that there are I can make sure those make it into the native image.

Thank you!

@coyote58
Would you like to create a simple console program and check if the license can be successfully set up?

About how to check if the License is loaded successfully, please refer to the following document.

If you still could not make it work (after setting the licensing code correctly in your program), kindly do provide your new (SHA1) signed license file but via private message. In order to send a private message with attachment (license file - please zip the file first), please click on my name and find “Message” button. Now, please attach the zipped archive containing the license and send us. We will investigate the issue with your provided license.
Also, see the topic on how to send the license to Aspose staff for your reference.
https://forum.aspose.com/t/how-to-send-license-file-to-support-team/225542

@John.He @amjad.sahi

I figured it out. There were GraalVM configuration files missing. Those configuration files tell GraalVM how to access static resources from within the native image.

Those configuration files can be created by hand, but it’s probably easier to use GraalVM itself to generate them, which is what I did.

To have GraalVM generate the configuration files for you, first be sure you’re using the GraalVM and not a regular JDK.

Then, run your application normally in the JVM (as in, not trying to compile it as native). When starting the JVM, be sure to add this JVM flag option adds an agent:

-agentlib:native-image-agent=config-output-dir=./src/main/resources/META-INF/native-image

In the above, you can use any output directory you want, but I chose to put them in my application’s src/main/resources/META-INF/native-image directory, because that’s where native-image looks for configuration files during the native compilation process.

When the JVM is started with the agent attached, exercise your application through all code paths to ensure that the agent catches everything that it needs to see.

After you’ve run the application, you’ll see some JSON configuration files in the configured output directory.

In this particular case, for Aspose, there are entries in the resource-config.json file that help Aspose find the files it needs when setting the license.

Once I had those configuration files, I was able to compile the application to native. At runtime, the license was found, as expected. I’m running into other problems with AWT, but I’m tackling those next.

Thank you for the help!!

See previous reply. I was able to get past the license error. Thank you!

@coyote58

Good to know your issue has been solved. And thank you very much for the provided details about the solution. We believe it will be very helpful for others who may encounter the similar issues with GraalVM. And you’re welcome to reach out to us again if you have any other questions.

1 Like