Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Onboarding new maven snapshots publishing to s3 ([#19619](https://github.com/opensearch-project/OpenSearch/pull/19619))
- Remove MultiCollectorWrapper and use MultiCollector in Lucene instead ([#19595](https://github.com/opensearch-project/OpenSearch/pull/19595))
- Change implementation for `percentiles` aggregation for latency improvement ([#19648](https://github.com/opensearch-project/OpenSearch/pull/19648))
- Wrap checked exceptions in painless.DefBootstrap to support JDK-25 ([#19706](https://github.com/opensearch-project/OpenSearch/pull/19706))
- Refactor the ThreadPoolStats.Stats class to use the Builder pattern instead of constructors ([#19306](https://github.com/opensearch-project/OpenSearch/pull/19306))

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ private DefBootstrap() {} // no instance!
*/
public static final int OPERATOR_EXPLICIT_CAST = 1 << 2;

/**
* ClassValue.getFromHashMap will wrap checked exceptions with Errors. To get
* around that we wrap any checked exceptions with this RuntimeException and
* unwrap them later.
*/
static final class WrappedCheckedException extends RuntimeException {
private WrappedCheckedException(Exception cause) {
super(cause);
}
}

/**
* CallSite that implements the polymorphic inlining cache (PIC).
*/
Expand Down Expand Up @@ -204,7 +215,10 @@ protected MethodHandle computeValue(Class<?> receiverType) {
try {
return lookup(flavor, name, receiverType).asType(type);
} catch (Throwable t) {
Def.rethrow(t);
switch (t) {
case Exception e -> throw new WrappedCheckedException(e);
default -> Def.rethrow(t);
}
throw new AssertionError();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,18 @@ public interface PainlessScript {
/**
* Adds stack trace and other useful information to exceptions thrown
* from a Painless script.
* @param t The throwable to build an exception around.
* @param originalThrowable The throwable to build an exception around.
* @return The generated ScriptException.
*/
default ScriptException convertToScriptException(Throwable t, Map<String, List<String>> extraMetadata) {
default ScriptException convertToScriptException(Throwable originalThrowable, Map<String, List<String>> extraMetadata) {
final Throwable unwrapped = switch (originalThrowable) {
case DefBootstrap.WrappedCheckedException w -> w.getCause();
default -> originalThrowable;
};
// create a script stack: this is just the script portion
List<String> scriptStack = new ArrayList<>();
ScriptException.Position pos = null;
for (StackTraceElement element : t.getStackTrace()) {
for (StackTraceElement element : unwrapped.getStackTrace()) {
if (WriterConstants.CLASS_NAME.equals(element.getClassName())) {
// found the script portion
int originalOffset = element.getLineNumber();
Expand Down Expand Up @@ -106,7 +110,14 @@ default ScriptException convertToScriptException(Throwable t, Map<String, List<S
scriptStack.add(element.toString());
}
}
ScriptException scriptException = new ScriptException("runtime error", t, scriptStack, getName(), PainlessScriptEngine.NAME, pos);
ScriptException scriptException = new ScriptException(
"runtime error",
unwrapped,
scriptStack,
getName(),
PainlessScriptEngine.NAME,
pos
);
for (Map.Entry<String, List<String>> entry : extraMetadata.entrySet()) {
scriptException.addMetadata(entry.getKey(), entry.getValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import java.util.Collections;
import java.util.HashMap;

import static org.hamcrest.Matchers.instanceOf;

public class DefBootstrapTests extends OpenSearchTestCase {
private final PainlessLookup painlessLookup = PainlessLookupBuilder.buildFromAllowlists(Allowlist.BASE_ALLOWLISTS);

Expand Down Expand Up @@ -157,9 +159,11 @@ public void testMegamorphic() throws Throwable {
map.put("a", "b");
assertEquals(2, (int) handle.invokeExact((Object) map));

final IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> {
final DefBootstrap.WrappedCheckedException wrapped = expectThrows(DefBootstrap.WrappedCheckedException.class, () -> {
Integer.toString((int) handle.invokeExact(new Object()));
});
assertThat(wrapped.getCause(), instanceOf(IllegalArgumentException.class));
final IllegalArgumentException iae = (IllegalArgumentException) wrapped.getCause();
assertEquals("dynamic method [java.lang.Object, size/0] not found", iae.getMessage());
assertTrue("Does not fail inside ClassValue.computeValue()", Arrays.stream(iae.getStackTrace()).anyMatch(e -> {
return e.getMethodName().equals("computeValue") && e.getClassName().startsWith("org.opensearch.painless.DefBootstrap$PIC$");
Expand Down
Loading