Skip to content

Commit

Permalink
Do not include custom exception messages when using reflection. Use r…
Browse files Browse the repository at this point in the history
…eflection when call sites are call site sensitive.
  • Loading branch information
raphw committed Aug 5, 2021
1 parent ca9d3ab commit eb4874b
Show file tree
Hide file tree
Showing 8 changed files with 346 additions and 228 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -299,9 +299,9 @@ public void clean(Reference<? extends ClassLoader> reference) {
try {
clean.invoke(STATIC_METHOD, reference);
} catch (IllegalAccessException exception) {
throw new IllegalStateException("Cannot access: " + clean, exception);
throw new IllegalStateException(exception);
} catch (InvocationTargetException exception) {
throw new IllegalStateException("Cannot invoke: " + clean, exception.getTargetException());
throw new IllegalStateException(exception.getTargetException());
}
}

Expand All @@ -316,9 +316,9 @@ public void register(String name,
try {
register.invoke(STATIC_METHOD, name, classLoader, referenceQueue, identification, loadedTypeInitializer);
} catch (IllegalAccessException exception) {
throw new IllegalStateException("Cannot access: " + register, exception);
throw new IllegalStateException(exception);
} catch (InvocationTargetException exception) {
throw new IllegalStateException("Cannot invoke: " + register, exception.getTargetException());
throw new IllegalStateException(exception.getTargetException());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -547,9 +547,9 @@ public Object getClassLoadingLock(ByteArrayClassLoader classLoader, String name)
try {
return method.invoke(classLoader, name);
} catch (IllegalAccessException exception) {
throw new IllegalStateException("Cannot access class loading lock for " + name + " on " + classLoader, exception);
throw new IllegalStateException(exception);
} catch (InvocationTargetException exception) {
throw new IllegalStateException("Error when getting " + name + " on " + classLoader, exception.getTargetException());
throw new IllegalStateException(exception.getTargetException());
}
}

Expand Down Expand Up @@ -615,9 +615,9 @@ public Object getClassLoadingLock(ByteArrayClassLoader classLoader, String name)
try {
return invokeWithArguments.invoke(bindTo.invoke(methodHandle, classLoader), (Object) new Object[]{name});
} catch (IllegalAccessException exception) {
throw new IllegalStateException("Cannot access class loading lock for " + name + " on " + classLoader, exception);
throw new IllegalStateException(exception);
} catch (InvocationTargetException exception) {
throw new IllegalStateException("Error when getting " + name + " on " + classLoader, exception.getTargetException());
throw new IllegalStateException(exception.getTargetException());
}
}
}
Expand Down Expand Up @@ -764,9 +764,9 @@ public Package apply(ByteArrayClassLoader classLoader, String name) {
try {
return (Package) getDefinedPackage.invoke(classLoader, name);
} catch (IllegalAccessException exception) {
throw new IllegalStateException("Cannot access " + getDefinedPackage, exception);
throw new IllegalStateException(exception);
} catch (InvocationTargetException exception) {
throw new IllegalStateException("Cannot invoke " + getDefinedPackage, exception.getTargetException());
throw new IllegalStateException(exception.getTargetException());
}
}
}
Expand Down

Large diffs are not rendered by default.

250 changes: 157 additions & 93 deletions byte-buddy-dep/src/main/java/net/bytebuddy/utility/FileSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,25 @@
*/
package net.bytebuddy.utility;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import net.bytebuddy.build.AccessControllerPlugin;
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
import net.bytebuddy.utility.dispatcher.JavaDispatcher;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.PrivilegedAction;

/**
* A dispatcher to interact with the file system. If NIO2 is available, the API is used. Otherwise, byte streams are used.
*/
public enum FileSystem {
public abstract class FileSystem {

/**
* The singleton instance.
* The file system accessor to use.
*/
INSTANCE;

/**
* A dispatcher to resolve a {@link File} to a {@code java.nio.file.Path}.
*/
private static final Dispatcher DISPATCHER = doPrivileged(JavaDispatcher.of(Dispatcher.class));

/**
* A dispatcher to interact with {@code java.nio.file.Files}.
*/
private static final Files FILES = doPrivileged(JavaDispatcher.of(Files.class));

/**
* A dispatcher to interact with {@code java.nio.file.StandardCopyOption}.
*/
private static final StandardCopyOption STANDARD_COPY_OPTION = doPrivileged(JavaDispatcher.of(StandardCopyOption.class));
public static final FileSystem INSTANCE = doPrivileged(CreationAction.INSTANCE);

/**
* A proxy for {@code java.security.AccessController#doPrivileged} that is activated if available.
Expand All @@ -65,9 +54,51 @@ private static <T> T doPrivileged(PrivilegedAction<T> action) {
* @param target The target file.
* @throws IOException If an I/O exception occurs.
*/
public void copy(File source, File target) throws IOException {
Object[] option = STANDARD_COPY_OPTION.toArray(1);
if (option.length == 0) {
public abstract void copy(File source, File target) throws IOException;

/**
* Moves a file.
*
* @param source The source file.
* @param target The target file.
* @throws IOException If an I/O exception occurs.
*/
public abstract void move(File source, File target) throws IOException;

/**
* An action to create a dispatcher for a {@link FileSystem}.
*/
protected enum CreationAction implements PrivilegedAction<FileSystem> {

/**
* The singleton instance.
*/
INSTANCE;

/**
* {@inheritDoc}
*/
@SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "Exception should not be rethrown but trigger fallback")
public FileSystem run() {
try {
Class<?> files = Class.forName("java.nio.file.Files"),
path = Class.forName("java.nio.file.Path"),
copyOption = Class.forName("[Ljava.nio.file.CopyOption;");
return new ForNio2CapableVm(files.getMethod("copy", path, path, copyOption), files.getMethod("move", path, path, copyOption));
} catch (Exception ignored) {
return new ForLegacyVm();
}
}
}

/**
* A file system representation for a VM that does not support NIO2.
*/
@HashCodeAndEqualsPlugin.Enhance
protected static class ForLegacyVm extends FileSystem {

@Override
public void copy(File source, File target) throws IOException {
InputStream inputStream = new FileInputStream(source);
try {
OutputStream outputStream = new FileOutputStream(target);
Expand All @@ -83,22 +114,10 @@ public void copy(File source, File target) throws IOException {
} finally {
inputStream.close();
}
} else {
option[0] = STANDARD_COPY_OPTION.valueOf("REPLACE_EXISTING");
FILES.copy(DISPATCHER.toPath(source), DISPATCHER.toPath(target), option);
}
}

/**
* Moves a file.
*
* @param source The source file.
* @param target The target file.
* @throws IOException If an I/O exception occurs.
*/
public void move(File source, File target) throws IOException {
Object[] option = STANDARD_COPY_OPTION.toArray(1);
if (option.length == 0) {
@Override
public void move(File source, File target) throws IOException {
InputStream inputStream = new FileInputStream(source);
try {
OutputStream outputStream = new FileOutputStream(target);
Expand All @@ -117,86 +136,131 @@ public void move(File source, File target) throws IOException {
if (!source.delete()) {
source.deleteOnExit();
}
} else {
option[0] = STANDARD_COPY_OPTION.valueOf("REPLACE_EXISTING");
FILES.move(DISPATCHER.toPath(source), DISPATCHER.toPath(target), option);
}
}

/**
* A dispatcher to resolve a {@link File} to a {@code java.nio.file.Path}.
* A file system representation for a VM that does support NIO2.
*/
@JavaDispatcher.Proxied("java.io.File")
protected interface Dispatcher {
@HashCodeAndEqualsPlugin.Enhance
protected static class ForNio2CapableVm extends FileSystem {

/**
* Resolves a {@link File} to a {@code java.nio.file.Path}.
*
* @param value The file to convert.
* @return The transformed {@code java.nio.file.Path}.
* @throws IOException If an I/O exception occurs.
* Indicates a static method invocation.
*/
Object toPath(File value) throws IOException;
}
private static final Object STATIC_MEMBER = null;

/**
* A dispatcher to interact with {@code java.nio.file.Files}.
*/
@JavaDispatcher.Proxied("java.nio.file.Files")
protected interface Files {
/**
* A dispatcher to resolve a {@link File} to a {@code java.nio.file.Path}.
*/
private static final Dispatcher DISPATCHER = doPrivileged(JavaDispatcher.of(Dispatcher.class));

/**
* Copies a {@code java.nio.file.Path} to a different location.
*
* @param source The source {@code java.nio.file.Path}.
* @param target The target {@code java.nio.file.Path}.
* @param option The copy options.
* @return The targeted {@code java.nio.file.Path}.
* @throws IOException If an I/O exception occurs.
* A dispatcher to interact with {@code java.nio.file.StandardCopyOption}.
*/
@JavaDispatcher.IsStatic
Object copy(@JavaDispatcher.Proxied("java.nio.file.Path") Object source,
@JavaDispatcher.Proxied("java.nio.file.Path") Object target,
@JavaDispatcher.Proxied("java.nio.file.CopyOption") Object[] option) throws IOException;
private static final StandardCopyOption STANDARD_COPY_OPTION = doPrivileged(JavaDispatcher.of(StandardCopyOption.class));

/**
* Moves a {@code java.nio.file.Path} to a different location.
*
* @param source The source {@code java.nio.file.Path}.
* @param target The target {@code java.nio.file.Path}.
* @param option The copy options.
* @return The targeted {@code java.nio.file.Path}.
* @throws IOException If an I/O exception occurs.
* The {@code java.nio.file.Files#copy} method.
*/
@JavaDispatcher.IsStatic
Object move(@JavaDispatcher.Proxied("java.nio.file.Path") Object source,
@JavaDispatcher.Proxied("java.nio.file.Path") Object target,
@JavaDispatcher.Proxied("java.nio.file.CopyOption") Object[] option) throws IOException;
}
private final Method copy;

/**
* A dispatcher to interact with {@code java.nio.file.StandardCopyOption}.
*/
@JavaDispatcher.Proxied("java.nio.file.StandardCopyOption")
protected interface StandardCopyOption {
/**
* The {@code java.nio.file.Files#move} method.
*/
private final Method move;

/**
* Creates an array of type {@code java.nio.file.StandardCopyOption}.
* Creates a new NIO2-capable file system dispatcher.
*
* @param size The array's size.
* @return An array of type {@code java.nio.file.StandardCopyOption}.
* @param copy The {@code java.nio.file.Files#copy} method.
* @param move The {@code java.nio.file.Files#move} method.
*/
protected ForNio2CapableVm(Method copy, Method move) {
this.copy = copy;
this.move = move;
}

@Override
public void copy(File source, File target) throws IOException {
Object[] option = STANDARD_COPY_OPTION.toArray(1);
option[0] = STANDARD_COPY_OPTION.valueOf("REPLACE_EXISTING");
try {
copy.invoke(STATIC_MEMBER, DISPATCHER.toPath(source), DISPATCHER.toPath(target), option);
} catch (IllegalAccessException exception) {
throw new IllegalStateException(exception);
} catch (InvocationTargetException exception) {
Throwable cause = exception.getTargetException();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof IOException) {
throw (IOException) cause;
} else {
throw new IllegalStateException(cause);
}
}
}

@Override
public void move(File source, File target) throws IOException {
Object[] option = STANDARD_COPY_OPTION.toArray(1);
option[0] = STANDARD_COPY_OPTION.valueOf("REPLACE_EXISTING");
try {
move.invoke(STATIC_MEMBER, DISPATCHER.toPath(source), DISPATCHER.toPath(target), option);
} catch (IllegalAccessException exception) {
throw new IllegalStateException(exception);
} catch (InvocationTargetException exception) {
Throwable cause = exception.getTargetException();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof IOException) {
throw (IOException) cause;
} else {
throw new IllegalStateException(cause);
}
}

}

/**
* A dispatcher to resolve a {@link File} to a {@code java.nio.file.Path}.
*/
@JavaDispatcher.Defaults
@JavaDispatcher.Container
Object[] toArray(int size);
@JavaDispatcher.Proxied("java.io.File")
protected interface Dispatcher {

/**
* Resolves a {@link File} to a {@code java.nio.file.Path}.
*
* @param value The file to convert.
* @return The transformed {@code java.nio.file.Path}.
* @throws IOException If an I/O exception occurs.
*/
Object toPath(File value) throws IOException;
}

/**
* Resolve an enumeration for {@code java.nio.file.StandardCopyOption}.
*
* @param name The enumeration name.
* @return The enumeration value.
* A dispatcher to interact with {@code java.nio.file.StandardCopyOption}.
*/
@JavaDispatcher.IsStatic
Object valueOf(String name);
@JavaDispatcher.Proxied("java.nio.file.StandardCopyOption")
protected interface StandardCopyOption {

/**
* Creates an array of type {@code java.nio.file.StandardCopyOption}.
*
* @param size The array's size.
* @return An array of type {@code java.nio.file.StandardCopyOption}.
*/
@JavaDispatcher.Container
Object[] toArray(int size);

/**
* Resolve an enumeration for {@code java.nio.file.StandardCopyOption}.
*
* @param name The enumeration name.
* @return The enumeration value.
*/
@JavaDispatcher.IsStatic
Object valueOf(String name);
}
}
}
Loading

0 comments on commit eb4874b

Please sign in to comment.