Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the right classloader to load the native library #628

Merged
merged 1 commit into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package net.consensys.linea;

import lombok.extern.slf4j.Slf4j;
import net.consensys.linea.compress.LibCompress;
import net.consensys.linea.config.LineaL1L2BridgeCliOptions;
import net.consensys.linea.config.LineaL1L2BridgeConfiguration;
import net.consensys.linea.config.LineaTransactionSelectorCliOptions;
Expand All @@ -38,6 +39,11 @@ public abstract class AbstractLineaSharedOptionsPlugin implements BesuPlugin {
protected static LineaTransactionValidatorConfiguration transactionValidatorConfiguration;
protected static LineaL1L2BridgeConfiguration l1L2BridgeConfiguration;

static {
// force the initialization of the gnark compress native library to fail fast in case of issues
LibCompress.CompressedSize(new byte[0], 0);
}

@Override
public synchronized void register(final BesuContext context) {
if (!cliOptionsRegistered) {
Expand Down
85 changes: 43 additions & 42 deletions native/compress/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,90 +14,91 @@
*/

plugins {
id 'java-library'
id 'maven-publish'
id 'com.jfrog.artifactory' version '4.20.0'
id 'java-library'
id 'common-plugins'
}

apply from: rootProject.file("gradle/java.gradle")
apply from: rootProject.file("gradle/dependency-management.gradle")
apply from: rootProject.file('gradle/common-dependencies.gradle')
apply from: rootProject.file("gradle/build-aliases.gradle")
apply from: rootProject.file("gradle/lint.gradle")

repositories {
mavenCentral()
mavenCentral()
}

test {
useJUnitPlatform()
useJUnitPlatform()
}

tasks.register('buildJNI', Exec) {
workingDir buildscript.sourceFile.parentFile
commandLine 'sh', '-c', '../build.sh'
workingDir buildscript.sourceFile.parentFile
commandLine 'sh', '-c', '../build.sh'
}

compileJava{
dependsOn buildJNI
dependsOn buildJNI
}

dependencies {
implementation 'net.java.dev.jna:jna'
implementation 'io.tmio:tuweni-bytes'
implementation 'net.java.dev.jna:jna'
implementation 'io.tmio:tuweni-bytes'

testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.junit.jupiter:junit-jupiter-engine'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.junit.jupiter:junit-jupiter-engine'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.mockito:mockito-core'
}


tasks.register('macArmLibCopy', Copy) {
from 'build/native/libcompress_jni.dylib'
into 'build/resources/main/darwin-aarch64'
from 'build/native/libcompress_jni.dylib'
into 'build/resources/main/darwin-aarch64'
}
processResources.dependsOn macArmLibCopy

tasks.register('macLibCopy', Copy) {
from 'build/native/libcompress_jni.dylib'
into 'build/resources/main/darwin-x86-64'
from 'build/native/libcompress_jni.dylib'
into 'build/resources/main/darwin-x86-64'
}
processResources.dependsOn macLibCopy

tasks.register('linuxLibCopy', Copy) {
from 'build/native/libcompress_jni.so'
into 'build/resources/main/linux-x86-64'
from 'build/native/libcompress_jni.so'
into 'build/resources/main/linux-x86-64'
}
processResources.dependsOn linuxLibCopy

tasks.register('linuxArm64LibCopy', Copy) {
from 'build/native/libcompress_jni.so'
into 'build/resources/main/linux-aarch64'
from 'build/native/libcompress_jni.so'
into 'build/resources/main/linux-aarch64'
}
processResources.dependsOn linuxArm64LibCopy

jar {
archiveBaseName = 'linea-native-compress'
includeEmptyDirs = false
manifest {
attributes(
'Specification-Title': archiveBaseName,
'Specification-Version': project.version,
'Implementation-Title': archiveBaseName,
'Implementation-Version': project.version,
'Automatic-Module-Name': 'org.consensys.nativelib.compress'
)
}
archiveBaseName = 'linea-native-compress'
includeEmptyDirs = false
manifest {
attributes(
'Specification-Title': archiveBaseName,
'Specification-Version': project.version,
'Implementation-Title': archiveBaseName,
'Implementation-Version': project.version,
'Automatic-Module-Name': 'net.consensys.nativelib.compress'
)
}
}

jar.dependsOn(buildJNI)

sourceSets {
main {
resources {
srcDirs '${buildDir}/darwin-aaarch64'
srcDirs '${buildDir}/darwin-x86-64'
srcDirs '${buildDir}/linux-gnu-x86_64'
srcDirs '${buildDir}/linux-gnu-aarch64'
}
main {
resources {
srcDirs '${buildDir}/darwin-aaarch64'
srcDirs '${buildDir}/darwin-x86-64'
srcDirs '${buildDir}/linux-gnu-x86_64'
srcDirs '${buildDir}/linux-gnu-aarch64'
}
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -15,53 +15,57 @@
*/
package net.consensys.linea.compress;

import com.sun.jna.Native;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;

/**
* Java interface to compress
*/
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;

/** Java interface to compress */
@Slf4j
public class LibCompress {

@SuppressWarnings("WeakerAccess")
public static final boolean ENABLED;
@SuppressWarnings("WeakerAccess")
public static final boolean ENABLED;

static {
boolean enabled;
try {
final File compressJni = Native.extractFromResourcePath("compress_jni");
Native.register(LibCompress.class, compressJni.getAbsolutePath());
static {
try {
final File compressJni =
Native.extractFromResourcePath("compress_jni", LibCompress.class.getClassLoader());
Native.register(LibCompress.class, compressJni.getAbsolutePath());

Path dictFilePath = Files.createTempFile("tempCompressor_dict", "bin");
try (InputStream stream = LibCompress.class.getClassLoader().getResourceAsStream("compressor_dict.bin")) {
Files.copy(stream, dictFilePath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
dictFilePath.toFile().deleteOnExit();
} catch (Exception e) {
System.out.println("Problem creating temp file from compressor_dict.bin resource: " + e.getMessage());
dictFilePath.toFile().delete();
System.exit(-1);
}
Path dictFilePath = Files.createTempFile("tempCompressor_dict", "bin");
try (InputStream stream =
LibCompress.class.getClassLoader().getResourceAsStream("compressor_dict.bin")) {
Files.copy(stream, dictFilePath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
dictFilePath.toFile().deleteOnExit();
} catch (Exception e) {
log.error(
"Problem creating temp file from compressor_dict.bin resource: " + e.getMessage());
dictFilePath.toFile().delete();
System.exit(1);
}

final String dictPath = dictFilePath.toAbsolutePath().toString();
if (!Init(dictPath)) {
throw new RuntimeException(Error());
}
enabled = true;
} catch (final Throwable t) {
t.printStackTrace();
enabled = false;
}
ENABLED = enabled;
final String dictPath = dictFilePath.toAbsolutePath().toString();
if (!Init(dictPath)) {
throw new RuntimeException(Error());
}
log.info(
"Loaded compress_jni native library from {} with compressor_dict {}",
compressJni,
dictPath);
} catch (final Throwable t) {
log.error("Error loading native compress_jni library", t);
System.exit(1);
}
ENABLED = true;
}

public static native boolean Init(String dictPath);

public static native boolean Init(String dictPath);

public static native int CompressedSize(
byte[] i, int i_len);
public static native int CompressedSize(byte[] i, int i_len);

public static native String Error();
}
public static native String Error();
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,29 @@
*/
package net.consensys.linea.compress;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

public class LibCompressTest {
@Test
public void testCompressZeroes() {
byte[] zeroes = new byte[128];
int size = LibCompress.CompressedSize(zeroes, 128);

// should not error
assertThat(size).isGreaterThan(0);

// should have compressed into 1 backref + header, must be less than 10
assertThat(size).isLessThan(10);
}

@Test
public void testCompressTooLargeInput() {
byte[] zeroes = new byte[512*1024];
int size = LibCompress.CompressedSize(zeroes, 512*1024);

// should error --> too large payload.
assertThat(size).isLessThan(0);
}
import org.junit.jupiter.api.Test;

}
public class LibCompressTest {
@Test
public void testCompressZeroes() {
byte[] zeroes = new byte[128];
int size = LibCompress.CompressedSize(zeroes, 128);

// should not error
assertThat(size).isGreaterThan(0);

// should have compressed into 1 backref + header, must be less than 10
assertThat(size).isLessThan(10);
}

@Test
public void testCompressTooLargeInput() {
byte[] zeroes = new byte[512 * 1024];
int size = LibCompress.CompressedSize(zeroes, 512 * 1024);

// should error --> too large payload.
assertThat(size).isLessThan(0);
}
}
Loading