Async call of a FeignClient Springboot with CompletableFuture - java

I want to call async rest endpoints with Feign client and have done the below changes.
When calling it the CompletableFuture.get() doesn't complete.
The while keeps looping...
while(!combinedFuture.isDone()) { log.info("useraccount - waiting for combinedFuture 2: " + request.toString()); }
Interface to call the API:
#FeignClient(value = "clientUser", url = "http://localhost:8898/springboot", fallback = UserFallback.class)
public interface User {
#RequestMapping(method = RequestMethod.GET, value = "/user/", produces = "application/json")
#Async
CompletableFuture<UserInfo> findUserInfo(#RequestHeader(value = "Authorization", required = true) String authorizationHeader);
}
Controller method:
#PostMapping(value = "/springboot/useraccount/", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> userAccount(#requestbody #Valid AuthRequest request) {
log.info("useraccount - request received with request body: " + request.toString());
try {
if (Strings.isBlank(request.getUsername()) || Strings.isBlank(request.getPassword())) {
throw new BadRequestException("invalid username or password");
}
String token = authorisationService.obtainAuthToken(request.getUsername(), request.getPassword());
CompletableFuture<UserInfo> userInfo = clientUser.findUserInfo(token);
CompletableFuture<UserAccountInfo> userAccountInfo = clientAccount.findAccountInfo(token);
CompletableFuture<Void> combinedFuture
= CompletableFuture.allOf(userInfo, userAccountInfo);
while(!combinedFuture.isDone()) {
log.info("useraccount - waiting for combinedFuture 2: " + request.toString());
}
Optional<UserAccountResponse> userAccountResponse = userAccountService.getAccountInfo(
userAccountInfo.get(), userInfo.get()
);
if (userAccountResponse.isEmpty()) {
throw new BadCredentialsException("Bad Credentials");
}
return ResponseEntity.ok().body(userAccountResponse);
} catch (BadCredentialsException | UnAuthorizedException ex) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
} catch (BadRequestException ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
} catch (ExecutionException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
} catch (InterruptedException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
(update) Have changed a bit to use CompletableFuture.supplyAsync
but now the object is always null...
#Service
public class AccountService {
#Autowired
Account accountClient;
#Async
public Optional<UserAccountInfo> getAccountInfo(String token) {
return Optional.of(accountClient.findAccountInfo(token));
}
}

Managed to solve it like this:
#Async
public CompletableFuture<UserAccountInfo> getAccountInfo(String token) {
try {
System.out.println(
"Current Thread account Name: "
+ Thread.currentThread().getName());
Thread.currentThread().sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return CompletableFuture.completedFuture(accountClient.findAccountInfo(token).getBody());
}
The same for the userInfo service. Then on the controller:
CompletableFuture<UserAccountInfo> userAccountInfo = accountService.getAccountInfo(token);
CompletableFuture<UserInfo> userInfo = userService.getUserInfo(token);
Optional<UserAccountResponse> userAccountResponse = userAccountService.getAccountInfo(
userAccountInfo.get(),userInfo.get()
);
So that means both services will start running each in a new thread while the main thread continues ran until find the first .get().
By doing it like that the maximum waiting time to finish is the time of the thread that takes more time and not the sum of both as it happens if it is a synchronous.
Thanks!

Related

Resubmit Callable to executorService on exception

My situation
I'm trying to craft a functionality which would execute n (where n >=0) requests to a given endpoint, but I do understand that sometimes that endpoint might not respond due to
500 error or other issue, so I want to repeat my requests to an endpoint (with a
small interval in between [not yet implemented]) till I get a response, or till I get an unknown error which would indicate what I can't repeat, because of other reasons than a crashed server.
So, I've tried to implement this piece of functionality using Executors and concurrency provided by Java 11 and it does not work as I want
I can't resubmit failed tasks till I get all the responses and I don't know why
I have a method
private void DoMyTasks(List<MyRequest> requests) {
final ExecutorService executorService = Executors.newFixedThreadPool(10);
final ExecutorCompletionService<MyReqResDto> completionService =
new ExecutorCompletionService<>(executorService);
for (final MyRequest MyRequest : requests) {
completionService.submit(new MyCallableRequest(webClient, MyRequest));
}
List<MyReqResDto> responses = new ArrayList<>();
for (int i = 0; i < requests.size(); ++i) {
try {
final Future<MyReqResDto> future = completionService.take();
if (future.get().getEx() != null) {
completionService.submit(new MyCallableRequest(webClient, future.get().getMyRequest()));
}
responses.add(future.get());
} catch (ExecutionException | InterruptedException e) {
log.warn("Error"));
} catch (Exception exception) {
log.error("Other error");
} finally {
executorService.shutdown();
try {
if (!executorService.awaitTermination(10, TimeUnit.MINUTES)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
}
}
}
responses.size();
}
I'm trying to repeat failed tasks with
if (future.get().getEx() != null) {
completionService.submit(new MyCallableRequest(webClient, future.get().getMyRequest()));
}
and yet, at the end of execution I don't get all responses for my requests. What I get is at most 3 to 5 responses when I try executing 10 requests. Why? How to fix it?
My callable class is
public class MyCallableRequest implements Callable<MyReqResDto> {
private final WebClient webClient;
private final MyRequest myRequest;
public MyCallableRequest(WebClient webClient, MyRequest myRequest) {
this.webClient = webClient;
this.myRequest = myRequest;
}
#Override
public MyReqResDto call() throws Exception {
try {
if (new Random().nextInt(10) % 2 == 0) {
throw new TestException();
}
if (new Random().nextInt(10) % 7 == 0) {
throw new RuntimeException();
}
WebClient.UriSpec<WebClient.RequestBodySpec> uriSpec = webClient.post();
WebClient.RequestBodySpec bodySpec = uriSpec.uri(
s -> s.path("/myEndpoint").build());
MyRequestDto myMyRequestDto = new MyRequestDto();
WebClient.RequestHeadersSpec<?> headersSpec =
bodySpec.body(Mono.just(myMyRequestDto), MyRequestDto.class);
ResponseDto responseDto = headersSpec.exchangeToMono(s -> {
if (s.statusCode().equals(HttpStatus.OK)) {
return s.bodyToMono(ResponseDto.class);
} else if (s.statusCode().is1xxInformational()) {
return s.createException().flatMap(Mono::error);
} else if (s.statusCode().is3xxRedirection()) {
return s.createException().flatMap(Mono::error);
} else if (s.statusCode().is4xxClientError()) {
return s.createException().flatMap(Mono::error);
} else if (s.statusCode().is5xxServerError()) {
return s.createException().flatMap(Mono::error);
} else {
return s.createException().flatMap(Mono::error);
}
//return null;
}).block();
return new MyReqResDto(myRequest, responseDto, null);
} catch (Exception exception) {
return new MyReqResDto(myRequest, null, exception);
}
}
}
Update NO. 1
I changed a for loop to a while loop according to a comment provided by
Slaw and an answer provided by erickson. And this solutions works, meaning that
it is hammering an endpoint till all responses are received without
any errors. But I'm still not sure it feels that I'm building a sh**
tower with this solution. Is there any thread related issues that I should be aware while using executor like this?
while (true) {
Future < MyReqResDto > future = null;
try {
future = completionService.take();
if (future.get().getEx() != null /*and check exception if possible to handle, if not break from a loop*/) {
completionService.submit(new MyCallableRequest(webClient, future.get().getRequestCT());
} else {
responseDtos.add(future.get());
}
} catch (ExecutionException | InterruptedException e) {
log.warn("Error while downloading", e.getCause());
// test if I can recover from these exceptions if no
break;
}
}
if (responseDtos.size() == requests.size()) {
executorService.shutdown();
try {
if (!executorService.awaitTermination(10, TimeUnit.MINUTES)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
}
break;
}
You are shutting down the executor as soon as you get one response. Perhaps a few more have completed in this time, but you are not allowing time for any others to complete.
Your logic here is wrong. The executor should only be shut down when you are sure no more tasks will be submitted; at soonest, that is after the loop responsible for re-submitting failures.
Here is a simplified view of your code to highlight the premature shutdown:
for (int i = 0; i < requests.size(); ++i) {
try {
final Future<MyReqResDto> future = completionService.take();
...
responses.add(future.get());
...
} finally {
executorService.shutdown();
}
}

ExecutorService InvokeAll for hybrid datatype

I am new trying to invoke multiple multiple threads with varied return types, using ExecutorService. I need to wait for all threads to complete, before I proceed. I am able to do it using homogeneous return types, but want to use heterogeneous return types.
Below is my sample code snippet:
#RestController
public class ApplicationController {
#GetMapping
public String HelloWorld() {
System.out.println("Inside Thread main");
Callable<String> callableTask = () -> {
return invokeThread1();
};
Callable<String> callableTask2 = () -> {
return invokeThread2();
};
List<Callable<String>> tasks = new ArrayList<>();
System.out.println("Inside Thread main - 1 ");
StringBuilder result = new StringBuilder();
ExecutorService executor = Executors.newFixedThreadPool(10);
System.out.println("Inside Thread main - 2");
tasks.add(callableTask);
tasks.add(callableTask2);
try {
List<Future<String>> futures = executor.invokeAll(tasks);
for (Future<String> f : futures) {
result.append(f.get());
System.out.println(" result ::: " + result);
}
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Inside Thread main - 5 " + result.toString());
return result.toString();
}
private String invokeThread1() {
final String uri = "http://localhost:8082";
return invokeService(uri).getBody();
}
private String invokeThread2() {
final String uri = "http://localhost:8083";
return invokeService(uri).getBody();
}
private ResponseEntity<String> invokeService(final String uri) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
return result;
}
}
Imagine the return type of invokeThread1 is String, while that of invokeThread2 is Integer. Please help me with the requisite changes.

ThreadPoolTaskExecutor add tasks upon available active threads

I am trying to call a REST service asynchronously using ThreadPoolTaskExecutor. I have to call the same service asynchronously for the given input. I have a thread pool of a certain size and want to send a request to the service once the active thread count is less than the pool size. I am not sure how I could do that. Here is the sample code.
public class CallableWrkr implements Callable<Response>{
public CallableWrkr(Map<String,String> headers,
String hostName, Transfer transfer, String name) {
this.transfer = transfer;
this.hostName = hostName;
this.name = name;
}
#Override
public Response call() throws Exception {
System.out.println(name + 1);
Thread.sleep((new Random().nextInt(5000)) + 500);
CoreServicesImpl service = new CoreServicesImpl();
service.setHost(hostName);
Response resp = service.process( headers,
transfer);
System.out.println(name + 2);
return resp;
}
}
I want to do some thing like below when I have a list of transfer objects.
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
ThreadPoolTaskExecutor taskExecutor = (ThreadPoolTaskExecutor) context.getBean("taskExecutor");
for (;;) {
int count = taskExecutor.getActiveCount();
System.out.println("Active Threads : " + count);
if(count < taskExecutor.getMaxPoolSize())
{
CallableWrkr callableTask = new CallableWrkr(headers transfers.get(i), new Integer(threadNumber).toString());
Future<Response> result = taskExecutor.submit(callableTask);
futureList.add(result);
}
else {
wait();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 0) {
taskExecutor.shutdown();
break;
}
}
Not sure if I could do that. Is there a queue I can add the list to?
Thanks.

Java duplicated Exception handling in a separate method

I work on a Spring webStart application...
I have 2 (and potentially more) methods that process multi-tier Exception clause, as in:
...
try {
employeeService.updateEmployeePartner(employeeId, partner);
LOG.info("partner details updated for partner id {}", employeeId);
result = new ResponseEntity<>(partner.getId(), HttpStatus.OK);
} catch (EmployeePartnerNotFoundException ex) {
LOG.error(ex.getMessage() + " employee id: ", employeeId);
errorResponse = new ErrorResponse("500", ex.getMessage());
} catch (ReadOperationDeniedException ex) {
LOG.error("User doesn't have permissions to update employee's {} details: {}", employeeId, ex.getMessage());
errorResponse = new ErrorResponse("403", "User doesn't have permissions to update employee's details");
} catch (Exception ex) {
LOG.error("something went wrong while updating employee's {} partner details: {}", employeeId, ex.getMessage());
errorResponse = new ErrorResponse("500", "unspecified server error");
} finally {
result = (result != null) ? result : new ResponseEntity<>(errorResponse, HttpStatus.I_AM_A_TEAPOT); // should be INTERNAL_SERVER_ERROR
}
...
Another method is almost identical, apart for this change:
employeeService.updateEmployeePartner(employeeId, partner); =>
employeeService.createEmployeePartner(employeeId, partner);
and catching EmployeePartnerAlreadyExistsException in that block.
Now, to reduce code duplication, I want to group all Error handling code in one place (method), so I replaced the above code with the following
...
try {
employeeService.updateEmployeePartner(employeeId, partner);
LOG.info("partner details updated for partner id {}", employeeId);
result = new ResponseEntity<>(partner.getId(), HttpStatus.OK);
} catch (Exception ex) {
errorResponse = processException(ex, employeeId, "update");
} finally {
result = (result != null) ? result : new ResponseEntity<>(errorResponse, HttpStatus.I_AM_A_TEAPOT); // should be INTERNAL_SERVER_ERROR
}
...
private ErrorResponse processException(Exception ex, Long employeeId, String operation) {
ErrorResponse errorResponse;
if (ex.getClass().equals(EmployeePartnerNotFoundException.class) ||
ex.getClass().equals(EmployeePartnerExistsException.class)) {
LOG.error(ex.getMessage() + " employee id: ", employeeId);
errorResponse = new ErrorResponse("500", ex.getMessage());
} else if (ex.getClass().isInstance(ReadOperationDeniedException.class)) {
LOG.error("User doesn't have permissions to " + operation + " employee's {} details: {}", employeeId, ex.getMessage());
errorResponse = new ErrorResponse("403", "User doesn't have permissions to " + operation + " employee's details");
} else { // Exception
LOG.error("something went wrong while trying to " + operation + " employee's {} partner details: {}", employeeId, ex.getMessage());
errorResponse = new ErrorResponse("500", "unspecified server error");
}
return errorResponse;
}
Is that a good enough approach or are there any patterns to handle exceptions in the above scenario by outsourcing the handling to a separate method/class?
Since it's a spring application, I also consider using Spring exception handlers, as in:
#ExceptionHandler(Exception.class)
, but that will only cover part of my requirements.
Use #ControllerAdvice with your custom ErrorResponse and each Handler for seprate exceptions. Refer Custom error response Spring
Sample code:
#ControllerAdvice
public class GlobalExceptionHandlers {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandlers.class);
/***************** User Defined Exceptions *************************/
#ExceptionHandler({ EmployeePartnerNotFoundException.class })
public ResponseEntity<Object> handleEmployeePartnerNotFoundException(EmployeePartnerNotFoundException ex) {
logger.error("EmployeePartnerNotFoundException : ", ex);
ErrorResponse errorResponse = new ErrorResponse("500", ex.getMessage());
return new ResponseEntity<Object>(errorResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST);
}
// other exception handlers
}
That's what I ended up doing in the end, along with the reply by Sangam:
Individual Exception handlers worked quite well; Do note there is no need to put these in separate class.
But I still wonder if there is a similar pattern where the application is not Spring MVC?
public ResponseEntity<?> updatePartnerDetails(#PathVariable("employeeId") Long employeeId,
#RequestBody PersonDetails partnerDto) {
LOG.info("Updating partner details for employee {}, partner details {}", employeeId, partnerDto);
validateRequestValues(partnerDto);
// Try-catches were around this call
Person partner = PersonMapper.fromPersonDetails(partnerDto);
employeeService.updateEmployeePartner(employeeId, partner);
LOG.info("partner details updated for partner id {}", employeeId);
return new ResponseEntity<>(partner.getId(), HttpStatus.OK);
}
#ResponseStatus(HttpStatus.I_AM_A_TEAPOT) // TODO: BAD_REQUEST
#ExceptionHandler({EmployeePartnerExistsException.class, EmployeePartnerNotFoundException.class})
public ResponseEntity<?> employeePartnerError(Exception ex) {
LOG.error(ex.getMessage());
return new ResponseEntity<Object>(new ErrorResponse(400, ex.getMessage()), HttpStatus.OK);
}
#ResponseStatus(HttpStatus.I_AM_A_TEAPOT) // TODO: BAD_REQUEST
#ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<?> validationError(Exception ex) {
LOG.error(ex.getMessage());
return new ResponseEntity<Object>(new ErrorResponse(400, ex.getMessage()), HttpStatus.OK);
}
#ResponseStatus(HttpStatus.I_AM_A_TEAPOT) // TODO: FORBIDDEN
#ExceptionHandler(ReadOperationDeniedException.class)
public ResponseEntity<?> forbidden(Exception ex) {
LOG.error("User doesn't have permissions to amend employee's details");
return new ResponseEntity<Object>(new ErrorResponse(403, "User doesn't have permissions to amend employee's details"), HttpStatus.OK);
}
#ResponseStatus(HttpStatus.I_AM_A_TEAPOT) // TODO: INTERNAL_SERVER_ERROR
#ExceptionHandler(Exception.class)
public ResponseEntity<?> unspecifiedError(Exception ex) {
LOG.error("User doesn't have permissions to amend employee's details");
return new ResponseEntity<Object>(new ErrorResponse(500, "Something went wrong while editing employee's details"), HttpStatus.OK);
}

Why does object inside a protected method has implementation?

Its the method invokeBackend(String request, HashMap context) .
Why does it have an object named java.security.PrivilegedAction createController = new java.security.PrivilegedAction()
and it has an implementation ? I see it has a run() method which means its a thread.
Does the run method returns "controller"? It returns "controller" to what?
What kind of an implementation is this? An object having implementation code?
3.Whats the primary use of implmentation of the method invokeBackend
Also the object
java.security.PrivilegedAction processRequest = new java.security.PrivilegedAction()
Thanks a lot!
protected static String invokeBackend(String request, HashMap context)
throws CommonModelException {
if (request.equals("")) {
return null;
}
if (logger.isDebugEnabled()) {
logger.debug("request: \r\n" + request);
}
Properties clientAuthenticationEnv = CommonProperties
.getClientAuthenticationProperties();
if (wccClientId == null) {
wccClientId = clientAuthenticationEnv.getProperty(CLIENT_ID);
}
if (wccClientPassword == null) {
wccClientPassword = clientAuthenticationEnv
.getProperty(CLIENT_PASSWORD);
}
controllerHome = getControllerHome();
String response = null;
try {
if (controllerHome == null) {
throw new CommonModelException(ResourceBundleHelper.resolve(
CommonResourceBundleNames.COMMON_STRINGS,
LOG_REMOTE_EXCEPTION));
}
if (isWASImpl) {
java.security.PrivilegedAction createController = new java.security.PrivilegedAction() {
public Object run() {
Object controller = null;
try {
controller = controllerHome.create();
} catch (RemoteException e) {
logger.error(ResourceBundleHelper.resolve(
CommonResourceBundleNames.COMMON_STRINGS,
LOG_REMOTE_EXCEPTION), e);
} catch (CreateException e) {
logger.error(ResourceBundleHelper.resolve(
CommonResourceBundleNames.COMMON_STRINGS,
LOG_FAIL_GET_EJB_INSTANCE), e);
}
return controller;
}
}; // PrivilegedAction
validateSecurityToken();
final DWLServiceController controller = (DWLServiceController) WSSubject
.doAs(subject, createController);
final String req = request;
final HashMap cxt = context;
java.security.PrivilegedAction processRequest = new java.security.PrivilegedAction() {
public Object run() {
Object response = null;
try {
response = (String) controller.processRequest(cxt,
req);
} catch (com.dwl.base.exception.DWLResponseException e) {
response = e.getLocalizedMessage();
} catch (RemoteException e) {
logger.error(ResourceBundleHelper.resolve(
CommonResourceBundleNames.COMMON_STRINGS,
LOG_REMOTE_EXCEPTION), e);
}
return response;
}
}; // PrivilegedAction
validateSecurityToken();
response = (String) WSSubject.doAs(subject, processRequest);
} else {
// DWLServiceController controller = controllerHome.create();
// response = (String) controller.processRequest(context,
// request);
java.security.PrivilegedAction createController = new java.security.PrivilegedAction() {
public Object run() {
Object controller = null;
try {
controller = controllerHome.create();
} catch (RemoteException e) {
logger.error(ResourceBundleHelper.resolve(
CommonResourceBundleNames.COMMON_STRINGS,
LOG_REMOTE_EXCEPTION), e);
} catch (CreateException e) {
logger.error(ResourceBundleHelper.resolve(
CommonResourceBundleNames.COMMON_STRINGS,
LOG_FAIL_GET_EJB_INSTANCE), e);
}
return controller;
}
}; // PrivilegedAction
//reflection invoke to avoid compile dependency on weblogic library
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class securityClazz = cl.getClass().getClassLoader().loadClass("weblogic.security.Security");
Method runAs = securityClazz.getMethod("runAs", new Class[]{Subject.class, java.security.PrivilegedAction.class});
final DWLServiceController controller = (DWLServiceController) runAs.invoke(securityClazz, new Object[]{subject, createController});
//final DWLServiceController controller = (DWLServiceController) Security.runAs(subject, createController);
final String req = request;
final HashMap cxt = context;
java.security.PrivilegedAction processRequest = new java.security.PrivilegedAction() {
public Object run() {
Object response = null;
try {
response = (String) controller.processRequest(cxt,
req);
} catch (com.dwl.base.exception.DWLResponseException e) {
response = e.getLocalizedMessage();
} catch (RemoteException e) {
logger.error(ResourceBundleHelper.resolve(
CommonResourceBundleNames.COMMON_STRINGS,
LOG_REMOTE_EXCEPTION), e);
}
return response;
}
}; // PrivilegedAction
response = (String)runAs.invoke(securityClazz, subject, processRequest);
//response = (String) Security.runAs(subject, processRequest);
}
} catch (Exception e) {
response = e.getLocalizedMessage();
// for non IBM WebSphere Server, we have one more chance to redo
// lookup for EJB server restart, clear the session first
controllerHome = getControllerHome();
if (controllerHome == null) {
throw new CommonModelException(ResourceBundleHelper.resolve(
CommonResourceBundleNames.COMMON_STRINGS,
LOG_REMOTE_EXCEPTION));
}
try {
DWLServiceController controller = controllerHome.create();
response = (String) controller.processRequest(context, request);
} catch (DWLResponseException e1) {
response = e1.getLocalizedMessage();
} catch (RemoteException e1) {
logger.error(ResourceBundleHelper.resolve(
CommonResourceBundleNames.COMMON_STRINGS,
LOG_REMOTE_EXCEPTION), e1);
throw new CommonModelException(e1);
} catch (CreateException e1) {
logger.error(ResourceBundleHelper.resolve(
CommonResourceBundleNames.COMMON_STRINGS,
LOG_FAIL_GET_EJB_INSTANCE), e1);
throw new CommonModelException(e1);
}
}
if (logger.isDebugEnabled()) {
logger.debug("response: \r\n" + response);
}
return response;
}
The declaration you're looking at is a local variable initialized to reference an instance of an anonymous inner class. The class implemented is PrivilegedAction. The syntax is used when you want to create a one-off implementation of an interface or class that you don't intend to use elsewhere, so there's no point in giving it a name. The code implements the run method from the interface and creates an object implementing that interface, that it assigns to the local variable.
The run method returns a controller object to whoever calls run on it. That isn't shown here, it's passed in as one of the arguments to the runAs method call on this line:
final DWLServiceController controller = (DWLServiceController) runAs.invoke(
securityClazz, new Object[]{subject, createController});
where the code used reflection to look up the runAs method on the class weblogic.security.Security.

Categories