Skip to content

Instantly share code, notes, and snippets.

@ezhov-da
Last active March 10, 2019 12:23
Show Gist options
  • Save ezhov-da/0eb4649af1a9d65af320f758bcdb4101 to your computer and use it in GitHub Desktop.
Save ezhov-da/0eb4649af1a9d65af320f758bcdb4101 to your computer and use it in GitHub Desktop.
java dll loader from jar
public interface DllLoader
{
void load() throws Exception;
}
import com.google.inject.Injector;
import java.io.File;
import java.lang.reflect.Field;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.logging.Level;
import java.util.logging.Logger;
import ru.ezhov.plannedsalescalculation.utils.ConfigLocalFile;
import ru.ezhov.plannedsalescalculation.utils.Configurable;
import ru.ezhov.plannedsalescalculation.utils.InjectorHolder;
/**
*
* @author ezhov_da
*/
public class DllLoaderImpl implements DllLoader
{
private static final Logger LOG = Logger.getLogger(DllLoaderImpl.class.getName());
private Injector injector;
private Configurable configLocalFile;
private String pathToTempFolder;
private String nameDll;
private enum Arch
{
X64("/auth/x64"), X86("/auth/x86");
private String path;
private Arch(String path)
{
this.path = path;
}
public String getPath()
{
return path;
}
};
public DllLoaderImpl() throws Exception
{
injector = InjectorHolder.getInstance();
configLocalFile = injector.getInstance(ConfigLocalFile.class);
nameDll = configLocalFile.getValue("dll", "dll.name");
pathToTempFolder = pathToTempFolder();
}
private String pathToTempFolder()
{
String path = System.getProperty("java.io.tmpdir");
LOG.log(Level.INFO, "Путь к временной папке: " + path);
return path;
}
@Override
public void load() throws Exception
{
Arch arch = archSystem();
String pathToFolder = constructPathToDllToUser(arch);
boolean isExistsFolder = checkFolder(pathToFolder);
if (!isExistsFolder)
{
createFolder(pathToFolder);
copyDll(pathToFolder, arch);
}
loadDll(pathToFolder);
}
private Arch archSystem()
{
String ocArch = System.getProperty("sun.arch.data.model");
Arch arch;
if ("64".equals(ocArch))
{
arch = Arch.X64;
LOG.log(Level.INFO, "arch 64");
} else if ("32".equals(ocArch))
{
arch = Arch.X86;
LOG.log(Level.INFO, "arch 32");
} else
{
throw new IllegalArgumentException(
"Not found system arch, find only 64 and 32"
);
}
return arch;
}
private String constructPathToDllToUser(Arch arch)
{
String path = pathToTempFolder + arch.getPath();
return path;
}
private boolean checkFolder(String pathFolder)
{
File file = new File(pathFolder);
return file.exists();
}
private void createFolder(String pathFolder)
{
File file = new File(pathFolder);
file.mkdirs();
}
private void copyDll(String pathFolderUserComputer, Arch arch) throws Exception
{
File fileDllUserDir = new File(pathFolderUserComputer + File.separator + nameDll);
String pathToDllFileInJar = arch.getPath() + File.separator + nameDll;
CopyOption[] options = new CopyOption[]
{
StandardCopyOption.REPLACE_EXISTING,
};
Files.copy(
this.getClass().getResourceAsStream(pathToDllFileInJar),
fileDllUserDir.toPath(),
options
);
}
private void loadDll(String pathToDllFolder)
{
ActiveLibraryPath.setLibraryPath(pathToDllFolder + File.separator + nameDll);
}
private static class ActiveLibraryPath
{
private static final Logger LOG = Logger.getLogger(ActiveLibraryPath.class.getName());
public static final synchronized void setLibraryPath(String path)
{
try
{
System.setProperty("java.library.path", path);
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);
} catch (Exception ex)
{
LOG.log(Level.SEVERE, "error load library path", ex);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment