Я был в этом в течение нескольких часов, но, кажется, не могу распутать это. Ошибка относится к этому сегменту кода:
(Полный код внизу этого вопроса. Я использую скриншоты, чтобы визуально показать проблему.)
Сама ошибка:
экземпляр(ы) переменной(ов) типа U не существует, так что GetUsersForAdAccountResponse соответствует CompletionStage
В самом начале цепочки thenCompose
я стер return
и использовал функцию IntelliJ "Ввести локальную переменную...", чтобы увидеть, какой тип возвращает вся цепочка (до строки 1118 включительно). :
В результате
final CompletionStage<U> uCompletionStage = ...
Но вы можете видеть, что возвращаемый тип охватывающего метода:
public CompletionStage<GetUsersForAdAccountResponse> ...
Что мешает компилятору вывести GetUsersForAdAccountResponse
? (Опять же, обычно здесь стоит return
.)
Я также пытался вводить локальную переменную в каждые thenCompose
по пути, и все они кажутся правильными. Каждый дает CompletionStage<Foo>
, для которого следующий thenCompose
предоставляет лямбду, ожидающую Foo
, и дает CompletionStage<Bar>
, и так далее. (В одной реорганизации кода я увидел вложенный CompletionStage<CompletionStage<Foo>>
, но я думаю, что это был артефакт моего собственного переписывания.)
Не знаю, поможет ли, но вот весь метод:
@Override
public CompletionStage<GetUsersForAdAccountResponse> getUsersForAdAccount(
RequestContext context, GetUsersForAdAccountRequest request) {
Uuid adAccountId = request.getAdAccountId();
return verifyAuthorization(context,
PortcullisTemplates.Action.GET_USERS_FOR_AD_ACCOUNT.getName(),
portcullisTemplates.topOrganizationResource())
.thenCompose(auditLogPrincipal -> jdbiExecutor.executeInTransaction(handler -> {
// We purposely safeguard the account lookup as well behind Portcullis.
AdAccountDao adAccountDao = handler.attach(AdAccountDao.class);
if (adAccountDao.getAdAccountById(adAccountId) == null) {
throw new ValidationException(SERVICE_NAME,
"Ad account not found: " + UuidUtils.toString(adAccountId));
}
AdAccountRoleUserMappingDao roleDao = handler.attach(AdAccountRoleUserMappingDao.class);
List<String> roleNames = request.getRoleNamesList();
return roleNames.isEmpty() ?
roleDao.getAdAccountRoleUserMappingsByAdAccount(adAccountId) :
roleDao.getAdAccountRoleUserMappingsByAdAccountAndRoles(adAccountId, roleNames);
})).thenCompose(adAccountRoleUserMappings -> jdbiExecutor.execute(UserDao.class, userDao -> {
return userDao
.getUsersBy]UserIds(
adAccountRoleUserMappings.stream()
.map(AdAccountRoleUserMapping::userId)
.collect(Collectors.toList())
).stream()
.collect(Collectors.toMap(
User::userId,
user -> new EncryptedFieldsBuilder()
.firstName(user.encryptedFirstName())
.lastName(user.encryptedLastName())
.email(user.encryptedEmail())
.build()
));
}).thenCompose(
userEncryptedFields -> padlockService.decryptUserAccounts(userEncryptedFields)
).thenCompose(decryptedUsers -> GetUsersForAdAccountResponse.newBuilder()
.addAllUserWithRole(
adAccountRoleUserMappings.stream()
.filter(mapping -> decryptedUsers.containsKey(mapping.userId()))
.map(mapping -> UserWithRole.newBuilder()
.setAccount(decryptedUsers.get(mapping.userId()))
.setRoleName(mapping.roleName())
.build())
.collect(Collectors.toSet())
).build()
));
}
thenCompose
на самом деле должен бытьthenApply
. Или, пожалуйста, предоставьте подпись методаbuild()
для всего, что возвращаетGetUsersForAdAccountResponse.newBuilder()
. - person Misha   schedule 17.08.2018thenApply
, но теперь вижу, что что-то еще было не так. Я сдался и перешел кthenCompose
, что, казалось, вызывало более ограниченную ошибку. Играя с этим, я по незнанию исправил первоначальную проблему, но никогда не возвращался кthenApply
. Теперь компилируется нормально. Спасибо, и не стесняйтесь добавлять ответ, чтобы я мог принять. - person slackwing   schedule 17.08.2018