Prevent reflection errors crashing the game

.getMethods() may throw if a method references classes which don't exist
(such as client-only classes on a server). This is an Error, and so is
unchecked - hence us not handling it before.

Fixes #645
This commit is contained in:
Jonathan Coates 2021-01-06 18:21:03 +00:00
parent 2c9f51db89
commit dd6f97622e
1 changed files with 20 additions and 2 deletions

View File

@ -56,11 +56,11 @@ public final class Generator<T>
private final LoadingCache<Class<?>, List<NamedMethod<T>>> classCache = CacheBuilder
.newBuilder()
.build( CacheLoader.from( this::build ) );
.build( CacheLoader.from( catching( this::build, Collections.emptyList() ) ) );
private final LoadingCache<Method, Optional<T>> methodCache = CacheBuilder
.newBuilder()
.build( CacheLoader.from( this::build ) );
.build( CacheLoader.from( catching( this::build, Optional.empty() ) ) );
Generator( Class<T> base, List<Class<?>> context, Function<T, T> wrap )
{
@ -358,4 +358,22 @@ private Boolean loadArg( MethodVisitor mw, Class<?> target, Method method, java.
arg.getName(), method.getDeclaringClass().getName(), method.getName() );
return null;
}
@SuppressWarnings( "Guava" )
private static <T, U> com.google.common.base.Function<T, U> catching( Function<T, U> function, U def )
{
return x -> {
try
{
return function.apply( x );
}
catch( Exception | LinkageError e )
{
// LinkageError due to possible codegen bugs and NoClassDefFoundError. The latter occurs when fetching
// methods on a class which references non-existent (i.e. client-only) types.
ComputerCraft.log.error( "Error generating @LuaFunctions", e );
return def;
}
};
}
}