use of io.quarkus.gizmo.ClassCreator in project camel-quarkus by apache.
the class GrpcProcessor method createBindableServiceBeans.
@BuildStep
void createBindableServiceBeans(BuildProducer<GeneratedBeanBuildItem> generatedBean, BuildProducer<ReflectiveClassBuildItem> reflectiveClass, CombinedIndexBuildItem combinedIndexBuildItem) {
IndexView index = combinedIndexBuildItem.getIndex();
Collection<ClassInfo> bindableServiceImpls = index.getAllKnownImplementors(BINDABLE_SERVICE_DOT_NAME);
// This mimics similar logic in DefaultBindableServiceFactory that uses Javassist ProxyFactory & MethodHandler
for (ClassInfo service : bindableServiceImpls) {
if (!Modifier.isAbstract(service.flags())) {
continue;
}
if (service.name().withoutPackagePrefix().startsWith("Mutiny")) {
/* The generate-code goal of quarkus-maven-plugin generates also Mutiny service that we do not use
* Not skipping it here results in randomly registering the Mutiny one or the right one.
* In case the Mutiny service one is registered, the client throws something like
* io.grpc.StatusRuntimeException: UNIMPLEMENTED */
continue;
}
String superClassName = service.name().toString();
String generatedClassName = superClassName + "QuarkusMethodHandler";
// Register the service classes for reflection
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, service.name().toString()));
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, service.enclosingClass().toString()));
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, generatedClassName));
try (ClassCreator classCreator = ClassCreator.builder().classOutput(new GeneratedBeanGizmoAdaptor(generatedBean)).className(generatedClassName).superClass(superClassName).interfaces(CamelQuarkusBindableService.class).build()) {
classCreator.addAnnotation(Dependent.class);
FieldCreator serverMethodHandler = classCreator.getFieldCreator("methodHandler", GrpcMethodHandler.class.getName()).setModifiers(Modifier.PRIVATE);
// Create constructor
try (MethodCreator initMethod = classCreator.getMethodCreator("<init>", void.class)) {
initMethod.setModifiers(Modifier.PUBLIC);
initMethod.invokeSpecialMethod(MethodDescriptor.ofMethod(superClassName, "<init>", void.class), initMethod.getThis());
initMethod.returnValue(null);
}
// Create setMethodHandler override
try (MethodCreator setMethodHandlerMethod = classCreator.getMethodCreator("setMethodHandler", void.class, GrpcMethodHandler.class)) {
setMethodHandlerMethod.setModifiers(Modifier.PUBLIC);
ResultHandle self = setMethodHandlerMethod.getThis();
ResultHandle methodHandlerInstance = setMethodHandlerMethod.getMethodParam(0);
setMethodHandlerMethod.writeInstanceField(serverMethodHandler.getFieldDescriptor(), self, methodHandlerInstance);
setMethodHandlerMethod.returnValue(null);
}
// Override service methods that the gRPC component is interested in
// E.g methods with one or two parameters where one is of type StreamObserver
List<MethodInfo> methods = service.methods();
for (MethodInfo method : methods) {
if (isCandidateServiceMethod(method)) {
String[] params = method.parameters().stream().map(type -> type.name().toString()).toArray(String[]::new);
ClassInfo classInfo = index.getClassByName(DotName.createSimple(GrpcMethodHandler.class.getName()));
String returnType = method.returnType().name().toString();
try (MethodCreator methodCreator = classCreator.getMethodCreator(method.name(), returnType, params)) {
method.exceptions().stream().map(type -> type.name().toString()).forEach(methodCreator::addException);
if (method.parameters().size() == 1) {
ResultHandle returnValue = generateGrpcDelegateMethod(classInfo, serverMethodHandler, methodCreator, method, "handleForConsumerStrategy");
methodCreator.returnValue(returnValue);
} else if (method.parameters().size() == 2) {
generateGrpcDelegateMethod(classInfo, serverMethodHandler, methodCreator, method, "handle");
methodCreator.returnValue(null);
}
}
}
}
}
}
}
use of io.quarkus.gizmo.ClassCreator in project camel-quarkus by apache.
the class XalanNativeImageProcessor method installTransformerFactory.
@BuildStep
void installTransformerFactory(BuildProducer<GeneratedNativeImageClassBuildItem> nativeImageClass, BuildProducer<GeneratedResourceBuildItem> generatedResources) {
final String serviceProviderFileContent = XalanTransformerFactory.class.getName() + "\n";
/* This is primarily for the JVM mode */
generatedResources.produce(new GeneratedResourceBuildItem(TRANSFORMER_FACTORY_SERVICE_FILE_PATH, serviceProviderFileContent.getBytes(StandardCharsets.UTF_8)));
/* A low level way to embed only our service file in the native image.
* There are at least two META-INF/services/javax.xml.transform.TransformerFactory files
* in the class path: ours and the one from xalan.jar. As of GraalVM 19.3.1-java8, 19.3.1-java11,
* 20.0.0-java8 and 20.0.0-java11, there is no way to ensure that ServiceProviderBuildItem
* or NativeImageResourceBuildItem will pick the service file preferred by us.
* We are thus forced to use this low level mechanism to ensure that.
*/
final ClassCreator file = new ClassCreator(new ClassOutput() {
@Override
public void write(String s, byte[] bytes) {
nativeImageClass.produce(new GeneratedNativeImageClassBuildItem(s, bytes));
}
}, getClass().getName() + "AutoFeature", null, Object.class.getName(), Feature.class.getName());
file.addAnnotation("com.oracle.svm.core.annotate.AutomaticFeature");
final MethodCreator beforeAn = file.getMethodCreator("beforeAnalysis", "V", Feature.BeforeAnalysisAccess.class.getName());
final TryBlock overallCatch = beforeAn.tryBlock();
overallCatch.invokeStaticMethod(ofMethod(ResourceUtils.class, "registerResources", void.class, String.class, String.class), overallCatch.load(TRANSFORMER_FACTORY_SERVICE_FILE_PATH), overallCatch.load(serviceProviderFileContent));
final CatchBlockCreator print = overallCatch.addCatch(Throwable.class);
print.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), print.getCaughtException());
beforeAn.returnValue(null);
file.close();
}
use of io.quarkus.gizmo.ClassCreator in project quarkus-github-action by quarkiverse.
the class GitHubActionProcessor method generatePayloadTypeResolver.
private static void generatePayloadTypeResolver(ClassOutput beanClassOutput, BuildProducer<ReflectiveClassBuildItem> reflectiveClasses, Collection<EventDefinition> eventDefinitions) {
String payloadTypeResolverClassName = GitHubEvent.class.getPackageName() + ".PayloadTypeResolverImpl";
reflectiveClasses.produce(new ReflectiveClassBuildItem(true, true, payloadTypeResolverClassName));
ClassCreator payloadTypeResolverClassCreator = ClassCreator.builder().classOutput(beanClassOutput).className(payloadTypeResolverClassName).interfaces(PayloadTypeResolver.class).build();
payloadTypeResolverClassCreator.addAnnotation(Singleton.class);
Map<String, DotName> payloadTypeMapping = eventDefinitions.stream().collect(Collectors.toMap(ed -> ed.getEvent(), ed -> ed.getPayloadType(), (ed1, ed2) -> ed1));
MethodCreator getPayloadTypeMethodCreator = payloadTypeResolverClassCreator.getMethodCreator("getPayloadType", Class.class, String.class);
ResultHandle eventRh = getPayloadTypeMethodCreator.getMethodParam(0);
for (Entry<String, DotName> payloadTypeMappingEntry : payloadTypeMapping.entrySet()) {
BytecodeCreator matches = getPayloadTypeMethodCreator.ifTrue(getPayloadTypeMethodCreator.invokeVirtualMethod(MethodDescriptors.OBJECT_EQUALS, getPayloadTypeMethodCreator.load(payloadTypeMappingEntry.getKey()), eventRh)).trueBranch();
matches.returnValue(matches.loadClass(payloadTypeMappingEntry.getValue().toString()));
}
getPayloadTypeMethodCreator.returnValue(getPayloadTypeMethodCreator.loadNull());
payloadTypeResolverClassCreator.close();
}
use of io.quarkus.gizmo.ClassCreator in project quarkus-github-action by quarkiverse.
the class GitHubActionProcessor method generateMultiplexers.
/**
* Multiplexers listen to the sync events emitted by the main class.
* <p>
* They are subclasses of the application classes registering actions or listening to GitHub events through our annotations.
* <p>
* They are useful for several purposes:
* <ul>
* <li>A single application method can listen to multiple event types: the event types are qualifiers and CDI wouldn't allow
* that (only events matching all the qualifiers would be received by the application method). That's why this class is
* called a multiplexer: it will generate one method per event type and each generated method will delegate to the original
* method.</li>
* <li>The multiplexer also handles the resolution of payloads, config files...</li>
* <li>We can inject a properly configured instance of GitHub or DynamicGraphQLClient into the method.</li>
* </ul>
*/
private static void generateMultiplexers(ClassOutput beanClassOutput, DispatchingConfiguration dispatchingConfiguration, BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
for (Entry<DotName, TreeSet<ActionDispatchingMethod>> actionDispatchingMethodsEntry : dispatchingConfiguration.getMethods().entrySet()) {
DotName declaringClassName = actionDispatchingMethodsEntry.getKey();
TreeSet<ActionDispatchingMethod> actionDispatchingMethods = actionDispatchingMethodsEntry.getValue();
ClassInfo declaringClass = actionDispatchingMethods.iterator().next().getMethod().declaringClass();
reflectiveClasses.produce(new ReflectiveClassBuildItem(true, true, declaringClassName.toString()));
String multiplexerClassName = declaringClassName + "_Multiplexer";
reflectiveClasses.produce(new ReflectiveClassBuildItem(true, true, multiplexerClassName));
ClassCreator multiplexerClassCreator = ClassCreator.builder().classOutput(beanClassOutput).className(multiplexerClassName).superClass(declaringClassName.toString()).build();
multiplexerClassCreator.addAnnotation(Multiplexer.class);
if (!BuiltinScope.isDeclaredOn(declaringClass)) {
multiplexerClassCreator.addAnnotation(Singleton.class);
}
for (AnnotationInstance classAnnotation : declaringClass.classAnnotations()) {
multiplexerClassCreator.addAnnotation(classAnnotation);
}
// Copy the constructors
for (MethodInfo originalConstructor : declaringClass.constructors()) {
MethodCreator constructorCreator = multiplexerClassCreator.getMethodCreator(MethodDescriptor.ofConstructor(multiplexerClassName, originalConstructor.parameters().stream().map(t -> t.name().toString()).toArray(String[]::new)));
List<AnnotationInstance> originalMethodAnnotations = originalConstructor.annotations().stream().filter(ai -> ai.target().kind() == Kind.METHOD).collect(Collectors.toList());
for (AnnotationInstance originalMethodAnnotation : originalMethodAnnotations) {
constructorCreator.addAnnotation(originalMethodAnnotation);
}
Map<Short, List<AnnotationInstance>> originalConstructorParameterAnnotationMapping = originalConstructor.annotations().stream().filter(ai -> ai.target().kind() == Kind.METHOD_PARAMETER).collect(Collectors.groupingBy(ai -> ai.target().asMethodParameter().position()));
List<ResultHandle> parametersRh = new ArrayList<>();
for (short i = 0; i < originalConstructor.parameters().size(); i++) {
parametersRh.add(constructorCreator.getMethodParam(i));
AnnotatedElement parameterAnnotations = constructorCreator.getParameterAnnotations(i);
List<AnnotationInstance> originalConstructorParameterAnnotations = originalConstructorParameterAnnotationMapping.getOrDefault(i, Collections.emptyList());
for (AnnotationInstance originalConstructorParameterAnnotation : originalConstructorParameterAnnotations) {
parameterAnnotations.addAnnotation(originalConstructorParameterAnnotation);
}
}
constructorCreator.invokeSpecialMethod(MethodDescriptor.of(originalConstructor), constructorCreator.getThis(), parametersRh.toArray(ResultHandle[]::new));
constructorCreator.returnValue(null);
}
// Generate the multiplexed event dispatching methods
for (ActionDispatchingMethod actionDispatchingMethod : actionDispatchingMethods) {
String name = actionDispatchingMethod.getName();
AnnotationInstance eventSubscriberInstance = actionDispatchingMethod.getEventSubscriberInstance();
MethodInfo originalMethod = actionDispatchingMethod.getMethod();
Map<Short, List<AnnotationInstance>> originalMethodParameterAnnotationMapping = originalMethod.annotations().stream().filter(ai -> ai.target().kind() == Kind.METHOD_PARAMETER).collect(Collectors.groupingBy(ai -> ai.target().asMethodParameter().position()));
// if the method already has an @Observes or @ObservesAsync annotation
if (originalMethod.hasAnnotation(DotNames.OBSERVES) || originalMethod.hasAnnotation(DotNames.OBSERVES_ASYNC)) {
LOG.warn("Methods listening to GitHub actions may not be annotated with @Observes or @ObservesAsync. Offending method: " + originalMethod.declaringClass().name() + "#" + originalMethod);
}
List<String> parameterTypes = new ArrayList<>();
List<Type> originalMethodParameterTypes = originalMethod.parameters();
// detect the parameter that is a payload
short payloadParameterPosition = -1;
if (eventSubscriberInstance != null) {
for (short i = 0; i < originalMethodParameterTypes.size(); i++) {
List<AnnotationInstance> parameterAnnotations = originalMethodParameterAnnotationMapping.getOrDefault(i, Collections.emptyList());
if (parameterAnnotations.stream().anyMatch(ai -> ai.name().equals(eventSubscriberInstance.name()))) {
payloadParameterPosition = i;
break;
}
}
}
short j = 0;
Map<Short, Short> parameterMapping = new HashMap<>();
for (short i = 0; i < originalMethodParameterTypes.size(); i++) {
List<AnnotationInstance> originalMethodAnnotations = originalMethodParameterAnnotationMapping.getOrDefault(i, Collections.emptyList());
if (originalMethodAnnotations.stream().anyMatch(ai -> CONFIG_FILE.equals(ai.name())) || INJECTABLE_TYPES.contains(originalMethodParameterTypes.get(i).name()) || i == payloadParameterPosition) {
// if the parameter is annotated with @ConfigFile, is of an injectable type or is the payload, we skip it
continue;
}
parameterTypes.add(originalMethodParameterTypes.get(i).name().toString());
parameterMapping.put(i, j);
j++;
}
int configFileReaderParameterPosition = -1;
if (originalMethod.hasAnnotation(CONFIG_FILE)) {
parameterTypes.add(ConfigFileReader.class.getName());
configFileReaderParameterPosition = j;
j++;
}
parameterTypes.add(GitHubEvent.class.getName());
int gitHubEventParameterPosition = j;
MethodCreator methodCreator = multiplexerClassCreator.getMethodCreator(originalMethod.name() + "_" + HashUtil.sha1(originalMethod.toString() + "_" + (eventSubscriberInstance != null ? eventSubscriberInstance.toString() : EventDefinition.ALL)), originalMethod.returnType().name().toString(), parameterTypes.toArray());
for (Type exceptionType : originalMethod.exceptions()) {
methodCreator.addException(exceptionType.name().toString());
}
ResultHandle[] parameterValues = new ResultHandle[originalMethod.parameters().size()];
// copy annotations except for @ConfigFile
for (short i = 0; i < originalMethodParameterTypes.size(); i++) {
List<AnnotationInstance> parameterAnnotations = originalMethodParameterAnnotationMapping.getOrDefault(i, Collections.emptyList());
if (parameterAnnotations.isEmpty()) {
continue;
}
// Elements that are not in the mapping are ignored
Short generatedParameterIndex = parameterMapping.get(i);
if (generatedParameterIndex == null) {
continue;
}
AnnotatedElement generatedParameterAnnotations = methodCreator.getParameterAnnotations(generatedParameterIndex);
for (AnnotationInstance annotationInstance : parameterAnnotations) {
generatedParameterAnnotations.addAnnotation(annotationInstance);
}
}
// add annotations to the GitHubEvent parameter
AnnotatedElement gitHubEventParameterAnnotations = methodCreator.getParameterAnnotations(gitHubEventParameterPosition);
gitHubEventParameterAnnotations.addAnnotation(DotNames.OBSERVES.toString());
gitHubEventParameterAnnotations.addAnnotation(Action.class).addValue("value", name);
if (eventSubscriberInstance != null) {
gitHubEventParameterAnnotations.addAnnotation(eventSubscriberInstance);
}
ResultHandle gitHubEventRh = methodCreator.getMethodParam(gitHubEventParameterPosition);
// generate the code of the method
for (short originalMethodParameterIndex = 0; originalMethodParameterIndex < originalMethodParameterTypes.size(); originalMethodParameterIndex++) {
List<AnnotationInstance> parameterAnnotations = originalMethodParameterAnnotationMapping.getOrDefault(originalMethodParameterIndex, Collections.emptyList());
Short multiplexerMethodParameterIndex = parameterMapping.get(originalMethodParameterIndex);
if (originalMethodParameterIndex == payloadParameterPosition) {
parameterValues[originalMethodParameterIndex] = methodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getPayload", GHEventPayload.class), gitHubEventRh);
} else if (INJECTABLE_TYPES.contains(originalMethodParameterTypes.get(originalMethodParameterIndex).name())) {
DotName injectableType = originalMethodParameterTypes.get(originalMethodParameterIndex).name();
parameterValues[originalMethodParameterIndex] = methodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "get" + injectableType.withoutPackagePrefix(), injectableType.toString()), gitHubEventRh);
} else if (parameterAnnotations.stream().anyMatch(ai -> ai.name().equals(CONFIG_FILE))) {
AnnotationInstance configFileAnnotationInstance = parameterAnnotations.stream().filter(ai -> ai.name().equals(CONFIG_FILE)).findFirst().get();
String configObjectType = originalMethodParameterTypes.get(originalMethodParameterIndex).name().toString();
boolean isOptional = false;
if (Optional.class.getName().equals(configObjectType)) {
if (originalMethodParameterTypes.get(originalMethodParameterIndex).kind() != Type.Kind.PARAMETERIZED_TYPE) {
throw new IllegalStateException("Optional is used but not parameterized for method " + originalMethod.declaringClass().name() + "#" + originalMethod);
}
isOptional = true;
configObjectType = originalMethodParameterTypes.get(originalMethodParameterIndex).asParameterizedType().arguments().get(0).name().toString();
}
ResultHandle gitHubRh = methodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getGitHub", GitHub.class), gitHubEventRh);
ResultHandle contextRh = methodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getContext", Context.class), gitHubEventRh);
ResultHandle repositoryRh = methodCreator.invokeInterfaceMethod(MethodDescriptor.ofMethod(Context.class, "getGitHubRepository", String.class), contextRh);
ResultHandle configFileReaderRh = methodCreator.getMethodParam(configFileReaderParameterPosition);
ResultHandle configObject = methodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(ConfigFileReader.class, "getConfigObject", Object.class, GitHub.class, String.class, String.class, Class.class), configFileReaderRh, gitHubRh, repositoryRh, methodCreator.load(configFileAnnotationInstance.value().asString()), methodCreator.loadClass(configObjectType));
configObject = methodCreator.checkCast(configObject, configObjectType);
if (isOptional) {
configObject = methodCreator.invokeStaticMethod(MethodDescriptor.ofMethod(Optional.class, "ofNullable", Optional.class, Object.class), configObject);
}
parameterValues[originalMethodParameterIndex] = configObject;
} else {
parameterValues[originalMethodParameterIndex] = methodCreator.getMethodParam(multiplexerMethodParameterIndex);
}
}
ResultHandle returnValue = methodCreator.invokeVirtualMethod(originalMethod, methodCreator.getThis(), parameterValues);
methodCreator.returnValue(returnValue);
}
multiplexerClassCreator.close();
}
}
use of io.quarkus.gizmo.ClassCreator in project quarkus-logging-logback by quarkiverse.
the class LoggingLogbackProcessor method init.
@Record(ExecutionTime.STATIC_INIT)
@BuildStep
void init(LogbackRecorder recorder, RecorderContext context, BuildProducer<RunTimeConfigurationDefaultBuildItem> runTimeConfigurationDefaultBuildItemBuildProducer, BuildProducer<GeneratedClassBuildItem> generatedClasses, OutputTargetBuildItem outputTargetBuildItem, CurateOutcomeBuildItem curateOutcomeBuildItem, ShutdownContextBuildItem shutdownContextBuildItem) throws Exception {
// first check the versions
doVersionCheck();
URL url = getUrl();
if (url == null) {
return;
}
context.registerSubstitution(StartEvent.class, StartSub.class, (Class) EventSubstitution.class);
context.registerSubstitution(BodyEvent.class, BodySub.class, (Class) EventSubstitution.class);
context.registerSubstitution(EndEvent.class, EndSub.class, (Class) EventSubstitution.class);
final AtomicReference<List<SaxEvent>> events = new AtomicReference<>();
JoranConfigurator configurator = new JoranConfigurator() {
@Override
public void doConfigure(List<SaxEvent> eventList) throws JoranException {
events.set(eventList);
}
};
configurator.setContext(new LoggerContext());
configurator.doConfigure(url);
List<String> loggerPath = Arrays.asList("configuration", "logger");
List<String> rootPath = Arrays.asList("configuration", "root");
String rootLevel = null;
Map<String, String> levels = new HashMap<>();
Set<String> allClasses = new HashSet<>();
for (SaxEvent i : events.get()) {
if (i instanceof StartEvent) {
StartEvent s = ((StartEvent) i);
if (Objects.equals(loggerPath, s.elementPath.getCopyOfPartList())) {
String level = s.attributes.getValue("level");
if (level != null) {
levels.put(s.attributes.getValue("name"), level);
}
} else if (Objects.equals(rootPath, s.elementPath.getCopyOfPartList())) {
String level = s.attributes.getValue("level");
if (level != null) {
rootLevel = level;
}
}
int classIndex = s.attributes.getIndex("class");
if (classIndex != -1) {
allClasses.add(s.attributes.getValue(classIndex));
}
}
}
boolean disableConsole = false;
Set<String> delayedClasses = new HashSet<>();
for (String i : allClasses) {
if (i.equals("ch.qos.logback.core.ConsoleAppender")) {
disableConsole = true;
}
try {
Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(i);
if (LifeCycle.class.isAssignableFrom(c)) {
delayedClasses.add(i);
}
} catch (ClassNotFoundException exception) {
throw new RuntimeException(exception);
}
}
if (disableConsole) {
runTimeConfigurationDefaultBuildItemBuildProducer.produce(new RunTimeConfigurationDefaultBuildItem("quarkus.log.console.enable", "false"));
}
for (String i : delayedClasses) {
try (ClassCreator c = new ClassCreator(new GeneratedClassGizmoAdaptor(generatedClasses, (Function<String, String>) s -> s.substring(s.length() - LogbackRecorder.DELAYED.length())), i + LogbackRecorder.DELAYED, null, i, DelayedStart.class.getName())) {
MethodCreator start = c.getMethodCreator("start", void.class);
start.invokeStaticMethod(MethodDescriptor.ofMethod(LogbackRecorder.class, "addDelayed", void.class, DelayedStart.class), start.getThis());
start.returnValue(null);
MethodCreator method = c.getMethodCreator("doQuarkusDelayedStart", void.class);
method.invokeSpecialMethod(MethodDescriptor.ofMethod(i, "start", void.class), method.getThis());
method.returnValue(null);
}
}
if (rootLevel != null) {
runTimeConfigurationDefaultBuildItemBuildProducer.produce(new RunTimeConfigurationDefaultBuildItem("quarkus.log.level", rootLevel));
}
for (Map.Entry<String, String> e : levels.entrySet()) {
runTimeConfigurationDefaultBuildItemBuildProducer.produce(new RunTimeConfigurationDefaultBuildItem("quarkus.log.category.\"" + e.getKey() + "\".level", e.getValue()));
}
Map<String, String> buildProperties = new HashMap<>(outputTargetBuildItem.getBuildSystemProperties().entrySet().stream().collect(Collectors.toMap(Object::toString, Object::toString)));
buildProperties.put(PROJECT_VERSION, curateOutcomeBuildItem.getEffectiveModel().getAppArtifact().getVersion());
recorder.init(events.get(), delayedClasses, shutdownContextBuildItem, buildProperties);
}
Aggregations