JNI UnsatisfiedLinkError when using native function

问题描述 投票:0回答:0

我有一种使用一些外部库执行某些操作的方法。
为此,我定义了一个接口

IMethod
和一个抽象类
AMethod

public interface IMethod {
    /**
     * Get a level by a certain method.
     *
     * @return The level obtained using this method.
     * @throws MethodUndefinedResultException If an error occurred in the method while obtaining the level.
     */
    Level getLevel() throws MethodUndefinedResultException;

    /**
     * Get method type.
     *
     * @return Enum method value.
     */
    Method getMethod();
}
abstract class ALibrary implements IMethod {
    private final Logger log = LoggerWrapper.getLogger();
    private final Library library;

    public ALibrary(Library library) {
        this.library = library;
    }

    @Override
    public Level getLevel() throws MethodUndefinedResultException {
        try {
            linkWithLibrary();
            String nativeCallResult = makeNativeCall();
            return parseNativeCallResult(nativeCallResult);
        } catch (LibraryResolveException | LibraryNativeCallException | LibraryParsingException e) {
            log.error(e.getMessage());
            throw new MethodUndefinedResultException(library.getMethod(), e);
        }
    }

    @Override
    public Method getMethod() {
        return library.getMethod();
    }

    /**
     * Link with library for the native method.
     *
     * @throws LibraryResolveException If library is not available.
     */
    private void linkWithLibrary() throws LibraryResolveException {
        try {
            System.loadLibrary(library.getLibraryName());
        } catch (Throwable e) {
            log.error(e.getMessage());
            throw new LibraryResolveException(library, e);
        }
    }

    /**
     * Make native call for the level.
     *
     * @return Result of the native call.
     * @throws LibraryNativeCallException If the result does not contain a level.
     */
    protected abstract String makeNativeCall() throws LibraryNativeCallException;

    /**
     * Parse library native call result to the level.
     *
     * @param nativeCallResult Result of the native call.
     * @return Parsed level value.
     * @throws LibraryParsingException If the result of the native method call could not be parsed.
     */
    protected abstract Level parseNativeCallResult(String nativeCallResult)
            throws LibraryParsingException;
}

在此之后,我实现了测试类

TestMethod
,它扩展了
AMethod
并实现了
IMethod

public class TestLibrary extends ALibrary implements IMethod {
    private static final Library LIBRARY = Library.Test;

    private final Logger log = LoggerWrapper.getLogger();

    public TestLibrary() {
        super(LIBRARY);
    }

    /**
     * A native method of the Test library that returns level.
     *
     * @return Level in numeric format.
     */
    private native String getlvl();

    @Override
    protected String makeNativeCall() throws LibraryNativeCallException {
        try {
            return new TestLibrary().getlvl();
        } catch (Throwable e) {
            log.error(e.getMessage());
            throw new LibraryNativeCallException(LIBRARY);
        }
    }

    @Override
    protected Level parseNativeCallResult(String nativeCallResult) throws LibraryParsingException {
        log.info(nativeCallResult);
        // TODO: Test with lib and remove stub
        throw new LibraryParsingException(LIBRARY, null);
    }
}

并将其用作:

IMethod testMethod = new TestLibrary();
testMethod.getLevel();

但是我在

UnsatisfiedLinkError
类的
getlvl()
方法中从
makeNativeCall()
得到了
TestMethod
导致
LibraryNativeCallException
.

但是当我做类似的事情时:

public class TestMethod {
    public native String getlvl();

    static {
        System.loadLibrary(Library.Test.getLibraryName());
    }

    public String getLevel() throws UnsatisfiedLinkError {
        return new TestMethod().getlvl();
    }
}

一切正常。在我看来,抽象类存在某种问题,但我无法弄清楚它是什么。我想修复新代码并删除旧代码。

你能帮忙吗?

java java-native-interface
© www.soinside.com 2019 - 2024. All rights reserved.