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

Typed Exceptions #666

Closed
mahesh-hegde opened this issue Apr 12, 2023 · 13 comments
Closed

Typed Exceptions #666

mahesh-hegde opened this issue Apr 12, 2023 · 13 comments
Labels
lang-java Related to Java support package:jni package:jnigen type-enhancement A request for a change that isn't a bug

Comments

@mahesh-hegde
Copy link
Contributor

mahesh-hegde commented Apr 12, 2023

Status Quo:

  • Any exception in JNI would be thrown as JniException. Since resource management of references is hard with exceptional control flow, we serialize the exception message and stack trace into a string and throw it as a single type JniException in dart.

Problems with this approach:

  • It's hard to catch specific exception in this way. Let's say I only want to catch IOException, there's no way to do this except inspecting the string representation.
  • Some exception types carry additional information along with the message, which will be lost.

Implementation options

  1. Exceptions as first-class JNI objects:

    • Map each Exception to a JObject subclass, as we did before.
    • keep a central registry at package:jni which maps qualfiied name (FQN) of Java Exception types to their constructors. This is required because we must decide the type of JThrowable when we are rethrowing it in Dart.
    • Provide convenience methods to obtain stack trace.
  2. Generate marker exception classes which correspond to Java exception types.

    • These are not JObject subclasses, and hold no JNI references. Can directly subclass current JniException. All functionality would be in JniException, and subclass is just a marker.
    • But still need a central registry to look up the FQN of the exception object and throw appropriate type.
    • Pro: resource management. Con: lose access to specialized methods of few exception types.
@mahesh-hegde mahesh-hegde added package:jnigen lang-java Related to Java support type-enhancement A request for a change that isn't a bug and removed package:jnigen labels Apr 12, 2023
@mahesh-hegde
Copy link
Contributor Author

I have an initial design for this.

Initial Design:

Exceptions will be mapped to instances of JObject subclasses corresponding to the class of the exception.

If the corresponding exception class is not available (i.e neither generated as a binding, nor linked from another JNIgen module using config), it will be mapped to a generic JNIException consisting of a stack trace and error message obtained from toString().

However, we need to override toString on these types, because we want to print Java stack trace on error.

So we create an intermediate class, JExceptionObject which overrides toString, and also ensure all classes directly or indirectly extending Exception or Error in Java inherit this.

This analysis, of whether a type is exception type, may prove to be impossible at times. We add another condition.

A type will be mapped as subclass of JExceptionObject iff either

  1. It's provably a subclass of Java Exception type Throwable.

OR

  1. It's names ends in Exception or Error.

this can be configured as regex from YAML.

exceptions:
  exception_types:
    - ".*Problem"
    - com.company.MyCustomErrorTypeWithCustomSuffix
  name_heuristic: false ## disable mapping based on suffix alone (`Exception` or `Error`).

Marker types

Let's say we bind a library, we want to catch java.io.FileNotFoundException to distinguish it from other exceptions. But java.io.FileNotFoundException is not in the set of bindings to be generated.

In such cases we give an option to specify exception marker types, which extend the generic JException with no overridden functionality.

exceptions:
  generate_markers:
    - 'java.io.FileNotFoundException'

Resource management

This design opts for keeping JObjects in Exception objects, which is useful to access properties of custom exception types. For instance URISyntaxException gives getIndex() and getInput().

Also I believe this aligns with our objective of being faithful to source Java API as much as possible, without adding additional abstraction on dart side.

Due to keeping the JObject reference, it's on the caller to dispose the JExceptionObject so obtained. I suppose NativeFinalizer is sufficient to take care of this.

implementation

Mapping of exceptions thrown in Java, to wrapper / marker types in Dart is a dynamic process. Only once an exception is thrown, we get to determine what's the type of the exception.

I think here's a choice we need to make:

  1. Maintain a central registry mapping from class FQN (can be implemented as a package:jni function). Upon library initialization, which happens upon first access of a library symbol (and already involves loading the DLL), register the mapping from FQN -> Exception class constructor.

    But this design is not "correct". If you get a libraryB.Exception before ever accessing libraryB, you will get a generic JException

  2. Make the library initialization explicit. This will end up requiring the user to register each JNI binding library before using them. We can just use a function of this form. 1

Jni.initializeLibraries([
  libraryA.init,
  libraryB.init,
  libraryC.init,
]);
  1. Any other ideas?

cc: @dcharkes @HosseinYousefi @mkustermann

Footnotes

  1. For migration & ease of use, we can always add a check on first access.

@dcharkes
Copy link
Collaborator

Maintain a central registry mapping from class FQN (can be implemented as a package:jni function). Upon library initialization, which happens upon first access of a library symbol (and already involves loading the DLL), register the mapping from FQN -> Exception class constructor.

  • keep a central registry at package:jni which maps qualfiied name (FQN) of Java Exception types to their constructors. This is required because we must decide the type of JThrowable when we are rethrowing it in Dart.

Could you elaborate why do we need this for exceptions, but not for return values of methods?

@mahesh-hegde
Copy link
Contributor Author

Could you elaborate why do we need this for exceptions, but not for return values of methods?

For return values, the mapping is statically known. If I have a method getTitle, I statically know it returns a java.lang.String.

In contrast, any type of exception can get thrown during execution of any method. Once you get an exception result from a method, let's say called, openConfigurationFile(), all you have is a jthrowable a.k.a Pointer<Void>.

To differentiate whether it's a say FileNotFoundException, URISyntaxException, IllegalArgumentException, or OutOfMemoryError, we must do a runtime check, to find out what is the class of the jthrowable we got.

But we want to distinguish exceptions based on their source type, so that we can, for example, only catch FileNotFoundException and retry. So this check is necessary.

Feel free to correct me if you can think of a way around it.

@dcharkes
Copy link
Collaborator

I was thinking that if we have the list of classes that we generate for already, then we can't we use that list of classes? Is it because we only know the fully qualified name and thus only what wrapper to instantiate at runtime?

This is actually somewhat similar to if B extends A, a method returns A statically but B at runtime, we return a JNIgen generated A to the user and the Dart is B check would fail, even though the backing object in Java is a B. Or am I mistaken?

If I understand you correctly, one way to fix both these issues is to construct a Map<String fullyQualifiedName, JObject Function() constructor> so that we can instantiate the a Dart object of the right type. And constructing this map requires some kind of global init.

@mahesh-hegde
Copy link
Contributor Author

mahesh-hegde commented Aug 16, 2023

This is actually somewhat similar to if B extends A, a method returns A statically but B at runtime, we return a JNIgen generated A to the user and the Dart is B check would fail, even though the backing object in Java is a B. Or am I mistaken?

Yeah this is similar. The static return type of method is A, and to instantiate B with a runtime check is not a good abstraction. This should be rather solved with a helper method [#266]. Anyway A is precise enough for most use case.

In case of exceptions though, only type we statically know is Throwable, which is very imprecise. Since exception handling is much rarer than method return, and we need more precision than this, using a runtime check for concrete type could be a good idea.

If I understand you correctly, one way to fix both these issues is to construct a Map<String fullyQualifiedName, JObject Function() constructor> so that we can instantiate the a Dart object of the right type. And constructing this map requires some kind of global init.

Right.

@dcharkes
Copy link
Collaborator

I'd say that if we solve it for exceptions, we should consider doing the same for normal objects (unless it's prohibitively expensive, then maybe we should add a castToRuntimeType or something).

I assume we wouldn't need this for checked exceptions, because we know the list of exceptions then. (That is, if our parsers see that data.)

But this design is not "correct". If you get a libraryB.Exception before ever accessing libraryB, you will get a generic JException

We could potentially detect with the library imports that one library is using another one.
Or we should make it such that in their init function someone can call another init function.
I think we should try to avoid having the end user having to list the transitive closure of all JNIgen-generated packages.

@mahesh-hegde
Copy link
Contributor Author

unless it's prohibitively expensive

We should consider tree shaking for a small set of exception types vs all types? Keeping MyClass.fromRef in a map implies it can be called dynamically.

Besides, Its overhead will surely exceed that of method call itself. I don't think you can do it without a JNI method call to getClass() then getName(). Even if we find a way to do getClassName in below snippet with 1 JNI call, the strings result in some more calls. (I am not aware of any integer based "primary key" ID mechanism for classes, so we have to use FQN).

JObjectPtr className = getClassName(reference);
String name = className.toDartString(deleteOriginal: true);
A Function(JObjectPtr) constructor = registry.lookup(name);
return constructor(reference);

Subtyping complicates it further. If you return a private subtype of B called Bx, you should either traverse Bx's parents until you obtain a known class, which will be even more expensive to do on happy path. (I am not sure we should do it on exception path either, it depends on how pervasive private subtypes are).

castToRuntimeType

We can add an instanceOf(type) and isSameType(otherJobject) instead. #639 .

Or we should make it such that in their init function someone can call another init function.

Why didn't I think of this 😃 This should solve the problem. Thanks.

I assume we wouldn't need this for checked exceptions, because we know the list of exceptions then. (That is, if our parsers see that data.

For the functions which throw checked exceptions, we still need to do some matching to check the type.

I think you meant something like this.

// Serial matchiing
final exception = result.exception
if (JNIEnv.isAssignable(exception, Exception1_jclass)) {
  return Exception1.fromRef(exception);
} else if (JNIEnv.isAssignable(exception, Exception2_jclass)) {
  return Exception2.fromRef ...
} else if (...) {
...
...
...
} else {
  // Could be an unchecked exception not mentioned in the signature.
  return exceptionFromLookup(exception);
}

This is cumbersome, and more generated code. Not to mention now we have to handle the lifecycle of Exception1_jclass etc..

Another thing is if you have a method declared as throws IOException, but want to catch a more specific one like FileNotFoundException, this is not helpful.

So I think we should rather use the same mechanism for both.

Even with a method having single checked exception, you can still have other unchecked exceptions from 10 methods deep.

Is there a better way you thought of with checked exceptions?

@HosseinYousefi
Copy link
Member

We know which exceptions can be thrown from a method, right?

void f() throws IOException, URISyntaxException, IllegalArgumentException {
  // ...
}

Can we throw something like Union3<IOException, URISyntaxException, IllegalArgumentException>, and then if the exception is found to be IOException, you can check if e.instanceOf(FileNotFoundException.type) to get a more exact type.

@mahesh-hegde
Copy link
Contributor Author

I am aiming for a usage like:

on (FileNotFoundException) catch e {

}

Maybe this is not essential at all, as you said.

@mahesh-hegde
Copy link
Contributor Author

We know which exceptions can be thrown from a method, right?

Technicaly, we know a subset of them. All exceptions declared in method signature AND any unchecked exception.

@HosseinYousefi
Copy link
Member

I am aiming for a usage like:

on (FileNotFoundException) catch e {

}

Maybe this is not essential at all, as you said.

If we write code like on X catch e then surely we know X. Probably we can write code that uses X.type instead and provide nice enough helper methods on the thrown object.

try {
  Foo.bar();
} on JException catch (e) {
  if (e.instanceOf(X.type)) {
    e.castTo(X.type, deleteOriginal: true).usefulMethod();
  }
}

Do you think it's worth the complications to change the above code to this?

try {
  Foo.bar();
} on X catch (e) {
  e.usefulMethod();
}

@mahesh-hegde
Copy link
Contributor Author

Right then,

we just have to make JException a subtype of JObject and make getStackTrace() lazy, I guess.

@HosseinYousefi
Copy link
Member

We just have to make JException a subtype of JObject and make getStackTrace() lazy, I guess.

Sounds like a plan!

@HosseinYousefi HosseinYousefi transferred this issue from dart-archive/jnigen Nov 17, 2023
@HosseinYousefi HosseinYousefi moved this to Backlog in JNIgen tracker Apr 11, 2024
@github-project-automation github-project-automation bot moved this from Backlog to Done in JNIgen tracker May 22, 2024
auto-submit bot pushed a commit that referenced this issue Oct 1, 2024
Bumps the github-actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [actions/setup-java](https://github.com/actions/setup-java).

Updates `actions/checkout` from 4.1.7 to 4.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/actions/checkout/releases">actions/checkout's releases</a>.</em></p>
<blockquote>
<h2>v4.2.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Add Ref and Commit outputs by <a href="https://github.com/lucacome"><code>@�lucacome</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependabot updates in <a href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a> &amp; <a href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/yasonk"><code>@�yasonk</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/1869">actions/checkout#1869</a></li>
<li><a href="https://github.com/lucacome"><code>@�lucacome</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v4.1.7...v4.2.0">https://github.com/actions/checkout/compare/v4.1.7...v4.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a href="https://github.com/lucacome"><code>@�lucacome</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a href="https://github.com/dependabot"><code>@�dependabot</code></a>- <a href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>, <a href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4 updates by <a href="https://github.com/dependabot"><code>@�dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a href="https://github.com/dependabot"><code>@�dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a href="https://github.com/orhantoy"><code>@�orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
<li>Pin actions/checkout's own workflows to a known, good, stable version. by <a href="https://github.com/jww3"><code>@�jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li>
</ul>
<h2>v4.1.6</h2>
<ul>
<li>Check platform to set archive extension appropriately by <a href="https://github.com/cory-miller"><code>@�cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li>
</ul>
<h2>v4.1.5</h2>
<ul>
<li>Update NPM dependencies by <a href="https://github.com/cory-miller"><code>@�cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li>
<li>Bump github/codeql-action from 2 to 3 by <a href="https://github.com/dependabot"><code>@�dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li>
<li>Bump actions/setup-node from 1 to 4 by <a href="https://github.com/dependabot"><code>@�dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li>
<li>Bump actions/upload-artifact from 2 to 4 by <a href="https://github.com/dependabot"><code>@�dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li>
<li>README: Suggest <code>user.email</code> to be <code>41898282+github-actions[bot]@users.noreply.github.com</code> by <a href="https://github.com/cory-miller"><code>@�cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1707">actions/checkout#1707</a></li>
</ul>
<h2>v4.1.4</h2>
<ul>
<li>Disable <code>extensions.worktreeConfig</code> when disabling <code>sparse-checkout</code> by <a href="https://github.com/jww3"><code>@�jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1692">actions/checkout#1692</a></li>
<li>Add dependabot config by <a href="https://github.com/cory-miller"><code>@�cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1688">actions/checkout#1688</a></li>
<li>Bump the minor-actions-dependencies group with 2 updates by <a href="https://github.com/dependabot"><code>@�dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1693">actions/checkout#1693</a></li>
<li>Bump word-wrap from 1.2.3 to 1.2.5 by <a href="https://github.com/dependabot"><code>@�dependabot</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1643">actions/checkout#1643</a></li>
</ul>
<h2>v4.1.3</h2>
<ul>
<li>Check git version before attempting to disable <code>sparse-checkout</code> by <a href="https://github.com/jww3"><code>@�jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1656">actions/checkout#1656</a></li>
<li>Add SSH user parameter by <a href="https://github.com/cory-miller"><code>@�cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1685">actions/checkout#1685</a></li>
<li>Update <code>actions/checkout</code> version in <code>update-main-version.yml</code> by <a href="https://github.com/jww3"><code>@�jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1650">actions/checkout#1650</a></li>
</ul>
<h2>v4.1.2</h2>
<ul>
<li>Fix: Disable sparse checkout whenever <code>sparse-checkout</code> option is not present <a href="https://github.com/dscho"><code>@�dscho</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1598">actions/checkout#1598</a></li>
</ul>
<h2>v4.1.1</h2>
<ul>
<li>Correct link to GitHub Docs by <a href="https://github.com/peterbe"><code>@�peterbe</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1511">actions/checkout#1511</a></li>
<li>Link to release page from what's new section by <a href="https://github.com/cory-miller"><code>@�cory-miller</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1514">actions/checkout#1514</a></li>
</ul>
<h2>v4.1.0</h2>
<ul>
<li><a href="https://redirect.github.com/actions/checkout/pull/1396">Add support for partial checkout filters</a></li>
</ul>
<h2>v4.0.0</h2>
<ul>
<li><a href="https://redirect.github.com/actions/checkout/pull/1067">Support fetching without the --progress option</a></li>
<li><a href="https://redirect.github.com/actions/checkout/pull/1436">Update to node20</a></li>
</ul>
<h2>v3.6.0</h2>
<ul>
<li><a href="https://redirect.github.com/actions/checkout/pull/1377">Fix: Mark test scripts with Bash'isms to be run via Bash</a></li>
</ul>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/actions/checkout/commit/d632683dd7b4114ad314bca15554477dd762a938"><code>d632683</code></a> Prepare 4.2.0 release (<a href="https://redirect.github.com/actions/checkout/issues/1878">#1878</a>)</li>
<li><a href="https://github.com/actions/checkout/commit/6d193bf28034eafb982f37bd894289fe649468fc"><code>6d193bf</code></a> Bump braces from 3.0.2 to 3.0.3 (<a href="https://redirect.github.com/actions/checkout/issues/1777">#1777</a>)</li>
<li><a href="https://github.com/actions/checkout/commit/db0cee9a514becbbd4a101a5fbbbf47865ee316c"><code>db0cee9</code></a> Bump the minor-npm-dependencies group across 1 directory with 4 updates (<a href="https://redirect.github.com/actions/checkout/issues/1872">#1872</a>)</li>
<li><a href="https://github.com/actions/checkout/commit/b6849436894e144dbce29d7d7fda2ae3bf9d8365"><code>b684943</code></a> Add Ref and Commit outputs (<a href="https://redirect.github.com/actions/checkout/issues/1180">#1180</a>)</li>
<li><a href="https://github.com/actions/checkout/commit/2d7d9f7ff5b310f983d059b68785b3c74d8b8edd"><code>2d7d9f7</code></a> Provide explanation for where user email came from (<a href="https://redirect.github.com/actions/checkout/issues/1869">#1869</a>)</li>
<li><a href="https://github.com/actions/checkout/commit/9a9194f87191a7e9055e3e9b95b8cfb13023bb08"><code>9a9194f</code></a> Bump docker/build-push-action from 5.3.0 to 6.5.0 (<a href="https://redirect.github.com/actions/checkout/issues/1832">#1832</a>)</li>
<li><a href="https://github.com/actions/checkout/commit/dd960bd3c3f080561a1810e32349ac211ecec7d4"><code>dd960bd</code></a> Bump docker/login-action in the minor-actions-dependencies group (<a href="https://redirect.github.com/actions/checkout/issues/1831">#1831</a>)</li>
<li>See full diff in <a href="https://github.com/actions/checkout/compare/692973e3d937129bcbf40652eb9f2f61becf3332...d632683dd7b4114ad314bca15554477dd762a938">compare view</a></li>
</ul>
</details>
<br />

Updates `actions/setup-java` from 4.2.2 to 4.4.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/actions/setup-java/releases">actions/setup-java's releases</a>.</em></p>
<blockquote>
<h2>v4.4.0</h2>
<h2>What's Changed</h2>
<p><strong>Add-ons :</strong></p>
<ul>
<li>Add support for Oracle GraalVM by <a href="https://github.com/fniephaus"><code>@�fniephaus</code></a> in <a href="https://redirect.github.com/actions/setup-java/pull/501">actions/setup-java#501</a></li>
</ul>
<pre><code>steps:
 - name: Checkout
   uses: actions/checkout@v4
 - name: Setup-java
   uses: actions/setup-java@v4
   with:
     distribution: 'graalvm'
     java-version: '21'
</code></pre>
<ul>
<li>Add workflow file for publishing releases to immutable action package by <a href="https://github.com/Jcambass"><code>@�Jcambass</code></a> in <a href="https://redirect.github.com/actions/setup-java/pull/684">actions/setup-java#684</a></li>
</ul>
<p><strong>Bug fixes :</strong></p>
<ul>
<li>Add architecture to cache key by <a href="https://github.com/Zxilly"><code>@�Zxilly</code></a> in <a href="https://redirect.github.com/actions/setup-java/pull/664">actions/setup-java#664</a>
This addresses issues with caching by adding the architecture (arch) to the cache key, ensuring that cache keys are accurate to prevent conflicts.
Note: This change may break previous cache keys as they will no longer be compatible with the new format.</li>
<li>Resolve check failures by <a href="https://github.com/aparnajyothi-y"><code>@�aparnajyothi-y</code></a> in <a href="https://redirect.github.com/actions/setup-java/pull/687">actions/setup-java#687</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Jcambass"><code>@�Jcambass</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-java/pull/684">actions/setup-java#684</a></li>
<li><a href="https://github.com/Zxilly"><code>@�Zxilly</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-java/pull/664">actions/setup-java#664</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/actions/setup-java/compare/v4...v4.4.0">https://github.com/actions/setup-java/compare/v4...v4.4.0</a></p>
<h2>v4.3.0</h2>
<p>What's Changed</p>
<ul>
<li>Add support for SapMachine JDK/JRE by <a href="https://github.com/Shegox"><code>@�Shegox</code></a> in <a href="https://redirect.github.com/actions/setup-java/issues/614">#614</a></li>
</ul>
<pre lang="yaml"><code>steps:
 - name: Checkout
   uses: actions/checkout@v4
 - name: Setup-java
   uses: actions/setup-java@v4
   with:
     distribution: 'sapmachine'
     java-version: '21'
</code></pre>
<p>Bug fixes :</p>
<ul>
<li>
<pre><code>Fix typos on Corretto by @johnshajiang in [#666](actions/setup-java#666)
</code></pre>
</li>
<li>
<pre><code>IBM Semeru Enhancement on arm64 by @mahabaleshwars in [#677](actions/setup-java#677) 
</code></pre>
</li>
<li>
<pre><code>Resolve Basic Validation Check Failures by @aparnajyothi-y� in [#682](actions/setup-java#682) 
</code></pre>
</li>
</ul>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/actions/setup-java/commit/b36c23c0d998641eff861008f374ee103c25ac73"><code>b36c23c</code></a> check-dist-failure-fix (<a href="https://redirect.github.com/actions/setup-java/issues/687">#687</a>)</li>
<li><a href="https://github.com/actions/setup-java/commit/40b9536ce5efadffec365e30f26f62a3640d2548"><code>40b9536</code></a> fix: add arch to cache key (<a href="https://redirect.github.com/actions/setup-java/issues/664">#664</a>)</li>
<li><a href="https://github.com/actions/setup-java/commit/0a40ce6f61952eeee640a8940ea8050407c06cb5"><code>0a40ce6</code></a> Add support for Oracle GraalVM (<a href="https://redirect.github.com/actions/setup-java/issues/501">#501</a>)</li>
<li><a href="https://github.com/actions/setup-java/commit/bcfbca5b713b77435aded8de683c7ee5e79f63cb"><code>bcfbca5</code></a> Merge pull request <a href="https://redirect.github.com/actions/setup-java/issues/684">#684</a> from actions/Jcambass-patch-1</li>
<li><a href="https://github.com/actions/setup-java/commit/78eae7945c050692110fb75199251cfe322201d4"><code>78eae79</code></a> Add workflow file for publishing releases to immutable action package</li>
<li><a href="https://github.com/actions/setup-java/commit/2dfa2011c5b2a0f1489bf9e433881c92c1631f88"><code>2dfa201</code></a> basic validation failure fix (<a href="https://redirect.github.com/actions/setup-java/issues/682">#682</a>)</li>
<li><a href="https://github.com/actions/setup-java/commit/7467385c615a13cecd14d5768e738332968d0792"><code>7467385</code></a> feat: add support for SapMachine JDK/JRE (<a href="https://redirect.github.com/actions/setup-java/issues/614">#614</a>)</li>
<li><a href="https://github.com/actions/setup-java/commit/8e04ddff28554375a9a1096c888a2ef2c9803cd7"><code>8e04ddf</code></a> Update Error Messages and Fix Architecture Detection for IBM Semeru (<a href="https://redirect.github.com/actions/setup-java/issues/677">#677</a>)</li>
<li><a href="https://github.com/actions/setup-java/commit/67fbd726daaf08212a7b021c1c4d117f94a81dd3"><code>67fbd72</code></a> Fix typos on Corretto (<a href="https://redirect.github.com/actions/setup-java/issues/665">#665</a>) (<a href="https://redirect.github.com/actions/setup-java/issues/666">#666</a>)</li>
<li>See full diff in <a href="https://github.com/actions/setup-java/compare/6a0805fcefea3d4657a47ac4c165951e33482018...b36c23c0d998641eff861008f374ee103c25ac73">compare view</a></li>
</ul>
</details>
<br />

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions

</details>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lang-java Related to Java support package:jni package:jnigen type-enhancement A request for a change that isn't a bug
Projects
Status: Done
Development

No branches or pull requests

3 participants