Use reflection to access DatatypeConverter
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
parent
bfa5fe1598
commit
8a6776731a
@ -40,6 +40,7 @@ import java.net.URLStreamHandler;
|
|||||||
import java.net.URLStreamHandlerFactory;
|
import java.net.URLStreamHandlerFactory;
|
||||||
|
|
||||||
import org.prismlauncher.fix.Fix;
|
import org.prismlauncher.fix.Fix;
|
||||||
|
import org.prismlauncher.utils.Base64;
|
||||||
import org.prismlauncher.utils.Parameters;
|
import org.prismlauncher.utils.Parameters;
|
||||||
import org.prismlauncher.utils.logging.Log;
|
import org.prismlauncher.utils.logging.Log;
|
||||||
import org.prismlauncher.utils.url.UrlUtils;
|
import org.prismlauncher.utils.url.UrlUtils;
|
||||||
@ -59,7 +60,7 @@ public final class SkinFix implements Fix, URLStreamHandlerFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(Parameters params) {
|
public boolean isApplicable(Parameters params) {
|
||||||
if (!UrlUtils.isSupported()) {
|
if (!UrlUtils.isSupported() || !Base64.isSupported()) {
|
||||||
Log.warning("Cannot access the necessary Java internals for skin fix");
|
Log.warning("Cannot access the necessary Java internals for skin fix");
|
||||||
Log.warning("Try adding '--add-opens java.base/java.net=ALL-UNNAMED' to your Java arguments");
|
Log.warning("Try adding '--add-opens java.base/java.net=ALL-UNNAMED' to your Java arguments");
|
||||||
Log.warning("Alternatively, turning off legacy skin fix in Settings > Miscellaneous will silence the warnings");
|
Log.warning("Alternatively, turning off legacy skin fix in Settings > Miscellaneous will silence the warnings");
|
||||||
|
@ -35,25 +35,60 @@
|
|||||||
|
|
||||||
package org.prismlauncher.utils;
|
package org.prismlauncher.utils;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import javax.xml.bind.DatatypeConverter;
|
import org.prismlauncher.utils.logging.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses Base64 with Java 8 or later, otherwise DatatypeConverter. In the latter
|
||||||
|
* case, reflection is used to allow using newer compilers.
|
||||||
|
*/
|
||||||
public final class Base64 {
|
public final class Base64 {
|
||||||
|
|
||||||
private static boolean legacy;
|
private static boolean supported = true;
|
||||||
|
private static MethodHandle legacy;
|
||||||
|
|
||||||
public static byte[] decode(String input) {
|
static {
|
||||||
if (!legacy) {
|
try {
|
||||||
|
Class.forName("java.util.Base64");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
try {
|
try {
|
||||||
return java.util.Base64.getDecoder().decode(input.getBytes(StandardCharsets.UTF_8));
|
Class<?> datatypeConverter = Class.forName("javax.xml.bind.DatatypeConverter");
|
||||||
} catch (NoClassDefFoundError e) {
|
legacy = MethodHandles.lookup().findStatic(datatypeConverter, "parseBase64Binary",
|
||||||
legacy = true;
|
MethodType.methodType(byte[].class, String.class));
|
||||||
|
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e1) {
|
||||||
|
Log.error("Base64 not supported", e1);
|
||||||
|
supported = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// support for Java versions < 8
|
/**
|
||||||
return DatatypeConverter.parseBase64Binary(input);
|
* Determines whether base64 is supported.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if base64 can be parsed
|
||||||
|
*/
|
||||||
|
public static boolean isSupported() {
|
||||||
|
return supported;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] decode(String input) {
|
||||||
|
if (!isSupported())
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
|
||||||
|
if (legacy == null)
|
||||||
|
return java.util.Base64.getDecoder().decode(input.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
try {
|
||||||
|
return (byte[]) legacy.invokeExact(input);
|
||||||
|
} catch (Error | RuntimeException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -82,10 +82,16 @@ public final class UrlUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static URLConnection openHttpConnection(URL url, Proxy proxy) throws IOException {
|
public static URLConnection openHttpConnection(URL url, Proxy proxy) throws IOException {
|
||||||
|
if (http == null)
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
|
||||||
return openConnection(http, url, proxy);
|
return openConnection(http, url, proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static URLConnection openConnection(URLStreamHandler handler, URL url, Proxy proxy) throws IOException {
|
public static URLConnection openConnection(URLStreamHandler handler, URL url, Proxy proxy) throws IOException {
|
||||||
|
if (openConnection == null)
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return (URLConnection) openConnection.invokeExact(handler, url, proxy);
|
return (URLConnection) openConnection.invokeExact(handler, url, proxy);
|
||||||
} catch (IOException | Error | RuntimeException e) {
|
} catch (IOException | Error | RuntimeException e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user