Iterator loadProxyService()

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();
        }
    }