我的 java webstart 应用程序有一个大问题,我尝试了很多解决方案,但最终似乎没有一个能正常工作。
我需要编写一个 webstart 小程序来加载有关客户端计算机的基本硬件信息,以检查我的客户端是否可以连接到我们的系统并使用我们课程的四个软件。我使用 Sigar 加载 CPU 和内存信息,然后使用 JNI 加载一个自定义的 C++ 脚本来检查显卡名称(这个工作完美)。
我已经将我所有的 dll 放在 src/resources 文件夹中以将它们加载到 jar 中,我还使用了我们在这里称为“引擎”的东西,它们被归类为执行指定操作(在我们的例子中,Jni 引擎、配置引擎和数据引擎(下面的代码)),我是 webstart 的新手,所以我不确定这个概念是否适用于库加载。
我尝试将 dll 作为 Netbeans 中的库添加到 jar 中,我尝试在 jnlp 中添加 dll,但每次运行都会重新创建它,我无法使用项目属性添加它们,最后,我已经构建我的数据引擎的方式应该在 java temp 目录中加载 dll,以防它们不存在,但 Sigar 仍然不想工作。我还将我的 dll 正确配置在 java.library.path 中(因为它在本地工作)。
当我在本地运行我的主类时它可以工作(通过右键单击运行),但是当我单击运行按钮加载 webstart 时,它会崩溃并显示此错误消息(它发生在 ConfigEngine 中,因为它扩展了 SigarBase):
JNLPClassLoader:在 java.library.path 中查找库 sigar-amd64-winnt.dll.dll 没有 sigar-amd64-winnt.dll org.hyperic.sigar.SigarException:在 java.library.path 中没有 sigar-amd64-winnt.dll
这是代码:
JNi 引擎(加载显卡的 c++ 代码)
package Engine;
public class JniEngine
{
static private final String nomLibJni = "JniEngine";
static private final String nomLibJni64 = "JniEngine_x64";
static
{
if (System.getProperty("os.arch").contains("86"))
{
System.loadLibrary(nomLibJni);
}
else
{
System.loadLibrary(nomLibJni64);
}
}
public native String getInfoGPU() throws Error;
}
配置引擎
package Engine;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.cmd.SigarCommandBase;
public class ConfigEngine extends SigarCommandBase
{
private final String nomOsAcceptes = "Windows";
static
{
DataEngine data;
}
public ConfigEngine()
{
super();
}
@Override
public void output(String[] args) throws SigarException
{
}
public HashMap<String, String> getMap() throws SigarException, SocketException
{
HashMap<String, String> hmConfig = new HashMap<>();
loadInfoCpu(hmConfig);
loadInfoRam(hmConfig);
loadInfoOs(hmConfig);
loadInfoNet(hmConfig);
loadInfoGpu(hmConfig);
return hmConfig;
}
private void loadInfoCpu(HashMap<String,String> Hashmap) throws SigarException
{
org.hyperic.sigar.CpuInfo[] configCpu = this.sigar.getCpuInfoList();
org.hyperic.sigar.CpuInfo infoCpu = configCpu[0];
long cacheSize = infoCpu.getCacheSize();
Hashmap.put("Builder", infoCpu.getVendor());
Hashmap.put("Model" , infoCpu.getModel());
Hashmap.put("Mhz", String.valueOf(infoCpu.getMhz()));
Hashmap.put("Cpus nbr", String.valueOf(infoCpu.getTotalCores()));
if ((infoCpu.getTotalCores() != infoCpu.getTotalSockets()) ||
(infoCpu.getCoresPerSocket() > infoCpu.getTotalCores()))
{
Hashmap.put("Cpus", String.valueOf(infoCpu.getTotalSockets()));
Hashmap.put("Core", String.valueOf(infoCpu.getCoresPerSocket()));
}
if (cacheSize != Sigar.FIELD_NOTIMPL) {
Hashmap.put("Cache", String.valueOf(cacheSize));
}
}
private void loadInfoRam(HashMap<String,String> Hashmap) throws SigarException
{
org.hyperic.sigar.Mem mem = this.sigar.getMem();
Hashmap.put("RAM" , String.valueOf(mem.getRam()));
Hashmap.put("Memoery", String.valueOf(mem.getTotal()));
Hashmap.put("Free", String.valueOf(mem.getUsed()));
}
private void loadInfoOs(HashMap<String,String> Hashmap) throws SigarException
{
Hashmap.put("OS", System.getProperty("os.name"));
Hashmap.put("Version", System.getProperty("os.version"));
Hashmap.put("Arch", System.getProperty("os.arch"));
}
private void loadInfoNet(HashMap<String,String> Hashmap) throws SocketException
{
List<NetworkInterface> interfaces = Collections.
list(NetworkInterface.getNetworkInterfaces());
int i = 1;
for (NetworkInterface net : interfaces)
{
if (!net.isVirtual() && net.isUp())
{
Hashmap.put("Port Name " + String.valueOf(i), net.getDisplayName());
}
i++;
}
}
private void loadInfoGpu(HashMap<String,String> Hashmap) throws SocketException
{
if (System.getProperty("os.name").contains(nomOsAcceptes))
{
JniEngine Jni = new JniEngine();
Hashmap.put("VGA", Jni.getInfoGPU());
}
}
}
最后,我的数据引擎尝试加载所有 dll 并更改库路径(其中大部分是临时的,因为它是补丁上的补丁)
package Engine;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
public class DataEngine
{
static private final String nomLibSigar = "sigar-x86-winnt";
static private final String nomLibSigar64 = "sigar-amd64-winnt";
static private final String nomLibJni = "JniEngine";
static private final String nomLibJni64 = "JniEngine_x64";
static private final String NomJar86 = "lib_config_x86";
static private final String nomJar64 = "lib_config_x64";
static private final String path = "Resources\\";
static
{
try
{
if (System.getProperty("os.arch").contains("86"))
{
System.loadLibrary(nomLibJni);
System.loadLibrary(nomLibSigar);
}
else
{
System.loadLibrary(nomLibJni64);
System.loadLibrary(nomLibSigar64);
}
}
catch (UnsatisfiedLinkError ex)
{
loadJniFromJar();
loadSigarFromJar();
}
}
public static void loadSigarFromJar()
{
try
{
File dll;
InputStream is;
if (System.getProperty("os.arch").contains("86"))
{
is = DataEngine.class.getResourceAsStream(
path + nomLibSigar + ".dll");
dll = File.createTempFile(path + nomLibSigar, ".dll");
}
else
{
is = DataEngine.class.getResourceAsStream(
path + nomLibSigar64 + ".dll");
dll = File.createTempFile(path + nomLibSigar64, ".dll");
}
FileOutputStream fos = new FileOutputStream(dll);
byte[] array = new byte[1024];
for (int i = is.read(array);
i != -1;
i = is.read(array))
{
fos.write(array, 0, i);
}
fos.close();
is.close();
System.load(dll.getAbsolutePath());
System.setProperty("java.library.path", dll.getAbsolutePath());
}
catch (Throwable e)
{
}
}
public static void loadJniFromJar()
{
try
{
File dll;
InputStream is;
if (System.getProperty("os.arch").contains("86"))
{
is = DataEngine.class.getResourceAsStream(
path + nomLibJni + ".dll");
dll = File.createTempFile(path + nomLibJni, ".dll");
}
else
{
is = DataEngine.class.getResourceAsStream(
path + nomLibJni64 + ".dll");
dll = File.createTempFile(path + nomLibJni64, ".dll");
}
FileOutputStream fos = new FileOutputStream(dll);
byte[] array = new byte[1024];
for (int i = is.read(array);
i != -1;
i = is.read(array))
{
fos.write(array, 0, i);
}
fos.close();
is.close();
System.load(dll.getAbsolutePath());
}
catch (Throwable e)
{
}
}
}
我的主类也有一些问题(NetBeans 不希望我的 JAppletForm 成为我项目的主类,但我可能会重新创建项目,因为我尝试的数百个补丁破坏了构建。我的主类只需使用 ConfigEngine 的 GetMap 加载 HashMap 并在本地显示它,如果它使用 webstart 运行,则在 JAppletForm 中显示它。
这是一个很大的问题,所以如果被问到,我会用你需要的所有信息来更新我的问题。