Skip to content

Commit

Permalink
Move snappy native library resource registration to a feature
Browse files Browse the repository at this point in the history
Always registers the correct native library as the logic runs on the
same architecture we are targeting (even when using containers).

Closes quarkusio#43801
  • Loading branch information
zakkak committed Oct 16, 2024
1 parent fe164e0 commit b9ec68c
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,17 @@
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.LogCategoryBuildItem;
import io.quarkus.deployment.builditem.NativeImageFeatureBuildItem;
import io.quarkus.deployment.builditem.RunTimeConfigurationDefaultBuildItem;
import io.quarkus.deployment.builditem.RuntimeConfigSetupCompleteBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageConfigBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageSecurityProviderBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassConditionBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
import io.quarkus.deployment.logging.LogCleanupFilterBuildItem;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.deployment.pkg.builditem.NativeImageRunnerBuildItem;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import io.quarkus.kafka.client.runtime.KafkaAdminClient;
import io.quarkus.kafka.client.runtime.KafkaBindingConverter;
Expand All @@ -95,6 +94,7 @@
import io.quarkus.kafka.client.runtime.SnappyRecorder;
import io.quarkus.kafka.client.runtime.devui.KafkaTopicClient;
import io.quarkus.kafka.client.runtime.devui.KafkaUiUtils;
import io.quarkus.kafka.client.runtime.graal.SnappyFeature;
import io.quarkus.kafka.client.serialization.BufferDeserializer;
import io.quarkus.kafka.client.serialization.BufferSerializer;
import io.quarkus.kafka.client.serialization.JsonArrayDeserializer;
Expand Down Expand Up @@ -310,27 +310,14 @@ public void build(
}

@BuildStep(onlyIf = { HasSnappy.class, NativeOrNativeSourcesBuild.class })
public void handleSnappyInNative(NativeImageRunnerBuildItem nativeImageRunner,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
BuildProducer<NativeImageResourceBuildItem> nativeLibs) {
public void handleSnappyInNative(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
BuildProducer<NativeImageFeatureBuildItem> feature) {
reflectiveClass.produce(ReflectiveClassBuildItem.builder("org.xerial.snappy.SnappyInputStream",
"org.xerial.snappy.SnappyOutputStream")
.reason(getClass().getName() + " snappy support")
.methods().fields().build());

String root = "org/xerial/snappy/native/";
// add linux64 native lib when targeting containers
if (nativeImageRunner.isContainerBuild()) {
String dir = "Linux/x86_64";
String snappyNativeLibraryName = "libsnappyjava.so";
String path = root + dir + "/" + snappyNativeLibraryName;
nativeLibs.produce(new NativeImageResourceBuildItem(path));
} else { // otherwise the native lib of the platform this build runs on
String dir = SnappyUtils.getNativeLibFolderPathForCurrentOS();
String snappyNativeLibraryName = System.mapLibraryName("snappyjava");
String path = root + dir + "/" + snappyNativeLibraryName;
nativeLibs.produce(new NativeImageResourceBuildItem(path));
}
feature.produce(new NativeImageFeatureBuildItem(SnappyFeature.class));
}

@BuildStep(onlyIf = HasSnappy.class)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.quarkus.kafka.client.runtime.graal;

import java.io.File;

import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.hosted.RuntimeResourceAccess;
import org.xerial.snappy.OSInfo;

public class SnappyFeature implements Feature {

/**
* This method uses code from org.xerial.snappy.SnappyLoader#findNativeLibrary
* to load the Snappy native library. The original code is licensed under the
* Apache License, Version 2.0 and includes the following notice:
*
* <pre>
*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*--------------------------------------------------------------------------
* </pre>
*/
@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
final String KEY_SNAPPY_LIB_PATH = "org.xerial.snappy.lib.path";
final String KEY_SNAPPY_LIB_NAME = "org.xerial.snappy.lib.name";

// Try to load the library in org.xerial.snappy.lib.path */
String snappyNativeLibraryPath = System.getProperty(KEY_SNAPPY_LIB_PATH);
String snappyNativeLibraryName = System.getProperty(KEY_SNAPPY_LIB_NAME);

// Resolve the library file name with a suffix (e.g., dll, .so, etc.)
if (snappyNativeLibraryName == null) {
snappyNativeLibraryName = System.mapLibraryName("snappyjava");
}

if (snappyNativeLibraryPath != null) {
File nativeLib = new File(snappyNativeLibraryPath, snappyNativeLibraryName);
if (nativeLib.exists()) {
RuntimeResourceAccess.addResource(OSInfo.class.getModule(),
snappyNativeLibraryPath + "/" + snappyNativeLibraryName);
return;
}
}

// Load an OS-dependent native library inside a jar file
snappyNativeLibraryPath = "org/xerial/snappy/native/" + OSInfo.getNativeLibFolderPathForCurrentOS();
String path = snappyNativeLibraryPath + "/" + snappyNativeLibraryName;
RuntimeResourceAccess.addResource(OSInfo.class.getModule(), path);
}

}

0 comments on commit b9ec68c

Please sign in to comment.