我有一种使用一些外部库执行某些操作的方法。
为此,我定义了一个接口
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();
}
}
一切正常。在我看来,抽象类存在某种问题,但我无法弄清楚它是什么。我想修复新代码并删除旧代码。
你能帮忙吗?