Skip to content
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
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ dependencies {
}
```

> [!NOTE]
> ### Alternative: Custom Native Library
>
> You can bring your own `libdave` binary by using `-Djdave.library.path=/path/to/libdave.so` as a JVM argument or setting it using `System.setProperty(NativeLibraryLoader.LIBRARY_PATH_PROPERTY, path)` before loading the `LibDave` class.

## Example: JDA

To use this library with [JDA](https://github.com/discord-jda/JDA), you can use the [JDaveSessionFactory](api/src/main/java/club/minnced/discord/jdave/interop/JDaveSessionFactory.java) to configure the audio module:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,27 @@
import java.util.StringJoiner;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NativeLibraryLoader {
public static final String LIBRARY_PATH_PROPERTY = "jdave.library.path";

private static final Logger log = LoggerFactory.getLogger(NativeLibraryLoader.class);

/**
* Returns the path to a local libdave binary, if set.
*
* <p>Uses {@link #LIBRARY_PATH_PROPERTY} to determine the path from system properties.
* If the property is not set, this method returns null.
*
* @return The path to a local libdave binary, or null if not set.
*/
@Nullable
public static String getLibraryPath() {
return System.getProperty(LIBRARY_PATH_PROPERTY);
}

@NonNull
public static NativeLibrary getNativeLibrary() {
return resolveLibrary("dave");
Expand Down Expand Up @@ -46,6 +65,11 @@ public static Path createTemporaryFile() {

@NonNull
public static SymbolLookup getSymbolLookup() {
String customLibraryPath = getLibraryPath();
if (customLibraryPath != null) {
return getSymbolLookupFromPath(customLibraryPath);
}

Path tempFile = createTemporaryFile();
return SymbolLookup.libraryLookup(tempFile, Arena.global());
}
Expand All @@ -68,6 +92,23 @@ public static NativeLibrary resolveLibrary(
return new NativeLibrary(os, arch, baseName);
}

@NonNull
private static SymbolLookup getSymbolLookupFromPath(@NonNull String customLibraryPath) {
Path path = Path.of(customLibraryPath).toAbsolutePath();
log.debug("Loading library from custom path: {}", path);
if (!Files.exists(path)) {
throw new IllegalStateException("Could not find library at path: " + path);
}
if (!Files.isRegularFile(path)) {
throw new IllegalStateException("Path is not a regular file: " + path);
}
if (!Files.isReadable(path)) {
throw new IllegalStateException("Path is not readable: " + path);
}

return SymbolLookup.libraryLookup(path, Arena.global());
}

@NonNull
private static OperatingSystem getOperatingSystem(@NonNull String osName) {
osName = osName.toLowerCase();
Expand Down
Loading