Skip to content

Commit

Permalink
Native library: refactored loading of Windows native library from `Fl…
Browse files Browse the repository at this point in the history
…atWindowsNativeWindowBorder` to `FlatNativeLibrary` to make it easier to add native libraries for other platforms (for issues #204 and #482)
  • Loading branch information
DevCharly committed May 17, 2022
1 parent 5f96161 commit 90de14d
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 45 deletions.
@@ -0,0 +1,99 @@
/*
* Copyright 2022 FormDev Software GmbH
*
* 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
*
* https://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.
*/

package com.formdev.flatlaf.ui;

import java.io.File;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.NativeLibrary;
import com.formdev.flatlaf.util.SystemInfo;

/**
* Helper class to load FlatLaf native library (.dll, .so or .dylib),
* if available for current operating system and CPU architecture.
*
* @author Karl Tauber
* @since 2.3
*/
class FlatNativeLibrary
{
private static NativeLibrary nativeLibrary;

/**
* Loads native library (if available) and returns whether loaded successfully.
* Returns {@code false} if no native library is available.
*/
static synchronized boolean isLoaded() {
initialize();
return (nativeLibrary != null) ? nativeLibrary.isLoaded() : false;
}

private static void initialize() {
if( nativeLibrary != null )
return;

String libraryName;
if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64) ) {
// Windows: requires Windows 10 (x86 or x86_64)

libraryName = "flatlaf-windows-x86";
if( SystemInfo.isX86_64 )
libraryName += "_64";

// load jawt native library
loadJAWT();
} else
return; // no native library available for current OS or CPU architecture

// load native library
nativeLibrary = createNativeLibrary( libraryName );
}

private static NativeLibrary createNativeLibrary( String libraryName ) {
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
if( libraryPath != null ) {
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
if( libraryFile.exists() )
return new NativeLibrary( libraryFile, true );
else
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
}

return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
}

private static void loadJAWT() {
if( SystemInfo.isJava_9_orLater )
return;

// In Java 8, load jawt.dll (part of JRE) explicitly because it
// is not found when running application with <jdk>/bin/java.exe.
// When using <jdk>/jre/bin/java.exe, it is found.
// jawt.dll is located in <jdk>/jre/bin/.
// Java 9 and later do not have this problem.
try {
System.loadLibrary( "jawt" );
} catch( UnsatisfiedLinkError ex ) {
// log error only if native library jawt.dll not already loaded
String message = ex.getMessage();
if( message == null || !message.contains( "already loaded in another classloader" ) )
LoggingFacade.INSTANCE.logSevere( null, ex );
} catch( Exception ex ) {
LoggingFacade.INSTANCE.logSevere( null, ex );
}
}
}
Expand Up @@ -27,7 +27,6 @@
import java.awt.geom.AffineTransform;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
Expand All @@ -38,9 +37,7 @@
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.NativeLibrary;
import com.formdev.flatlaf.util.SystemInfo;

//
Expand Down Expand Up @@ -84,7 +81,6 @@ class FlatWindowsNativeWindowBorder
private Color colorizationColor;
private int colorizationColorBalance;

private static NativeLibrary nativeLibrary;
private static FlatWindowsNativeWindowBorder instance;

static FlatNativeWindowBorder.Provider getInstance() {
Expand All @@ -96,31 +92,8 @@ static FlatNativeWindowBorder.Provider getInstance() {
if( !SystemInfo.isX86 && !SystemInfo.isX86_64 )
return null;

// load native library
if( nativeLibrary == null ) {
if( !SystemInfo.isJava_9_orLater ) {
// In Java 8, load jawt.dll (part of JRE) explicitly because it
// is not found when running application with <jdk>/bin/java.exe.
// When using <jdk>/jre/bin/java.exe, it is found.
// jawt.dll is located in <jdk>/jre/bin/.
// Java 9 and later does not have this problem.
try {
System.loadLibrary( "jawt" );
} catch( UnsatisfiedLinkError ex ) {
// log error only if native library jawt.dll not already loaded
String message = ex.getMessage();
if( message == null || !message.contains( "already loaded in another classloader" ) )
LoggingFacade.INSTANCE.logSevere( null, ex );
} catch( Exception ex ) {
LoggingFacade.INSTANCE.logSevere( null, ex );
}
}

nativeLibrary = createNativeLibrary();
}

// check whether native library was successfully loaded
if( !nativeLibrary.isLoaded() )
if( !FlatNativeLibrary.isLoaded() )
return null;

// create new instance
Expand All @@ -129,23 +102,6 @@ static FlatNativeWindowBorder.Provider getInstance() {
return instance;
}

private static NativeLibrary createNativeLibrary() {
String libraryName = "flatlaf-windows-x86";
if( SystemInfo.isX86_64 )
libraryName += "_64";

String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
if( libraryPath != null ) {
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
if( libraryFile.exists() )
return new NativeLibrary( libraryFile, true );
else
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
}

return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
}

private FlatWindowsNativeWindowBorder() {
}

Expand Down

0 comments on commit 90de14d

Please sign in to comment.