com.javonet.utils.BinariesUnloader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javonet-java-sdk Show documentation
Show all versions of javonet-java-sdk Show documentation
Javonet allows you to reference and use modules or packages written in (Java/Kotlin/Groovy/Clojure, C#/VB.NET, Ruby, Perl, Python, JavaScript/TypeScript) like they were created in your technology.
It works on Linux/Windows and MacOS for applications created in JVM, CLR/Netcore, Perl, Python, Ruby, NodeJS, C++ or GoLang and gives you unparalleled freedom and flexibility with native performance in building your mixed-technologies products.
Let it be accessing best AI or cryptography libraries, devices SDKs, legacy client modules, internal custom packages or anything from public repositories available on NPM, Nuget, PyPI, Maven/Gradle, RubyGems or GitHub. Get free from programming languages barriers today!
For more information check out our guides at https://www.javonet.com/guides/v2/
package com.javonet.utils;
import com.javonet.sdk.Javonet;
import java.io.*;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.Locale;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
public class BinariesUnloader {
public static void extractBinariesFromJar(RuntimeName runtimeName) {
if (isAndroid()) {
return;
}
try {
String dir = getJarPath(Javonet.class);
String destDir = System.getProperty("user.dir");
String binariesJvmPath = getBinariesSpecificPath(runtimeName.toString());
Path binariesPath = Paths.get(destDir, binariesJvmPath);
String currentVersion = getManifestProperty("Version");
if (!Files.isDirectory(Paths.get(binariesJvmPath)) || shouldUpdateBinaries(binariesPath, currentVersion)) {
if (dir.contains("!")) {
try (JarInputStream jarStream = getJarInputStream(dir)) {
extractFolderFromJar(jarStream, destDir, binariesJvmPath);
}
} else {
try (JarFile jarFile = new JarFile(dir)) {
extractFolderFromJar(jarFile, destDir, binariesJvmPath);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void extractNativeFromJar() {
if (isAndroid()) {
return;
}
try {
String dir = getJarPath(Javonet.class);
String destDir = System.getProperty("user.dir");
String binariesNativePath = getBinariesSpecificPath("Native");
Path binariesPath = Paths.get(destDir, binariesNativePath);
String currentVersion = getManifestProperty("Version");
if (!Files.isDirectory(Paths.get(binariesNativePath)) || shouldUpdateBinaries(binariesPath, currentVersion)) {
if (dir.contains("!")) {
try (JarInputStream jarStream = getJarInputStream(dir)) {
extractFolderFromJar(jarStream, destDir, binariesNativePath);
}
} else {
try (JarFile jarFile = new JarFile(dir)) {
extractFolderFromJar(jarFile, destDir, binariesNativePath);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static JarInputStream getJarInputStream(String jarFilePath) throws IOException {
URL jarUrl = new URL(jarFilePath);
JarURLConnection jarConnection = (JarURLConnection) jarUrl.openConnection();
return new JarInputStream(jarConnection.getInputStream());
}
private static void extractFolderFromJar(Object jar, String destDir, String folderPath) throws IOException {
if (jar instanceof JarFile) {
JarFile jarFile = (JarFile) jar;
Enumeration enumEntries = jarFile.entries();
while (enumEntries.hasMoreElements()) {
JarEntry file = enumEntries.nextElement();
extractFileFromJarEntry(jarFile, file, destDir, folderPath);
}
} else {
JarInputStream jarStream = (JarInputStream) jar;
JarEntry entry;
while ((entry = jarStream.getNextJarEntry()) != null) {
extractFileFromJarEntry(jarStream, entry, destDir, folderPath);
}
}
}
private static void extractFileFromJarEntry(Object jar, JarEntry file, String destDir, String folderPath) throws IOException {
File f = new File(destDir + File.separator + file.getName());
if (file.isDirectory() && file.getName().startsWith(folderPath)) { // if its a directory, create it
f.mkdirs();
return;
}
if (file.getName().startsWith(folderPath)) {
InputStream in;
if (jar instanceof JarFile) {
in = ((JarFile) jar).getInputStream(file); // get the input stream
} else {
in = (JarInputStream) jar; // directly use the JarInputStream
}
try (FileOutputStream out = new FileOutputStream(f)) {
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
}
}
private static String getBinariesSpecificPath(String runtimeLib) {
String osArch;
String binariesPath;
osArch = "X64";
if (System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win")) {
binariesPath = "Binaries/" + runtimeLib + "/Windows/" + osArch + "/";
} else if (System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("mac")) {
binariesPath = "Binaries/" + runtimeLib + "/MacOs/" + osArch + "/";
} else {
binariesPath = "Binaries/" + runtimeLib + "/Linux/" + osArch + "/";
}
return binariesPath;
}
private static boolean isAndroid() {
return System.getProperty("os.version").toLowerCase(Locale.US).contains("android");
}
private static String getJarPath(Class> aclass) {
URL url;
String extURL;
try {
url = aclass.getProtectionDomain().getCodeSource().getLocation();
} catch (SecurityException ex) {
url = aclass.getResource(aclass.getSimpleName() + ".class");
}
extURL = url.toExternalForm();
// Check for nested JAR
if (extURL.contains(".jar!")) {
return extURL;
}
if (!extURL.endsWith(".jar")) {
String suffix = "/"+(aclass.getName()).replace(".", "/")+".class";
extURL = extURL.replace(suffix, "");
if (extURL.startsWith("jar:") && extURL.endsWith(".jar!")) {
extURL = extURL.substring(4);
}
}
try {
return new File(new URL(extURL).toURI()).getAbsolutePath();
} catch(MalformedURLException | URISyntaxException ex) {
return new File(url.getPath()).getAbsolutePath();
}
}
private static String getManifestProperty(String propertyName) throws IOException {
Enumeration resources = BinariesUnloader.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
try (InputStream input = resources.nextElement().openStream()) {
Manifest manifest = new Manifest(input);
Attributes mainAttributes = manifest.getMainAttributes();
String value = mainAttributes.getValue(propertyName);
if (value != null) {
return value;
}
}
}
return null;
}
private static boolean shouldUpdateBinaries(Path binariesPath, String currentVersion) throws IOException {
Path versionFile = Paths.get(binariesPath.toString(), "version.txt");
if (Files.exists(versionFile)) {
String oldVersion = new String(Files.readAllBytes(versionFile), StandardCharsets.UTF_8);
oldVersion = oldVersion.replace("'", ""); // remove single quotes
return !oldVersion.equals(currentVersion);
} else {
return true;
}
}
}