java.lang.UnsatisfiedLinkError:no jhdf5 in java.library.path问题的解决

本文详述了使用MyEclipse与HDF5 Java API进行HDF文件读写的步骤,包括配置环境变量、添加依赖库及解决java.lang.UnsatisfiedLinkError等问题,并附带完整代码示例。

笔者在MyEclipse中进行HDF文件的读写,遇到了java.lang.UnsatisfiedLinkError:no jhdf5 in java.library.path的问题。笔者详细地记录了整个过程,如只需此问题的解决,可跳过前面部分直接找该问题解决方法。

1.MyEclipse新建Java工程,命名为HDF_Dataset

2.添加所需jar包  jarhdf5-3.2.1.jar  slf4j-api-1.7.5.jar    slf4j-nop-1.7.5.jar

工程名右键选择新建文件夹,命名为lib

将三个jar包拷贝到lib下

jar包右键--Build Path--Add to Build Path

3.编辑代码

新建Class文件,命名为H5Ex_D_ReadWrite,放到包examples.datasets

代码如下:

package examples.datasets;

import hdf.hdf5lib.H5;
import hdf.hdf5lib.HDF5Constants;

public class H5Ex_D_ReadWrite {
	private static String FILENAME = "/home/hadoop/Documents/HDF5/test.h5";
	private static String DATASETNAME = "DS1";
	private static final int DIM_X = 4;
	private static final int DIM_Y = 7;
	private static final int RANK = 2;

	private static void WriteDataset() {
		int file_id = -1;
		int filespace_id = -1;
		int dataset_id = -1;
		long[] dims = { DIM_X, DIM_Y };
		int[][] dset_data = new int[DIM_X][DIM_Y];

		// Initialize data.
		for (int indx = 0; indx < DIM_X; indx++)
			for (int jndx = 0; jndx < DIM_Y; jndx++)
				dset_data[indx][jndx] = indx * jndx - jndx;

		// Create a new file using default properties.
		try {
			file_id = H5.H5Fcreate(FILENAME, HDF5Constants.H5F_ACC_TRUNC,   //创建文件,指定文件名,文件存取模式,文件创建特性列表,文件存取特性列表
					HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);  
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		// Create dataspace. Setting maximum size to NULL sets the maximum
		// size to be the current size.
		try {                         //H5Screate_simple新建一个数据空间并打开它等待接收数据 
			filespace_id = H5.H5Screate_simple(RANK, dims, null);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		// Create the dataset. We will use all default properties for this example.
		try {
			if ((file_id >= 0) && (filespace_id >= 0))        //H5Dcreate 新建一个数据集file_id
				dataset_id = H5.H5Dcreate(file_id, DATASETNAME,
						HDF5Constants.H5T_STD_I32LE, filespace_id,
						HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		// Write the data to the dataset.
		try {
			if (dataset_id >= 0)     //H5.H5Dwrite将dset_data中的数据对象写入文件中
				H5.H5Dwrite(dataset_id, HDF5Constants.H5T_NATIVE_INT,
						HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
						HDF5Constants.H5P_DEFAULT, dset_data);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		// End access to the dataset and release resources used by it.
		try {
			if (dataset_id >= 0)
				H5.H5Dclose(dataset_id); //关闭数据集
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		try {
			if (filespace_id >= 0)
				H5.H5Sclose(filespace_id); //释放数据空间
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		// Close the file.
		try {
			if (file_id >= 0)
				H5.H5Fclose(file_id);//关闭文件,写操作结束
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void ReadDataset() {
		int file_id = -1;
		int dataset_id = -1;
		int[][] dset_data = new int[DIM_X][DIM_Y];

		// Open file using the default properties.
		try {              //H5.H5Fopen打开一个已存在的文件
			file_id = H5.H5Fopen(FILENAME, HDF5Constants.H5F_ACC_RDWR, 
					HDF5Constants.H5P_DEFAULT);  
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		// Open dataset using the default properties.
		try {
			if (file_id >= 0)       //H5.H5Dopen打开数据集
				dataset_id = H5.H5Dopen(file_id, DATASETNAME, HDF5Constants.H5P_DEFAULT);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		// Read the data using the default properties.
		try {
			if (dataset_id >= 0)   //H5Dread读数据到dset_data中
				H5.H5Dread(dataset_id, HDF5Constants.H5T_NATIVE_INT,
						HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
						HDF5Constants.H5P_DEFAULT, dset_data);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		// Output the data to the screen.
		System.out.println(DATASETNAME + ":");
		for (int indx = 0; indx < DIM_X; indx++) {
			System.out.print(" [ ");
			for (int jndx = 0; jndx < DIM_Y; jndx++)
				System.out.print(dset_data[indx][jndx] + " ");
			System.out.println("]");
		}
		System.out.println();

		// Close the dataset.
		try {
			if (dataset_id >= 0)
				H5.H5Dclose(dataset_id);
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		// Close the file.
		try {
			if (file_id >= 0)
				H5.H5Fclose(file_id);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		H5Ex_D_ReadWrite.WriteDataset();
		H5Ex_D_ReadWrite.ReadDataset();
	}

}

注意:此时运行,会报出java.lang.UnsatisfiedLinkError: no jhdf5 in java.library.path错误,如图


根据错误类型java.lang.UnsatisfiedLinkError,我们知道这是Link错误,即程序运行时找不到链接库。因此还需要一步:

4.add the HDF5 JNI library to your path

在Linux中,需要的是so文件;Windows中是dll文件

在命令行下,Linux通过设置LD_LIBRARY_PATH,Windows设置PATH 参考:https://support.hdfgroup.org/products/java/release/download.html#script 截图如下:

重点说在MyEclipse中:

Run---Run Configurations

设置Arguments--VM arguments:-Djava.library.path=libjhdf5.so文件所在目录,然后点击右下角Run 运行即可。

再运行,就会得到正确结果:

在/home/hadoop/Documents/HDF5下可以看到test.h5文件

用HDFView可以查看该文件:


补充:

文件下载:

https://support.hdfgroup.org/products/java/release/download.html#bldsrc中下载HDFJava 3.2.1

解压缩之后运行.sh文件

在lib文件夹中有要用到的jar包和libjhd5.so 。注意,将下图中的libjhdf5.so.3.2.1拷贝到指定文件夹(/home/hadoop/Documents/linux)改名!改名为libjhd5.so

注意:

要用新版jar包,旧版jar包有ncsa前缀,新版没有。

旧版:

import ncsa.hdf.hdf5lib.H5;

import ncsa.hdf.hdf5lib.HDF5Constants;

而最新的jar包没有ncsa,即:

import hdf.hdf5lib.H5;

import hdf.hdf5lib.HDF5Constants;

笔者很详细地记录了整个过程,因为解决java.lang.UnsatisfiedLinkError着实费了很多功夫,因为用的是旧版jar包和新版libjhdf5.so文件,一直没成功,后来想到了这个原因,解决了问题。

也可以直接下载需要的三个jar包和so文件:

http://download.youkuaiyun.com/detail/luoying_1993/9866509

`java.lang.UnsatisfiedLinkError: no FCCJavaClientProxyv16064 in java.library.path` 异常表明 Java 无法在 `java.library.path` 指定的路径中找到名为 `FCCJavaClientProxyv16064.dll` 的本地库文件。尽管该 DLL 文件可能存在于系统中,但由于多种原因,JVM 无法正确加载它。以下是解决问题的详细方法: ### 1. 确认 `java.library.path` 的值 首先,打印当前运行时的 `java.library.path` 值,以确认 JVM 实际搜索的路径: ```java System.out.println("java.library.path: " + System.getProperty("java.library.path")); ``` 该路径通常包括系统环境变量 `PATH` 中的目录。确保 `FCCJavaClientProxyv16064.dll` 所在的目录包含在其中。 ### 2. 将 DLL 文件所在目录添加到 `java.library.path` 如果 DLL 文件不在默认的 `java.library.path` 中,可以通过启动参数手动指定路径: ```bash java -Djava.library.path="C:\path\to\dll" -jar yourApp.jar ``` 其中 `C:\path\to\dll` 是 `FCCJavaClientProxyv16064.dll` 所在的目录。 ### 3. 使用 `System.load()` 替代 `System.loadLibrary()` 如果无法将 DLL 所在路径加入 `java.library.path`,可以使用绝对路径加载 DLL: ```java System.load("C:\\full\\path\\to\\FCCJavaClientProxyv16064.dll"); ``` 这种方式绕过了 `java.library.path` 的限制,适用于调试或部署时路径固定的场景。 ### 4. 检查 DLL 文件的兼容性 确保 `FCCJavaClientProxyv16064.dll` 与当前 JVM 的架构匹配(即 64 位 JVM 需要 64 位 DLL,32 位 JVM 需要 32 位 DLL)。 ### 5. 检查 DLL 文件是否依赖其他库 使用工具如 [Dependency Walker](http://www.dependencywalker.com/) 检查 `FCCJavaClientProxyv16064.dll` 是否缺少依赖项。如果存在缺失的依赖库,即使 DLL 本身存在,也无法加载。 ### 6. 设置系统环境变量 `PATH` 将 DLL 所在目录添加到系统的 `PATH` 环境变量中。这样 JVM 在查找本地库时会自动包含该路径。 ### 7. 检查文件权限和路径中的空格/特殊字符 确保 JVM 有权限访问该 DLL 文件,并且路径中没有非法字符或空格。建议使用短路径(如 `C:\dlls`)以避免问题。 ### 示例代码:加载本地库 ```java public class NativeLoader { static { // 方法一:使用 loadLibrary(需确保 dll 在 java.library.path 中) System.loadLibrary("FCCJavaClientProxyv16064"); // 方法二:使用绝对路径加载 // System.load("C:\\dlls\\FCCJavaClientProxyv16064"); } public native void someNativeMethod(); public static void main(String[] args) { new NativeLoader().someNativeMethod(); } } ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值