Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8630eab

Browse files
committed
simplify native library loader
1 parent fd1b062 commit 8630eab

File tree

1 file changed

+59
-167
lines changed

1 file changed

+59
-167
lines changed

src/main/java/de/kherud/llama/LlamaLoader.java

Lines changed: 59 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import java.nio.file.StandardCopyOption;
2727
import java.util.LinkedList;
2828
import java.util.List;
29-
import java.util.UUID;
3029
import java.util.stream.Stream;
3130

3231
import org.jetbrains.annotations.Nullable;
@@ -94,176 +93,69 @@ private static void cleanPath(Path path) {
9493
}
9594

9695
private static void loadNativeLibrary(String name) {
97-
List<String> triedPaths = new LinkedList<>();
98-
boolean isDebug = System.getProperty("debug.native.loading", "false").equals("true");
99-
100-
if (isDebug) {
101-
System.out.println("[DEBUG] Attempting to load native library: " + name);
102-
System.out.println("[DEBUG] Current working directory: " + System.getProperty("user.dir"));
103-
System.out.println("[DEBUG] java.library.path: " + System.getProperty("java.library.path", ""));
104-
System.out.println("[DEBUG] PATH environment: " + System.getenv("PATH"));
105-
}
96+
List<String> triedPaths = new LinkedList<>();
10697

107-
String nativeLibName = System.mapLibraryName(name);
108-
if (isDebug) {
109-
System.out.println("[DEBUG] Mapped library name: " + nativeLibName);
110-
}
111-
112-
String nativeLibPath = System.getProperty("de.kherud.llama.lib.path");
113-
if (nativeLibPath != null) {
114-
Path path = Paths.get(nativeLibPath, nativeLibName);
115-
if (isDebug) {
116-
System.out.println("[DEBUG] Trying custom lib path: " + path);
117-
}
118-
if (loadNativeLibraryWithDebug(path, isDebug)) {
119-
return;
120-
} else {
121-
triedPaths.add(nativeLibPath);
122-
}
123-
}
124-
125-
if (OSInfo.isAndroid()) {
126-
try {
127-
if (isDebug) {
128-
System.out.println("[DEBUG] Android detected, trying System.loadLibrary directly");
129-
}
130-
// loadLibrary can load directly from packed apk file automatically
131-
// if java-llama.cpp is added as code source
132-
System.loadLibrary(name);
133-
return;
134-
} catch (UnsatisfiedLinkError e) {
135-
if (isDebug) {
136-
System.out.println("[DEBUG] Failed to load from APK: " + e.getMessage());
137-
}
138-
triedPaths.add("Directly from .apk/lib");
139-
}
140-
}
141-
142-
// Try to load the library from java.library.path
143-
String javaLibraryPath = System.getProperty("java.library.path", "");
144-
for (String ldPath : javaLibraryPath.split(File.pathSeparator)) {
145-
if (ldPath.isEmpty()) {
146-
continue;
147-
}
148-
Path path = Paths.get(ldPath, nativeLibName);
149-
if (isDebug) {
150-
System.out.println("[DEBUG] Trying java.library.path entry: " + path);
151-
if (Files.exists(path)) {
152-
System.out.println("[DEBUG] File exists at path: " + path);
153-
} else {
154-
System.out.println("[DEBUG] File does NOT exist at path: " + path);
155-
}
156-
}
157-
if (loadNativeLibraryWithDebug(path, isDebug)) {
158-
return;
159-
} else {
160-
triedPaths.add(ldPath);
161-
}
162-
}
163-
164-
// As a last resort try load the os-dependent library from the jar file
165-
nativeLibPath = getNativeResourcePath();
166-
if (isDebug) {
167-
System.out.println("[DEBUG] Trying to extract from JAR, native resource path: " + nativeLibPath);
168-
}
169-
170-
if (hasNativeLib(nativeLibPath, nativeLibName)) {
171-
// temporary library folder
172-
String tempFolder = getTempDir().getAbsolutePath();
173-
if (isDebug) {
174-
System.out.println("[DEBUG] Extracting library to temp folder: " + tempFolder);
175-
}
176-
177-
// Try extracting the library from jar
178-
if (extractAndLoadLibraryFileWithDebug(nativeLibPath, nativeLibName, tempFolder, isDebug)) {
179-
return;
180-
} else {
181-
triedPaths.add(nativeLibPath);
182-
}
183-
} else if (isDebug) {
184-
System.out.println("[DEBUG] Native library not found in JAR at path: " + nativeLibPath + "/" + nativeLibName);
185-
}
98+
String nativeLibName = System.mapLibraryName(name);
99+
String nativeLibPath = System.getProperty("de.kherud.llama.lib.path");
100+
if (nativeLibPath != null) {
101+
Path path = Paths.get(nativeLibPath, nativeLibName);
102+
if (loadNativeLibrary(path)) {
103+
return;
104+
}
105+
else {
106+
triedPaths.add(nativeLibPath);
107+
}
108+
}
186109

187-
throw new UnsatisfiedLinkError(
188-
String.format(
189-
"No native library found for name=%s os.name=%s, os.arch=%s, paths=[%s]",
190-
name,
191-
OSInfo.getOSName(),
192-
OSInfo.getArchName(),
193-
String.join(File.pathSeparator, triedPaths)
194-
)
195-
);
196-
}
110+
if (OSInfo.isAndroid()) {
111+
try {
112+
// loadLibrary can load directly from packed apk file automatically
113+
// if java-llama.cpp is added as code source
114+
System.loadLibrary(name);
115+
return;
116+
}
117+
catch (UnsatisfiedLinkError e) {
118+
triedPaths.add("Directly from .apk/lib");
119+
}
120+
}
197121

198-
// Add these helper methods
122+
// Try to load the library from java.library.path
123+
String javaLibraryPath = System.getProperty("java.library.path", "");
124+
for (String ldPath : javaLibraryPath.split(File.pathSeparator)) {
125+
if (ldPath.isEmpty()) {
126+
continue;
127+
}
128+
Path path = Paths.get(ldPath, nativeLibName);
129+
if (loadNativeLibrary(path)) {
130+
return;
131+
}
132+
else {
133+
triedPaths.add(ldPath);
134+
}
135+
}
199136

200-
private static boolean loadNativeLibraryWithDebug(Path path, boolean isDebug) {
201-
try {
202-
if (isDebug) {
203-
System.out.println("[DEBUG] Attempting to load: " + path.toAbsolutePath());
204-
}
205-
206-
if (!Files.exists(path)) {
207-
if (isDebug) System.out.println("[DEBUG] File doesn't exist: " + path);
208-
return false;
209-
}
210-
211-
System.load(path.toAbsolutePath().toString());
212-
if (isDebug) System.out.println("[DEBUG] Successfully loaded: " + path);
213-
return true;
214-
} catch (UnsatisfiedLinkError e) {
215-
if (isDebug) {
216-
System.out.println("[DEBUG] Failed to load " + path + ": " + e.getMessage());
217-
e.printStackTrace();
218-
}
219-
return false;
220-
}
221-
}
137+
// As a last resort try load the os-dependent library from the jar file
138+
nativeLibPath = getNativeResourcePath();
139+
if (hasNativeLib(nativeLibPath, nativeLibName)) {
140+
// temporary library folder
141+
String tempFolder = getTempDir().getAbsolutePath();
142+
// Try extracting the library from jar
143+
if (extractAndLoadLibraryFile(nativeLibPath, nativeLibName, tempFolder)) {
144+
return;
145+
}
146+
else {
147+
triedPaths.add(nativeLibPath);
148+
}
149+
}
222150

223-
private static boolean extractAndLoadLibraryFileWithDebug(String libFolderForCurrentOS, String libraryFileName,
224-
String targetFolder, boolean isDebug) {
225-
String nativeLibraryFilePath = libFolderForCurrentOS + "/" + libraryFileName;
226-
227-
// Include architecture name in temporary filename to avoid naming conflicts
228-
String uuid = UUID.randomUUID().toString();
229-
String extractedLibFileName = String.format("%s-%s-%s", libraryFileName, uuid, OSInfo.getArchName());
230-
File extractedLibFile = new File(targetFolder, extractedLibFileName);
231-
232-
try (InputStream reader = LlamaLoader.class.getResourceAsStream(nativeLibraryFilePath)) {
233-
if (isDebug) {
234-
System.out.println("[DEBUG] Extracting native library from JAR: " + nativeLibraryFilePath);
235-
}
236-
237-
if (reader == null) {
238-
if (isDebug) System.out.println("[DEBUG] Cannot find native library in JAR: " + nativeLibraryFilePath);
239-
return false;
240-
}
241-
242-
Files.copy(reader, extractedLibFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
243-
244-
if (isDebug) {
245-
System.out.println("[DEBUG] Extracted to: " + extractedLibFile.getAbsolutePath());
246-
System.out.println("[DEBUG] Attempting to load extracted file");
247-
}
248-
249-
try {
250-
System.load(extractedLibFile.getAbsolutePath());
251-
if (isDebug) System.out.println("[DEBUG] Successfully loaded: " + extractedLibFile.getAbsolutePath());
252-
return true;
253-
} catch (UnsatisfiedLinkError e) {
254-
if (isDebug) {
255-
System.out.println("[DEBUG] Failed to load extracted library: " + e.getMessage());
256-
e.printStackTrace();
257-
}
258-
return false;
259-
}
260-
} catch (IOException e) {
261-
if (isDebug) {
262-
System.out.println("[DEBUG] Failed to extract library: " + e.getMessage());
263-
e.printStackTrace();
264-
}
265-
return false;
266-
}
151+
throw new UnsatisfiedLinkError(
152+
String.format(
153+
"No native library found for os.name=%s, os.arch=%s, paths=[%s]",
154+
OSInfo.getOSName(),
155+
OSInfo.getArchName(),
156+
String.join(File.pathSeparator, triedPaths)
157+
)
158+
);
267159
}
268160

269161
/**
@@ -272,7 +164,7 @@ private static boolean extractAndLoadLibraryFileWithDebug(String libFolderForCur
272164
* @param path path of the native library
273165
* @return true for successfully loading, otherwise false
274166
*/
275-
private static boolean loadNativeLibrary(Path path) {
167+
public static boolean loadNativeLibrary(Path path) {
276168
if (!Files.exists(path)) {
277169
return false;
278170
}

0 commit comments

Comments
 (0)