This commit is contained in:
Andrea Cavalli 2023-05-09 18:01:53 +02:00
parent dba5c107cc
commit 36a6e90335
14 changed files with 207 additions and 280 deletions

View File

@ -11,13 +11,13 @@ jobs:
strategy: strategy:
matrix: matrix:
include: include:
- { os: ubuntu-20.04, arch: "linux/amd64", ssl: "ssl1" } - { os: ubuntu-20.04, arch: "linux/amd64" }
- { os: ubuntu-20.04, arch: "linux/amd64", ssl: "ssl3" }
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- name: Branch name - name: Branch name
id: branch_name id: branch_name
run: | run: |
set -xeo pipefail
echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/} echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/}
echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/} echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/}
echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/} echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/}
@ -28,6 +28,7 @@ jobs:
- name: Setup variables - name: Setup variables
shell: bash shell: bash
run: | run: |
set -xeo pipefail
# ====== Variables # ====== Variables
export REVISION=${{ steps.branch_name.outputs.SOURCE_TAG_VERSION }} export REVISION=${{ steps.branch_name.outputs.SOURCE_TAG_VERSION }}
export SSL_TYPE=${{ matrix.ssl }} export SSL_TYPE=${{ matrix.ssl }}
@ -44,13 +45,15 @@ jobs:
server-id: mchv-snapshot-distribution server-id: mchv-snapshot-distribution
server-username: MAVEN_USERNAME server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD server-password: MAVEN_PASSWORD
- name: Build (Snapshot) - name: Build and deploy to Maven (Snapshot)
if: ${{ !startsWith(github.ref, 'refs/tags/v') && matrix.ssl == 'ssl1' }} if: ${{ !startsWith(github.ref, 'refs/tags/v') && matrix.ssl == 'ssl1' }}
shell: bash shell: bash
run: | run: |
set -xeo pipefail
echo "SSL_TYPE: $SSL_TYPE" echo "SSL_TYPE: $SSL_TYPE"
source ./scripts/continuous-integration/github-workflows/deploy-snapshot.sh mvn -B -f bom/pom.xml -P "java8,java17" clean deploy
echo "Done."
env: env:
MAVEN_USERNAME: ${{ secrets.MCHV_USERNAME }} MAVEN_USERNAME: ${{ secrets.MCHV_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MCHV_TOKEN }} MAVEN_PASSWORD: ${{ secrets.MCHV_TOKEN }}
@ -64,14 +67,16 @@ jobs:
server-id: mchv-release-distribution server-id: mchv-release-distribution
server-username: MAVEN_USERNAME server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD server-password: MAVEN_PASSWORD
- name: Deploy to Maven (Release) - name: Build and deploy to Maven (Release)
if: ${{ startsWith(github.ref, 'refs/tags/v') }} if: ${{ startsWith(github.ref, 'refs/tags/v') }}
shell: bash shell: bash
run: | run: |
set -xeo pipefail
echo "REVISION: $REVISION" echo "REVISION: $REVISION"
echo "SSL_TYPE: $SSL_TYPE" echo "SSL_TYPE: $SSL_TYPE"
source ./scripts/continuous-integration/github-workflows/deploy-release.sh mvn -B -f bom/pom.xml -Drevision="${REVISION}" -P "java8,java17" clean deploy
echo "Done."
env: env:
MAVEN_USERNAME: ${{ secrets.MCHV_USERNAME }} MAVEN_USERNAME: ${{ secrets.MCHV_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MCHV_TOKEN }} MAVEN_PASSWORD: ${{ secrets.MCHV_TOKEN }}

View File

@ -8,14 +8,8 @@
<name>TDLight Java BOM</name> <name>TDLight Java BOM</name>
<properties> <properties>
<revision>3.0.0.0-SNAPSHOT</revision> <revision>3.0.0.0-SNAPSHOT</revision>
<nativesSsl3Suffix/> <tdlight.natives.version>4.0.374</tdlight.natives.version>
<nativesRevisionNumber>307</nativesRevisionNumber> <tdlight.api.version>4.0.372</tdlight.api.version>
<apiRevisionNumber>305</apiRevisionNumber>
<nativesRevisionSuffix/>
<tdlight.natives.version>4.0.${nativesRevisionNumber}${nativesRevisionSuffix}</tdlight.natives.version>
<tdlight.natives.ssl3.version>4.0.${nativesRevisionNumber}${nativesSsl3Suffix}${nativesRevisionSuffix}</tdlight.natives.ssl3.version>
<apiRevisionSuffix/>
<tdlight.api.version>4.0.${apiRevisionNumber}${apiRevisionSuffix}</tdlight.api.version>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
</properties> </properties>
@ -56,23 +50,14 @@
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
<artifactId>tdlight-api-legacy</artifactId> <artifactId>tdlight-api</artifactId>
<version>${tdlight.api.version}</version> <version>${tdlight.api.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
<artifactId>tdlight-api-sealed</artifactId> <artifactId>tdlight-api</artifactId>
<version>${tdlight.api.version}</version>
</dependency>
<dependency>
<groupId>it.tdlight</groupId>
<artifactId>tdlib-api-legacy</artifactId>
<version>${tdlight.api.version}</version>
</dependency>
<dependency>
<groupId>it.tdlight</groupId>
<artifactId>tdlib-api-sealed</artifactId>
<version>${tdlight.api.version}</version> <version>${tdlight.api.version}</version>
<classifier>legacy</classifier>
</dependency> </dependency>
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
@ -95,45 +80,66 @@
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
<artifactId>tdlight-natives-linux-amd64</artifactId> <artifactId>tdlight-natives</artifactId>
<version>${tdlight.natives.ssl3.version}</version>
</dependency>
<dependency>
<groupId>it.tdlight</groupId>
<artifactId>tdlight-natives-linux-aarch64</artifactId>
<version>${tdlight.natives.ssl3.version}</version>
</dependency>
<dependency>
<groupId>it.tdlight</groupId>
<artifactId>tdlight-natives-linux-x86</artifactId>
<version>${tdlight.natives.version}</version> <version>${tdlight.natives.version}</version>
<classifier>linux-amd64-ssl1</classifier>
</dependency> </dependency>
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
<artifactId>tdlight-natives-linux-armhf</artifactId> <artifactId>tdlight-natives</artifactId>
<version>${tdlight.natives.version}</version> <version>${tdlight.natives.version}</version>
<classifier>linux-amd64-ssl3</classifier>
</dependency> </dependency>
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
<artifactId>tdlight-natives-linux-ppc64le</artifactId> <artifactId>tdlight-natives</artifactId>
<version>${tdlight.natives.version}</version> <version>${tdlight.natives.version}</version>
<classifier>linux-arm64-ssl1</classifier>
</dependency>
<!--
<dependency>
<groupId>it.tdlight</groupId>
<artifactId>tdlight-natives</artifactId>
<version>${tdlight.natives.version}</version>
<classifier>linux-armhf-ssl1</classifier>
</dependency> </dependency>
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
<artifactId>tdlight-natives-windows-amd64</artifactId> <artifactId>tdlight-natives</artifactId>
<version>${tdlight.natives.version}</version> <version>${tdlight.natives.version}</version>
<classifier>linux-i386-ssl1</classifier>
</dependency> </dependency>
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
<artifactId>tdlight-natives-windows-s390x</artifactId> <artifactId>tdlight-natives</artifactId>
<version>${tdlight.natives.version}</version> <version>${tdlight.natives.version}</version>
<classifier>linux-ppc64le-ssl1</classifier>
</dependency> </dependency>
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
<artifactId>tdlight-natives-osx-amd64</artifactId> <artifactId>tdlight-natives</artifactId>
<version>${tdlight.natives.version}</version> <version>${tdlight.natives.version}</version>
<classifier>linux-s390x-ssl1</classifier>
</dependency> </dependency>
<dependency>
<groupId>it.tdlight</groupId>
<artifactId>tdlight-natives</artifactId>
<version>${tdlight.natives.version}</version>
<classifier>windows-amd64</classifier>
</dependency>
<dependency>
<groupId>it.tdlight</groupId>
<artifactId>tdlight-natives</artifactId>
<version>${tdlight.natives.version}</version>
<classifier>osx-amd64</classifier>
</dependency>
<dependency>
<groupId>it.tdlight</groupId>
<artifactId>tdlight-natives</artifactId>
<version>${tdlight.natives.version}</version>
<classifier>osx-arm64</classifier>
</dependency>
-->
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

View File

@ -1,28 +1,17 @@
#!/bin/bash -e #!/bin/bash -e
# OTHER REQUIRED ENVIRONMENT VARIABLES: # OTHER REQUIRED ENVIRONMENT VARIABLES:
# REVISION = <revision> # REVISION = <revision>
# SSL_TYPE = <ssl1|ssl3>
# Check variables correctness # Check variables correctness
if [ -z "${REVISION}" ]; then if [ -z "${REVISION}" ]; then
echo "Missing parameter: REVISION" echo "Missing parameter: REVISION"
exit 1 exit 1
fi fi
# Check variables correctness
if [ -z "${SSL_TYPE}" ]; then
echo "Missing parameter: SSL_TYPE"
exit 1
fi
SSL_SUFFIX=""
if [[ "$SSL_TYPE" == "ssl3" ]]; then
SSL_SUFFIX="-ssl3"
fi
cd "../../" cd "../../"
cd "bom" cd "bom"
mvn -B -Drevision="${REVISION}${SSL_SUFFIX}" -DnativesSsl3Suffix="${SSL_SUFFIX}" -P "java8,java17" clean deploy mvn -B -Drevision="${REVISION}" -P "java8,java17" clean deploy
cd "../" cd "../"
echo "Done." echo "Done."

View File

@ -4,7 +4,7 @@
cd "../../" cd "../../"
cd "bom" cd "bom"
mvn -B clean package mvn -B package
cd "../" cd "../"
echo "Done." echo "Done."

View File

@ -13,7 +13,6 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<revision>3.0.0.0-SNAPSHOT</revision> <revision>3.0.0.0-SNAPSHOT</revision>
<nativesSsl3Suffix/>
</properties> </properties>
<repositories> <repositories>
<repository> <repository>
@ -76,9 +75,15 @@
<dependency> <dependency>
<groupId>io.projectreactor.tools</groupId> <groupId>io.projectreactor.tools</groupId>
<artifactId>blockhound</artifactId> <artifactId>blockhound</artifactId>
<version>1.0.7.RELEASE</version> <version>1.0.8.RELEASE</version>
<optional>true</optional>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</dependency>
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
@ -112,7 +117,8 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
<artifactId>tdlight-api-legacy</artifactId> <artifactId>tdlight-api</artifactId>
<classifier>legacy</classifier>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
@ -172,7 +178,7 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>it.tdlight</groupId> <groupId>it.tdlight</groupId>
<artifactId>tdlight-api-sealed</artifactId> <artifactId>tdlight-api</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
@ -350,12 +356,12 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId> <artifactId>maven-install-plugin</artifactId>
<version>3.0.0-M1</version> <version>3.1.1</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId> <artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version> <version>3.1.1</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>

View File

@ -5,12 +5,4 @@ public final class LibraryVersion {
public static final String VERSION = "${project.version}"; public static final String VERSION = "${project.version}";
public static final String NATIVES_VERSION = "4.0.${nativesRevisionNumber}${nativesRevisionSuffix}"; public static final String NATIVES_VERSION = "4.0.${nativesRevisionNumber}${nativesRevisionSuffix}";
public static final String IMPLEMENTATION_NAME = "tdlight"; public static final String IMPLEMENTATION_NAME = "tdlight";
public static final String LINUX_X86_CLASS = "it.tdlight.jni.tdlight.linux.x86.v4_0_${nativesRevisionNumber}.LoadLibrary";
public static final String LINUX_AMD64_CLASS = "it.tdlight.jni.tdlight.linux.amd64.v4_0_${nativesRevisionNumber}.LoadLibrary";
public static final String LINUX_AARCH64_CLASS = "it.tdlight.jni.tdlight.linux.aarch64.v4_0_${nativesRevisionNumber}.LoadLibrary";
public static final String LINUX_ARMHF_CLASS = "it.tdlight.jni.tdlight.linux.armhf.v4_0_${nativesRevisionNumber}.LoadLibrary";
public static final String LINUX_S390X_CLASS = "it.tdlight.jni.tdlight.linux.s390x.v4_0_${nativesRevisionNumber}.LoadLibrary";
public static final String LINUX_PPC64LE_CLASS = "it.tdlight.jni.tdlight.linux.ppc64le.v4_0_${nativesRevisionNumber}.LoadLibrary";
public static final String WINDOWS_AMD64_CLASS = "it.tdlight.jni.tdlight.win.amd64.v4_0_${nativesRevisionNumber}.LoadLibrary";
public static final String OSX_AMD64_CLASS = "it.tdlight.jni.tdlight.osx.amd64.v4_0_${nativesRevisionNumber}.LoadLibrary";
} }

View File

@ -19,6 +19,9 @@ package it.tdlight;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -28,8 +31,8 @@ import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public final class ConstructorDetector { public final class ConstructorDetector {
private static ConcurrentHashMap<Integer, Class> constructorHashMap; private static Map<Integer, Class> constructorHashMap;
private static ConcurrentHashMap<Class, Integer> constructorHashMapInverse; private static IdentityHashMap<Class, Integer> constructorHashMapInverse;
private static void tryInit() { private static void tryInit() {
// Call this to load static methods and prevent errors during startup! // Call this to load static methods and prevent errors during startup!
@ -75,8 +78,8 @@ public final class ConstructorDetector {
} }
private static void setConstructorHashMap(Class[] tdApiClasses) { private static void setConstructorHashMap(Class[] tdApiClasses) {
constructorHashMap = new ConcurrentHashMap<>(); constructorHashMap = new HashMap<>();
constructorHashMapInverse = new ConcurrentHashMap<>(); constructorHashMapInverse = new IdentityHashMap<>();
for (Class apiClass : tdApiClasses) { for (Class apiClass : tdApiClasses) {
Field CONSTRUCTORField; Field CONSTRUCTORField;

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2018. Ernesto Castellotti <erny.castell@gmail.com>
* This file is part of JTdlib.
*
* JTdlib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* JTdlib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JTdlib. If not, see <http://www.gnu.org/licenses/>.
*/
package it.tdlight.utils;
/**
* Architectures recognized by this library.
*/
public enum Arch {
UNKNOWN, AMD64, I386, ARMHF, AARCH64, PPC64LE, S390X
}

View File

@ -37,7 +37,7 @@ public final class CantLoadLibrary extends Exception {
super(message, cause); super(message, cause);
} }
public CantLoadLibrary(Exception cause) { public CantLoadLibrary(Throwable cause) {
super(cause); super(cause);
} }
} }

View File

@ -14,43 +14,33 @@
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with JTdlib. If not, see <http://www.gnu.org/licenses/>. * along with JTdlib. If not, see <http://www.gnu.org/licenses/>.
*/ */
package it.tdlight.utils; package it.tdlight.utils;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.StringJoiner; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* The class to load the libraries needed to run Tdlib * The class to load the libraries needed to run Tdlib
*/ */
public final class LoadLibrary { public final class LoadLibrary {
private static final ConcurrentHashMap<String, Boolean> libraryLoaded = new ConcurrentHashMap<>(); private static final Set<String> LIBRARY_LOADED = new ConcurrentHashMap<String, Boolean>().keySet(true);
private static final Path librariesPath = Paths.get(".cache"); private static final String LIBS_VERSION =
private static final String libsVersion =
LibraryVersion.IMPLEMENTATION_NAME + "-" + LibraryVersion.VERSION + "-" + LibraryVersion.NATIVES_VERSION; LibraryVersion.IMPLEMENTATION_NAME + "-" + LibraryVersion.VERSION + "-" + LibraryVersion.NATIVES_VERSION;
static {
if (Files.notExists(librariesPath)) {
try {
Files.createDirectories(librariesPath);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/** /**
* Load a library installed in the system (priority choice) or a library included in the jar. * Load a library installed in the system (priority choice) or a library included in the jar.
* *
@ -62,35 +52,34 @@ public final class LoadLibrary {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
if (libraryLoaded.containsKey(libname)) { if (LIBRARY_LOADED.contains(libname)) return;
if (libraryLoaded.get(libname)) { synchronized (LoadLibrary.class) {
return; if (LIBRARY_LOADED.contains(libname)) return;
String libraryCachePathString = System.getProperty("it.tdlight.libraryCachePath");
Path libraryCachePath = libraryCachePathString != null ? Paths.get(libraryCachePathString) : null;
loadLibrary(libname, libraryCachePath);
LIBRARY_LOADED.add(libname);
} }
} }
loadLibrary(libname); /**
libraryLoaded.put(libname, true); * Load a native library
* @param libraryName Library name
* @param libraryCachePath optional, path in which the library will be extracted
* @throws CantLoadLibrary The library can't be loaded
*/
private static void loadLibrary(String libraryName, Path libraryCachePath) throws CantLoadLibrary {
if (libraryCachePath == null) {
libraryCachePath = Paths.get(System.getProperty("user.home")).resolve(".cache").resolve("tdlight-jni-cache");
} }
private static void loadLibrary(String libname) throws CantLoadLibrary {
Arch arch = getCpuArch();
Os os = getOs();
if (arch == Arch.UNKNOWN) {
throw new CantLoadLibrary("Arch: \"" + System.getProperty("os.arch") + "\" is unknown");
}
if (os == Os.UNKNOWN) {
throw new CantLoadLibrary("Os: \"" + System.getProperty("os.name") + "\" is unknown");
}
try { try {
loadJarLibrary(libname, arch, os); loadJarLibrary(libraryName, libraryCachePath);
} catch (CantLoadLibrary | UnsatisfiedLinkError e) { } catch (CantLoadLibrary | UnsatisfiedLinkError e) {
if (loadSysLibrary(libname)) { if (loadSysLibrary(libraryName)) {
return; return;
} }
throw (CantLoadLibrary) new CantLoadLibrary().initCause(e); throw new CantLoadLibrary(e);
} }
} }
@ -104,79 +93,25 @@ public final class LoadLibrary {
return true; return true;
} }
private static String removeLastPackageParts(String clazz, int count, String className) { private static void loadJarLibrary(String libraryName, Path libraryCachePath) throws CantLoadLibrary {
List<String> parts = new ArrayList<>(Arrays.asList(clazz.split("\\.")));
parts.remove(parts.size() - 1);
for (int i = 0; i < count; i++) {
parts.remove(parts.size() - 1);
}
StringJoiner joiner = new StringJoiner(".");
for (String part : parts) {
joiner.add(part);
}
joiner.add(className);
return joiner.toString();
}
private static void loadJarLibrary(String libname, Arch arch, Os os) throws CantLoadLibrary {
Path tempPath; Path tempPath;
try { try {
tempPath = Files.createDirectories(librariesPath.resolve("version-" + libsVersion).resolve(libname)); tempPath = libraryCachePath.resolve("version-" + LIBS_VERSION).resolve(libraryName);
if (Files.notExists(tempPath)) {
tempPath = Files.createDirectories(tempPath);
}
} catch (IOException e) { } catch (IOException e) {
throw new CantLoadLibrary("Can't create temporary files", e); throw new CantLoadLibrary("Can't create temporary files", e);
} }
Path tempFile = Paths.get(tempPath.toString(), libname + getExt(os));
Class<?> classForResource = null; ClassLoader classForResource = LoadLibrary.class.getClassLoader();
switch (os) { List<String> normalizedArchs = getNormalizedArchitectures().collect(Collectors.toList());
case LINUX: Exception lastEx = null;
switch (arch) { loadAny: for (String normalizedArch : normalizedArchs) {
case AMD64: Path tempFile = tempPath.resolve(libraryName + "." + normalizedArch);
classForResource = tryLoadLibraryVersionClass(LibraryVersion.LINUX_AMD64_CLASS, os, arch);
break;
case I386:
classForResource = tryLoadLibraryVersionClass(LibraryVersion.LINUX_X86_CLASS, os, arch);
break;
case AARCH64:
classForResource = tryLoadLibraryVersionClass(LibraryVersion.LINUX_AARCH64_CLASS, os, arch);
break;
case ARMHF:
classForResource = tryLoadLibraryVersionClass(LibraryVersion.LINUX_ARMHF_CLASS, os, arch);
break;
case S390X:
classForResource = tryLoadLibraryVersionClass(LibraryVersion.LINUX_S390X_CLASS, os, arch);
break;
case PPC64LE:
classForResource = tryLoadLibraryVersionClass(LibraryVersion.LINUX_PPC64LE_CLASS, os, arch);
break;
}
break;
case OSX:
if (arch == Arch.AMD64) {
classForResource = tryLoadLibraryVersionClass(LibraryVersion.OSX_AMD64_CLASS, os, arch);
}
break;
case WINDOWS:
switch (arch) {
case AMD64:
classForResource = tryLoadLibraryVersionClass(LibraryVersion.WINDOWS_AMD64_CLASS, os, arch);
break;
case I386:
break;
}
break;
}
if (classForResource == null) {
throw new CantLoadLibrary("Native libraries for platform " + os + "-" + arch + " not found!"
+ " Required version: " + getRequiredVersionName(os, arch));
}
InputStream libInputStream; InputStream libInputStream;
try { try {
libInputStream = Objects.requireNonNull((InputStream) classForResource libInputStream = Objects.requireNonNull(classForResource.getResourceAsStream("META-INF/tdlight-jni/lib" + libraryName + "." + normalizedArch));
.getDeclaredMethod("getLibraryAsStream")
.invoke(InputStream.class));
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | NullPointerException e) {
throw new CantLoadLibrary("Native libraries for platform " + os + "-" + arch + " not found!", e);
}
if (Files.notExists(tempFile)) { if (Files.notExists(tempFile)) {
try { try {
Files.copy(libInputStream, tempFile); Files.copy(libInputStream, tempFile);
@ -189,47 +124,81 @@ public final class LoadLibrary {
} catch (IOException e) { } catch (IOException e) {
throw new CantLoadLibrary("Can't load the native libraries", e); throw new CantLoadLibrary("Can't load the native libraries", e);
} }
System.load(tempFile.toFile().getAbsolutePath()); System.load(tempFile.toAbsolutePath().toString());
lastEx = null;
break loadAny;
} catch (Throwable e) {
lastEx = new CantLoadLibrary(e);
} }
}
private static Class<?> tryLoadLibraryVersionClass(String classForResource, Os os, Arch arch) { if (lastEx != null) {
try { throw new CantLoadLibrary("Native libraries for platforms "
return Class.forName(classForResource); + String.join(", ", normalizedArchs) + " not found!", lastEx);
} catch (ClassNotFoundException e1) {
// No library was found, return
return null;
} }
} }
private static String getRequiredVersionName(Os os, Arch arch) { private static Stream<String> getNormalizedArchitectures() {
return LibraryVersion.IMPLEMENTATION_NAME + " " + os.toString().toLowerCase() + " " + arch.toString().toLowerCase() String os = getOs();
+ " " + LibraryVersion.NATIVES_VERSION; String arch = getCpuArch();
if (os.equals("unknown") || arch.equals("unknown")) {
return getAllNormalizedArchitectures();
}
return getNormalizedArchitectures(os, arch);
} }
private static Arch getCpuArch() { private static Stream<String> getAllNormalizedArchitectures() {
Set<String> all = new LinkedHashSet<>();
for (String os : new String[]{"windows"}) {
for (String arch : new String[]{"arm64", "amd64", "armhf", "i386", "s390x", "ppc64le"}) {
getNormalizedArchitectures(os, arch).forEach(all::add);
}
}
return all.stream();
}
private static Stream<String> getNormalizedArchitectures(String os, String arch) {
switch (os) {
case "linux": {
return Stream.of("linux-" + arch + "-ssl1.so", "linux-" + arch + "-ssl3.so");
}
case "windows": {
return Stream.of("windows-" + arch + ".dll");
}
case "osx": {
return Stream.of("osx-" + arch + ".dylib");
}
default: {
throw new UnsupportedOperationException();
}
}
}
private static String getCpuArch() {
String architecture = System.getProperty("os.arch").trim(); String architecture = System.getProperty("os.arch").trim();
switch (architecture) { switch (architecture) {
case "amd64": case "amd64":
case "x86_64": case "x86_64":
return Arch.AMD64; return "amd64";
case "i386": case "i386":
case "x86": case "x86":
case "386": case "386":
case "i686": case "i686":
case "686": case "686":
return Arch.I386; return "i386";
case "armv6": case "armv6":
case "arm": case "arm":
case "armhf": case "armhf":
case "aarch32": case "aarch32":
case "armv7": case "armv7":
case "armv7l": case "armv7l":
return Arch.ARMHF; return "armhf";
case "arm64": case "arm64":
case "aarch64": case "aarch64":
case "armv8": case "armv8":
case "armv8l": case "armv8l":
return Arch.AARCH64; return "arm64";
case "s390x":
return "s390x";
case "powerpc": case "powerpc":
case "powerpc64": case "powerpc64":
case "powerpc64le": case "powerpc64le":
@ -242,42 +211,29 @@ public final class LoadLibrary {
.nativeOrder() .nativeOrder()
.equals(ByteOrder.LITTLE_ENDIAN)) // Java always returns ppc64 for all 64-bit powerpc but .equals(ByteOrder.LITTLE_ENDIAN)) // Java always returns ppc64 for all 64-bit powerpc but
{ {
return Arch.PPC64LE; // powerpc64le (our target) is very different, it uses this condition to accurately identify the architecture return "ppc64le"; // powerpc64le (our target) is very different, it uses this condition to accurately identify the architecture
} else { } else {
return Arch.UNKNOWN; return "unknown";
} }
default: default:
return Arch.UNKNOWN; return "unknown";
} }
} }
public static Os getOs() { public static String getOs() {
String os = System.getProperty("os.name").toLowerCase().trim(); String os = System.getProperty("os.name").toLowerCase().trim();
if (os.contains("linux")) { if (os.contains("linux")) {
return Os.LINUX; return "linux";
} }
if (os.contains("windows")) { if (os.contains("windows")) {
return Os.WINDOWS; return "windows";
} }
if (os.contains("mac")) { if (os.contains("mac")) {
return Os.OSX; return "osx";
} }
if (os.contains("darwin")) { if (os.contains("darwin")) {
return Os.OSX; return "osx";
}
return Os.UNKNOWN;
}
private static String getExt(Os os) {
switch (os) {
case WINDOWS:
return ".dll";
case OSX:
return ".dylib";
case LINUX:
case UNKNOWN:
default:
return ".so";
} }
return "unknown";
} }
} }

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2018. Ernesto Castellotti <erny.castell@gmail.com>
* This file is part of JTdlib.
*
* JTdlib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* JTdlib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JTdlib. If not, see <http://www.gnu.org/licenses/>.
*/
package it.tdlight.utils;
/**
* Enumeration with all operating systems recognized by this library.
*/
public enum Os {
LINUX, WINDOWS, OSX, UNKNOWN
}

View File

@ -0,0 +1,18 @@
package it.tdlight.utils;
import reactor.blockhound.BlockHound.Builder;
import reactor.blockhound.integration.BlockHoundIntegration;
public class TDLightBlockHoundIntegration implements BlockHoundIntegration {
@Override
public void applyTo(Builder builder) {
builder.nonBlockingThreadPredicate(current -> current.or(t -> {
if (t.getName() == null) {
return false;
}
return t.getName().equals("TDLib thread");
}));
}
}

View File

@ -3,6 +3,7 @@ module tdlight.java {
requires org.reactivestreams; requires org.reactivestreams;
requires org.slf4j; requires org.slf4j;
requires static com.google.zxing; requires static com.google.zxing;
requires static reactor.blockhound;
exports it.tdlight.tdnative; exports it.tdlight.tdnative;
exports it.tdlight; exports it.tdlight;
exports it.tdlight.utils; exports it.tdlight.utils;

View File

@ -0,0 +1 @@
it.tdlight.utils.TDLightBlockHoundIntegration