Skip to content

Commit

Permalink
Ensure that native-sources package results in the configuration as n…
Browse files Browse the repository at this point in the history
…ative

    Furthermore, fail the build when native-sources is requested but the extension
    creates its own output

    Related to: quarkusio/quarkus#15233 (comment)
  • Loading branch information
Luca Di Grazia committed Sep 4, 2022
1 parent d34ebc9 commit b3423a9
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.jboss.logmanager.EmbeddedConfigurator;
import org.objectweb.asm.Opcodes;

import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.bootstrap.logging.InitialConfigurator;
import io.quarkus.deployment.GeneratedClassGizmoAdaptor;
import io.quarkus.deployment.annotations.BuildProducer;
Expand All @@ -23,7 +22,6 @@
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.ConsoleFormatterBannerBuildItem;
import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.LogCategoryBuildItem;
import io.quarkus.deployment.builditem.LogConsoleFormatBuildItem;
import io.quarkus.deployment.builditem.LogHandlerBuildItem;
Expand All @@ -47,12 +45,9 @@
import io.quarkus.gizmo.MethodDescriptor;
import io.quarkus.gizmo.ResultHandle;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.configuration.ConfigInstantiator;
import io.quarkus.runtime.logging.CategoryBuildTimeConfig;
import io.quarkus.runtime.logging.CleanupFilterConfig;
import io.quarkus.runtime.logging.InheritableLevel;
import io.quarkus.runtime.logging.LogBuildTimeConfig;
import io.quarkus.runtime.logging.LogCleanupFilterElement;
import io.quarkus.runtime.logging.LogConfig;
import io.quarkus.runtime.logging.LogMetricsHandlerRecorder;
import io.quarkus.runtime.logging.LoggingSetupRecorder;
Expand Down Expand Up @@ -129,54 +124,31 @@ void miscSetup(
LoggingSetupBuildItem setupLoggingRuntimeInit(LoggingSetupRecorder recorder, LogConfig log, LogBuildTimeConfig buildLog,
List<LogHandlerBuildItem> handlerBuildItems,
List<NamedLogHandlersBuildItem> namedHandlerBuildItems, List<LogConsoleFormatBuildItem> consoleFormatItems,
Optional<ConsoleFormatterBannerBuildItem> possibleBannerBuildItem,
LaunchModeBuildItem launchModeBuildItem,
List<LogCleanupFilterBuildItem> logCleanupFilters) {
if (!launchModeBuildItem.isAuxiliaryApplication()) {
final List<RuntimeValue<Optional<Handler>>> handlers = handlerBuildItems.stream()
.map(LogHandlerBuildItem::getHandlerValue)
.collect(Collectors.toList());
final List<RuntimeValue<Map<String, Handler>>> namedHandlers = namedHandlerBuildItems.stream()
.map(NamedLogHandlersBuildItem::getNamedHandlersMap).collect(Collectors.toList());

ConsoleFormatterBannerBuildItem bannerBuildItem = null;
RuntimeValue<Optional<Supplier<String>>> possibleSupplier = null;
if (possibleBannerBuildItem.isPresent()) {
bannerBuildItem = possibleBannerBuildItem.get();
}
if (bannerBuildItem != null) {
possibleSupplier = bannerBuildItem.getBannerSupplier();
}
recorder.initializeLogging(log, buildLog, handlers, namedHandlers,
consoleFormatItems.stream().map(LogConsoleFormatBuildItem::getFormatterValue).collect(Collectors.toList()),
possibleSupplier);
LogConfig logConfig = new LogConfig();
ConfigInstantiator.handleObject(logConfig);
for (LogCleanupFilterBuildItem i : logCleanupFilters) {
CleanupFilterConfig value = new CleanupFilterConfig();
LogCleanupFilterElement filterElement = i.getFilterElement();
value.ifStartsWith = filterElement.getMessageStarts();
value.targetLevel = filterElement.getTargetLevel() == null ? org.jboss.logmanager.Level.DEBUG
: filterElement.getTargetLevel();
logConfig.filters.put(filterElement.getLoggerName(), value);
}
LoggingSetupRecorder.initializeBuildTimeLogging(logConfig, buildLog);
((QuarkusClassLoader) Thread.currentThread().getContextClassLoader()).addCloseTask(new Runnable() {
@Override
public void run() {
InitialConfigurator.DELAYED_HANDLER.buildTimeComplete();
}
});
Optional<ConsoleFormatterBannerBuildItem> possibleBannerBuildItem) {
final List<RuntimeValue<Optional<Handler>>> handlers = handlerBuildItems.stream()
.map(LogHandlerBuildItem::getHandlerValue)
.collect(Collectors.toList());
final List<RuntimeValue<Map<String, Handler>>> namedHandlers = namedHandlerBuildItems.stream()
.map(NamedLogHandlersBuildItem::getNamedHandlersMap).collect(Collectors.toList());

ConsoleFormatterBannerBuildItem bannerBuildItem = null;
RuntimeValue<Optional<Supplier<String>>> possibleSupplier = null;
if (possibleBannerBuildItem.isPresent()) {
bannerBuildItem = possibleBannerBuildItem.get();
}
if (bannerBuildItem != null) {
possibleSupplier = bannerBuildItem.getBannerSupplier();
}
recorder.initializeLogging(log, buildLog, handlers, namedHandlers,
consoleFormatItems.stream().map(LogConsoleFormatBuildItem::getFormatterValue).collect(Collectors.toList()),
possibleSupplier);
return new LoggingSetupBuildItem();
}

@BuildStep
@Record(ExecutionTime.STATIC_INIT)
void setupLoggingStaticInit(LoggingSetupRecorder recorder, LaunchModeBuildItem launchModeBuildItem) {
if (!launchModeBuildItem.isAuxiliaryApplication()) {
recorder.initializeLoggingForImageBuild();
}
void setupLoggingStaticInit(LoggingSetupRecorder recorder) {
recorder.initializeLoggingForImageBuild();
}

// This is specifically to help out with presentations, to allow an env var to always override this value
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.deployment.pkg.steps;

import java.util.function.BooleanSupplier;

import io.quarkus.deployment.pkg.PackageConfig;

/**
* Supplier that can be used to only run build steps in the
* native or native sources builds.
*/
public class NativeOrNativeSourcesBuild implements BooleanSupplier {

private final PackageConfig packageConfig;

NativeOrNativeSourcesBuild(PackageConfig packageConfig) {
this.packageConfig = packageConfig;
}

@Override
public boolean getAsBoolean() {
return packageConfig.type.equalsIgnoreCase(PackageConfig.NATIVE)
|| packageConfig.type.equalsIgnoreCase(PackageConfig.NATIVE_SOURCES);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package io.quarkus.deployment.steps;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
Expand All @@ -17,16 +15,15 @@
import io.quarkus.deployment.builditem.JavaLibraryPathAdditionalPathBuildItem;
import io.quarkus.deployment.builditem.JniBuildItem;
import io.quarkus.deployment.builditem.NativeImageEnableAllCharsetsBuildItem;
import io.quarkus.deployment.builditem.NativeImageEnableAllTimeZonesBuildItem;
import io.quarkus.deployment.builditem.SslNativeConfigBuildItem;
import io.quarkus.deployment.builditem.SslTrustStoreSystemPropertyBuildItem;
import io.quarkus.deployment.builditem.SystemPropertyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageConfigBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBundleBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageSystemPropertyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import io.quarkus.runtime.ssl.SslContextConfigurationRecorder;

//TODO: this should go away, once we decide on which one of the API's we want
Expand All @@ -41,7 +38,6 @@ void build(SslContextConfigurationRecorder sslContextConfigurationRecorder,
SslNativeConfigBuildItem sslNativeConfig,
List<JniBuildItem> jniBuildItems,
List<NativeImageEnableAllCharsetsBuildItem> nativeImageEnableAllCharsetsBuildItems,
List<NativeImageEnableAllTimeZonesBuildItem> nativeImageEnableAllTimeZonesBuildItems,
List<ExtensionSslNativeSupportBuildItem> extensionSslNativeSupport,
List<EnableAllSecurityServicesBuildItem> enableAllSecurityServicesBuildItems,
BuildProducer<NativeImageProxyDefinitionBuildItem> proxy,
Expand All @@ -50,8 +46,7 @@ void build(SslContextConfigurationRecorder sslContextConfigurationRecorder,
BuildProducer<RuntimeReinitializedClassBuildItem> runtimeReinit,
BuildProducer<NativeImageSystemPropertyBuildItem> nativeImage,
BuildProducer<SystemPropertyBuildItem> systemProperty,
BuildProducer<JavaLibraryPathAdditionalPathBuildItem> javaLibraryPathAdditionalPath,
BuildProducer<SslTrustStoreSystemPropertyBuildItem> sslTrustStoreSystemProperty) {
BuildProducer<JavaLibraryPathAdditionalPathBuildItem> javaLibraryPathAdditionalPath) {
for (NativeImageConfigBuildItem nativeImageConfigBuildItem : nativeImageConfigBuildItems) {
for (String i : nativeImageConfigBuildItem.getRuntimeInitializedClasses()) {
runtimeInit.produce(new RuntimeInitializedClassBuildItem(i));
Expand All @@ -75,15 +70,6 @@ void build(SslContextConfigurationRecorder sslContextConfigurationRecorder,
sslContextConfigurationRecorder.setSslNativeEnabled(!sslNativeConfig.isExplicitlyDisabled());

Boolean sslNativeEnabled = isSslNativeEnabled(sslNativeConfig, extensionSslNativeSupport);
if (sslNativeEnabled) {
// This makes the native image dependent on the local path used to build it.
String graalVmHome = System.getenv("GRAALVM_HOME");
if (graalVmHome != null) {
Path graalVmCacertsPath = Paths.get(graalVmHome, "jre", "lib", "security", "cacerts");
// This is useful for testing but the user will have to override it.
sslTrustStoreSystemProperty.produce(new SslTrustStoreSystemPropertyBuildItem(graalVmCacertsPath.toString()));
}
}
nativeImage.produce(new NativeImageSystemPropertyBuildItem("quarkus.ssl.native", sslNativeEnabled.toString()));

if (!enableAllSecurityServicesBuildItems.isEmpty()) {
Expand All @@ -101,10 +87,15 @@ void build(SslContextConfigurationRecorder sslContextConfigurationRecorder,
if (!nativeImageEnableAllCharsetsBuildItems.isEmpty()) {
nativeImage.produce(new NativeImageSystemPropertyBuildItem("quarkus.native.enable-all-charsets", "true"));
}
}

if (!nativeImageEnableAllTimeZonesBuildItems.isEmpty()) {
nativeImage.produce(new NativeImageSystemPropertyBuildItem("quarkus.native.enable-all-timezones", "true"));
}
@BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
void reinitHostNameUtil(BuildProducer<RuntimeReinitializedClassBuildItem> runtimeReInitClass) {
// certain libraries like JBoss logging internally use this class to determine the hostname
// of the system. This HostName class computes and stores the hostname as a static field in a class,
// so we reinitialize this to re-compute the field (and other related fields) during native application's
// runtime
runtimeReInitClass.produce(new RuntimeReinitializedClassBuildItem("org.wildfly.common.net.HostName"));
}

private Boolean isSslNativeEnabled(SslNativeConfigBuildItem sslNativeConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.SystemPropertyBuildItem;
import io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem;
import io.quarkus.deployment.pkg.steps.NativeBuild;
import io.quarkus.jackson.ObjectMapperProducer;
import io.quarkus.deployment.pkg.steps.NativeSourcesBuild;
import io.quarkus.jackson.runtime.ObjectMapperProducer;
import io.quarkus.runtime.LaunchMode;

@SuppressWarnings("unchecked")
public final class AmazonLambdaCommonProcessor {

@BuildStep(onlyIf = NativeSourcesBuild.class)
void failForNativeSources(BuildProducer<ArtifactResultBuildItem> artifactResultProducer) {
throw new IllegalArgumentException(
"The Amazon Lambda extensions are incompatible with the 'native-sources' package type.");
}

/**
* Lambda custom runtime does not like ipv6.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.ApplicationInfoBuildItem;
import io.quarkus.deployment.builditem.SuppressNonRuntimeConfigChangedWarningBuildItem;
import io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem;
import io.quarkus.deployment.pkg.steps.NativeSourcesBuild;

Expand All @@ -23,13 +22,7 @@ public class ContainerImageProcessor {
@BuildStep(onlyIf = NativeSourcesBuild.class)
void failForNativeSources(BuildProducer<ArtifactResultBuildItem> artifactResultProducer) {
throw new IllegalArgumentException(
"The Container Image extensions are incompatible with the 'native-sources' package type.");
}

@BuildStep
public void ignoreCredentialsChange(BuildProducer<SuppressNonRuntimeConfigChangedWarningBuildItem> producer) {
producer.produce(new SuppressNonRuntimeConfigChangedWarningBuildItem("quarkus.container-image.username"));
producer.produce(new SuppressNonRuntimeConfigChangedWarningBuildItem("quarkus.container-image.password"));
"The Container Imagee extensions are incompatible with the 'native-sources' package type.");
}

@BuildStep
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package io.quarkus.gcp.functions.deployment;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;

import io.quarkus.builder.BuildException;
import io.quarkus.deployment.IsNormal;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem;
import io.quarkus.deployment.pkg.builditem.JarBuildItem;
import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
import io.quarkus.deployment.pkg.builditem.UberJarRequiredBuildItem;
import io.quarkus.deployment.pkg.steps.NativeBuild;
import io.quarkus.deployment.pkg.steps.NativeSourcesBuild;

public class CloudFunctionDeploymentBuildStep {
@BuildStep
public UberJarRequiredBuildItem forceUberJar() {
// Google Cloud Function needs a single JAR inside a dedicated directory
return new UberJarRequiredBuildItem();
}

@BuildStep(onlyIf = NativeSourcesBuild.class)
void failForNativeSources(BuildProducer<ArtifactResultBuildItem> artifactResultProducer) {
throw new IllegalArgumentException(
"The Google Cloud extensions are incompatible with the 'native-sources' package type.");
}

/**
* Creates a target/deployment dir and copy the uber jar in it.
* This facilitates the usage of the 'glcoud' command.
*/
@BuildStep(onlyIf = IsNormal.class, onlyIfNot = NativeBuild.class)
public ArtifactResultBuildItem functionDeployment(OutputTargetBuildItem target, JarBuildItem jar)
throws BuildException, IOException {
if (!jar.isUberJar()) {
throw new BuildException("Google Cloud Function deployment need to use a uberjar, " +
"please set 'quarkus.package.type=uber-jar' inside your application.properties",
Collections.EMPTY_LIST);
}

Path deployment = target.getOutputDirectory().resolve("deployment");
if (Files.notExists(deployment)) {
Files.createDirectory(deployment);
}

Path jarPath = jar.getPath();
Path targetJarPath = deployment.resolve(jarPath.getFileName());
Files.deleteIfExists(targetJarPath);
Files.copy(jarPath, targetJarPath);

return new ArtifactResultBuildItem(targetJarPath, "function", Collections.EMPTY_MAP);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@
import io.quarkus.hibernate.orm.runtime.tenant.DataSourceTenantConnectionResolver;
import io.quarkus.hibernate.orm.runtime.tenant.TenantConnectionResolver;
import io.quarkus.hibernate.orm.runtime.tenant.TenantResolver;
import io.quarkus.panache.common.deployment.HibernateEnhancersRegisteredBuildItem;
import io.quarkus.panache.common.deployment.HibernateModelClassCandidatesForFieldAccessBuildItem;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.configuration.ConfigurationException;
import net.bytebuddy.description.type.TypeDescription;
Expand Down Expand Up @@ -500,12 +498,6 @@ public HibernateEnhancersRegisteredBuildItem enhancerDomainObjects(JpaEntitiesBu
return new HibernateEnhancersRegisteredBuildItem();
}

@BuildStep
public HibernateModelClassCandidatesForFieldAccessBuildItem candidatesForFieldAccess(JpaEntitiesBuildItem domainObjects) {
// Ask Panache to replace direct access to public fields with calls to accessors for all model classes.
return new HibernateModelClassCandidatesForFieldAccessBuildItem(domainObjects.getAllModelClassNames());
}

@BuildStep
@Record(STATIC_INIT)
public void build(HibernateOrmRecorder recorder, HibernateOrmConfig hibernateOrmConfig,
Expand Down Expand Up @@ -1221,7 +1213,7 @@ public static QuarkusScanner buildQuarkusScanner(JpaEntitiesBuildItem domainObje
}
scanner.setPackageDescriptors(packageDescriptors);
Set<ClassDescriptor> classDescriptors = new HashSet<>();
for (String className : domainObjects.getEntityClassNames()) {
for (String className : domainObjects.getAllModelClassNames()) {
QuarkusScanner.ClassDescriptorImpl desc = new QuarkusScanner.ClassDescriptorImpl(className,
ClassDescriptor.Categorization.MODEL);
classDescriptors.add(desc);
Expand Down
Loading

0 comments on commit b3423a9

Please sign in to comment.