package net.md_5.bungee.jni; import com.google.common.io.ByteStreams; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import net.md_5.bungee.jni.cipher.BungeeCipher; public final class NativeCode<T> { private final String name; private final Class<T> javaImpl; private final Class<T> nativeImpl; // private boolean loaded; public NativeCode(String name, Class<T> javaImpl, Class<T> nativeImpl) { this.name = name; this.javaImpl = javaImpl; this.nativeImpl = nativeImpl; } public T newInstance() { try { return ( loaded ) ? nativeImpl.newInstance() : javaImpl.newInstance(); } catch ( IllegalAccessException | InstantiationException ex ) { throw new RuntimeException( "Error getting instance", ex ); } } public boolean load() { if ( !loaded && isSupported() ) { String fullName = "bungeecord-" + name; try { System.loadLibrary( fullName ); loaded = true; } catch ( Throwable t ) { } if ( !loaded ) { try ( InputStream soFile = BungeeCipher.class.getClassLoader().getResourceAsStream( name + ".so" ) ) { // Else we will create and copy it to a temp file File temp = File.createTempFile( fullName, ".so" ); // Don't leave cruft on filesystem temp.deleteOnExit(); try ( OutputStream outputStream = new FileOutputStream( temp ) ) { ByteStreams.copy( soFile, outputStream ); } System.load( temp.getPath() ); loaded = true; } catch ( IOException ex ) { // Can't write to tmp? } catch ( UnsatisfiedLinkError ex ) { System.out.println( "Could not load native library: " + ex.getMessage() ); } } } return loaded; } public static boolean isSupported() { return "Linux".equals( System.getProperty( "os.name" ) ) && "amd64".equals( System.getProperty( "os.arch" ) ); } }