Skip to content

Commit

Permalink
Use the right classloader to load the native library (#628)
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio Di Fabio <fabio.difabio@consensys.net>
  • Loading branch information
fab-10 authored Feb 27, 2024
1 parent be738e7 commit 3188771
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 103 deletions.
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);
}
}

0 comments on commit 3188771

Please sign in to comment.