mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-07 06:20:53 +03:00
Native libraries: support loading via System.loadLibrary()
(for pre-extracted native libs in NetBeans)
This commit is contained in:
@@ -3,6 +3,11 @@ FlatLaf Change Log
|
|||||||
|
|
||||||
## 3.0-SNAPSHOT
|
## 3.0-SNAPSHOT
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- If value of system property `flatlaf.nativeLibraryPath` is `system`, then
|
||||||
|
`System.loadLibrary(String)` is used to load the native library.
|
||||||
|
|
||||||
#### Fixed bugs
|
#### Fixed bugs
|
||||||
|
|
||||||
- ComboBox and Spinner: Fixed missing arrow buttons if preferred height is zero.
|
- ComboBox and Spinner: Fixed missing arrow buttons if preferred height is zero.
|
||||||
|
|||||||
@@ -155,9 +155,19 @@ public interface FlatSystemProperties
|
|||||||
String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange";
|
String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies a directory in which the native FlatLaf library have been extracted.
|
* Specifies a directory in which the native FlatLaf libraries have been extracted.
|
||||||
* The path can be absolute or relative to current application working directory.
|
* The path can be absolute or relative to current application working directory.
|
||||||
* This can be used to avoid extraction of the native libraries to the temporary directory at runtime.
|
* This can be used to avoid extraction of the native libraries to the temporary directory at runtime.
|
||||||
|
* <p>
|
||||||
|
* If the value is {@code "system"}, then {@link System#loadLibrary(String)} is
|
||||||
|
* used to load the native library.
|
||||||
|
* Searches for the native library in classloader of caller
|
||||||
|
* (using {@link ClassLoader#findLibrary(String)}) and in paths specified
|
||||||
|
* in system properties {@code sun.boot.library.path} and {@code java.library.path}.
|
||||||
|
* (supported since FlatLaf 3)
|
||||||
|
* <p>
|
||||||
|
* If the native library can not loaded from the given path (or via {@link System#loadLibrary(String)}),
|
||||||
|
* then the embedded native library is extracted to the temporary directory and loaded from there.
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -84,11 +84,19 @@ class FlatNativeLibrary
|
|||||||
private static NativeLibrary createNativeLibrary( String libraryName ) {
|
private static NativeLibrary createNativeLibrary( String libraryName ) {
|
||||||
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
||||||
if( libraryPath != null ) {
|
if( libraryPath != null ) {
|
||||||
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
if( "system".equals( libraryPath ) ) {
|
||||||
if( libraryFile.exists() )
|
NativeLibrary library = new NativeLibrary( libraryName, true );
|
||||||
return new NativeLibrary( libraryFile, true );
|
if( library.isLoaded() )
|
||||||
else
|
return library;
|
||||||
|
|
||||||
|
LoggingFacade.INSTANCE.logSevere( "Did not find library " + libraryName + " in java.library.path, using extracted library instead", null );
|
||||||
|
} else {
|
||||||
|
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
||||||
|
if( libraryFile.exists() )
|
||||||
|
return new NativeLibrary( libraryFile, true );
|
||||||
|
|
||||||
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
||||||
@@ -101,9 +109,9 @@ class FlatNativeLibrary
|
|||||||
// log error only if native library jawt.dll not already loaded
|
// log error only if native library jawt.dll not already loaded
|
||||||
String message = ex.getMessage();
|
String message = ex.getMessage();
|
||||||
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( message, ex );
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,22 @@ public class NativeLibrary
|
|||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native library using {@link System#loadLibrary(String)}.
|
||||||
|
* Searches for the library in classloader of caller
|
||||||
|
* (using {@link ClassLoader#findLibrary(String)}) and in paths specified
|
||||||
|
* in system properties {@code sun.boot.library.path} and {@code java.library.path}.
|
||||||
|
*
|
||||||
|
* @param libraryName name of the native library (without "lib" prefix and without extension)
|
||||||
|
* @param supported whether the native library is supported on the current platform
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public NativeLibrary( String libraryName, boolean supported ) {
|
||||||
|
this.loaded = supported
|
||||||
|
? loadLibraryFromSystem( libraryName )
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the native library is loaded.
|
* Returns whether the native library is loaded.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -92,7 +108,7 @@ public class NativeLibrary
|
|||||||
? classLoader.getResource( libraryName )
|
? classLoader.getResource( libraryName )
|
||||||
: NativeLibrary.class.getResource( "/" + libraryName );
|
: NativeLibrary.class.getResource( "/" + libraryName );
|
||||||
if( libraryUrl == null ) {
|
if( libraryUrl == null ) {
|
||||||
log( "Library '" + libraryName + "' not found", null );
|
LoggingFacade.INSTANCE.logSevere( "Library '" + libraryName + "' not found", null );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +141,7 @@ public class NativeLibrary
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch( Throwable ex ) {
|
} catch( Throwable ex ) {
|
||||||
log( null, ex );
|
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||||
|
|
||||||
if( tempFile != null )
|
if( tempFile != null )
|
||||||
deleteOrMarkForDeletion( tempFile );
|
deleteOrMarkForDeletion( tempFile );
|
||||||
@@ -138,7 +154,24 @@ public class NativeLibrary
|
|||||||
System.load( libraryFile.getAbsolutePath() );
|
System.load( libraryFile.getAbsolutePath() );
|
||||||
return true;
|
return true;
|
||||||
} catch( Throwable ex ) {
|
} catch( Throwable ex ) {
|
||||||
log( ex.getMessage(), ex );
|
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean loadLibraryFromSystem( String libraryName ) {
|
||||||
|
try {
|
||||||
|
System.loadLibrary( libraryName );
|
||||||
|
return true;
|
||||||
|
} catch( Throwable ex ) {
|
||||||
|
String message = ex.getMessage();
|
||||||
|
|
||||||
|
// do not log error if library was not found
|
||||||
|
// thrown in ClassLoader.loadLibrary(Class<?> fromClass, String name, boolean isAbsolute)
|
||||||
|
if( ex instanceof UnsatisfiedLinkError && message != null && message.contains( "java.library.path" ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LoggingFacade.INSTANCE.logSevere( message, ex );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,10 +191,6 @@ public class NativeLibrary
|
|||||||
: System.mapLibraryName( libraryName );
|
: System.mapLibraryName( libraryName );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void log( String msg, Throwable thrown ) {
|
|
||||||
LoggingFacade.INSTANCE.logSevere( msg, thrown );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Path createTempFile( String libraryName ) throws IOException {
|
private static Path createTempFile( String libraryName ) throws IOException {
|
||||||
int sep = libraryName.lastIndexOf( '/' );
|
int sep = libraryName.lastIndexOf( '/' );
|
||||||
String name = (sep >= 0) ? libraryName.substring( sep + 1 ) : libraryName;
|
String name = (sep >= 0) ? libraryName.substring( sep + 1 ) : libraryName;
|
||||||
|
|||||||
Reference in New Issue
Block a user