in sdk/host/src/main/java/org/apache/teaclave/javasdk/host/AbstractEnclave.java [96:141]
<T> Iterator<T> loadProxyService(Class<?> service) throws ServicesLoadingException {
if (!getEnclaveContext().getEnclaveToken().tryAcquireToken()) {
throw new ServicesLoadingException("enclave was destroyed.");
}
try (MetricTraceContext trace = new MetricTraceContext(
this.getEnclaveInfo(),
MetricTraceContext.LogPrefix.METRIC_LOG_ENCLAVE_SERVICE_LOADING_PATTERN,
service.getName())) {
List<T> serviceProxies = new ArrayList<>();
Class<?>[] serviceInterface = new Class[]{service};
// Only need to provide service's interface name is enough to load service
// in enclave.
EnclaveInvocationResult resultWrapper;
resultWrapper = (EnclaveInvocationResult) SerializationHelper.deserialize(loadServiceNative(service.getName()));
trace.setCostInnerEnclave(resultWrapper.getCost());
Throwable exception = resultWrapper.getException();
Object result = resultWrapper.getResult();
// this exception is transformed from enclave, so throw it and handle it in proxy handler.
if (exception != null) {
throw new ServicesLoadingException("service load exception happened in enclave.", exception);
}
// result should never be null, at least it should have an empty ServiceMirror type array.
if (result == null) {
throw new ServicesLoadingException("service load with no any result.");
}
if (!(result instanceof ServiceHandler[])) {
throw new ServicesLoadingException("service load return type is not ServiceHandler[].");
}
for (ServiceHandler serviceHandler : (ServiceHandler[]) result) {
ProxyEnclaveInvocationHandler handler = new ProxyEnclaveInvocationHandler(this, serviceHandler);
T proxy = (T) Proxy.newProxyInstance(service.getClassLoader(), serviceInterface, handler);
serviceProxies.add(proxy);
// Register proxy handler for enclave's corresponding service gc recycling.
enclaveContext.getEnclaveServicesRecycler().registerProxyHandler(proxy, handler);
}
return serviceProxies.iterator();
} catch (IOException | ClassNotFoundException e) {
throw new ServicesLoadingException("EnclaveInvokeResultWrapper deserialization failed.", e);
} catch (MetricTraceLogWriteException e) {
throw new ServicesLoadingException(e);
} finally {
getEnclaveContext().getEnclaveToken().restoreToken();
}
}