web-dev-qa-db-ja.com

IndexOutOfBoundsExceptionによってスローされたUndeclaredThrowableException

_List<WebElement>_にデコレータパターンを使用しています。この装飾の一部では、プロキシを使用する必要があります。

範囲外のインデックスを使用してget(index)を呼び出すと、IndexOutOfBounds例外がスローされ、プロキシによってキャッチされ、UndeclaredThrowableExceptionでラップされます。

私の理解では、チェックされた例外の場合はのみこれを行う必要があります。 IndexOutOfBoundsunchecked例外ですが、なぜラップされるのですか?

invoke関数に_throws IndexOutOfBounds_を追加しても、ラップされます。

これが私のコードです:

_@SuppressWarnings("unchecked")
public WebElementList findWebElementList(final By by){
    return new WebElementList(
            (List<WebElement>) Proxy.newProxyInstance(this.getClass().getClassLoader(),
                    new Class<?>[] { List.class }, new InvocationHandler() {
        // Lazy initialized instance of WebElement
        private List<WebElement> webElements;

        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            if (webElements == null) {
                webElements = findElements(by);
            }
            return method.invoke(webElements, args);
        }
    }), driver);
}
_

これが私のスタックトレースの一部です:

_Java.lang.reflect.UndeclaredThrowableException
at com.Sun.proxy.$Proxy30.get(Unknown Source)
at org.lds.ldsp.enhancements.WebElementList.get(WebElementList.Java:29)
...
Caused by: Java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at Java.util.ArrayList.rangeCheck(ArrayList.Java:604)
at Java.util.ArrayList.get(ArrayList.Java:382)
... 41 more
_
8
Nathan Merrill

ヴィックチャンは正しいです。呼び出しをtry-catchでラップし、内部例外を再スローする必要があります。

try {
  return method.invoke(webElements, args);
} catch (InvocationTargetException ite) {
  throw ite.getCause();
}

その理由は、「Method.invoke」がメソッドのコードでスローされた例外をInvocationTargetExceptionでラップするためです。

Java.lang.reflect.Method:

スロー:
.。
InvocationTargetException-基になるメソッドが例外をスローした場合。

Java.lang.reflect.InvocationTargetException:

InvocationTargetExceptionは、呼び出されたメソッドまたはコンストラクターによってスローされた例外をラップするチェック済みの例外です。

プロキシオブジェクトのクラスには、その「スロー」の中で宣言されたInvocationTargetExceptionがありません。それはUndeclaredThrowableExceptionにつながります。

9
Zorg

コメントするのに十分な評判がありません。あなたの問題は これ に非常に似ているようです

そこで解決策を見て、それが機能するかどうかを確認できます。

つまり、method.invoketry{}catch例外、そしてthrowに再度ラップする必要があります。

3
Vic Jang