Skip to content

Commit

Permalink
Trivial SpringBoot native-image support.
Browse files Browse the repository at this point in the history
  • Loading branch information
sdedic committed Jan 26, 2023
1 parent cb3a98e commit f9b6f8a
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 26 deletions.
2 changes: 1 addition & 1 deletion enterprise/micronaut/nbproject/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
<compile-dependency/>
<run-dependency>
<release-version>2</release-version>
<specification-version>2.156</specification-version>
<specification-version>2.157</specification-version>
</run-dependency>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectActionContext;
import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.modules.maven.api.execute.RunConfig;
import org.netbeans.modules.maven.api.execute.RunUtils;
import org.netbeans.modules.micronaut.AbstractMicronautArtifacts;
import org.netbeans.modules.project.dependency.ArtifactSpec;
import org.netbeans.modules.project.dependency.ProjectArtifactsQuery;
Expand All @@ -62,8 +64,13 @@ public class MicronautPackagingArtifactsImpl implements ProjectArtifactsImplemen
/**
* sharedLibrary plugin parameter. Will build a DLL or .so
*/
public static final String PLUGIN_PARAM_SHAREDLIBRARY = "sharedLibrary";
public static final String PLUGIN_PARAM_SHAREDLIBRARY = "sharedLibrary"; // NOI18N

/**
* Maven goal that does the native-image compilation.
*/
private static final String GOAL_NATIVE_COMPILE = "native:compile"; // NOI18N

private static final Set<String> SUPPORTED_ARTIFACT_TYPES = new HashSet<>(Arrays.asList(
MicronautMavenConstants.TYPE_DYNAMIC_LIBRARY, MicronautMavenConstants.TYPE_EXECUTABLE
));
Expand Down Expand Up @@ -116,7 +123,8 @@ public boolean computeSupportsChanges(R r) {
return true;
}

static class R extends AbstractMicronautArtifacts {
static class R extends AbstractMicronautArtifacts {

private final NbMavenProject mavenProject;

public R(Project project, NbMavenProject mavenProject, ProjectArtifactsQuery.Filter query) {
Expand All @@ -137,11 +145,11 @@ protected void detach(PropertyChangeListener l) {
protected boolean accept(PropertyChangeEvent e) {
return NbMavenProject.PROP_PROJECT.equals(e.getPropertyName());
}

@Override
protected List<ArtifactSpec> compute() {
ProjectActionContext buildCtx;

if (query.getBuildContext() != null) {
if (query.getBuildContext().getProjectAction() == null) {
buildCtx = query.getBuildContext().newDerivedBuilder().forProjectAction(ActionProvider.COMMAND_BUILD).context();
Expand All @@ -152,7 +160,7 @@ protected List<ArtifactSpec> compute() {
buildCtx = ProjectActionContext.newBuilder(getProject()).forProjectAction(ActionProvider.COMMAND_BUILD).context();
}
if (query.getArtifactType() != null &&
!SUPPORTED_ARTIFACT_TYPES.contains(query.getArtifactType()) &&
!SUPPORTED_ARTIFACT_TYPES.contains(query.getArtifactType()) &&
!ProjectArtifactsQuery.Filter.TYPE_ALL.equals(query.getArtifactType())) {
LOG.log(Level.FINE, "Unsupported type: {0}", query.getArtifactType());
return Collections.emptyList();
Expand All @@ -162,14 +170,24 @@ protected List<ArtifactSpec> compute() {
return Collections.emptyList();
}
MavenProject model = mavenProject.getEvaluatedProject(buildCtx);
if (!MicronautMavenConstants.PACKAGING_NATIVE.equals(model.getPackaging())) {
boolean explicitGraalvmGoal = false;
if (buildCtx.getProjectAction() != null) {
RunConfig cfg = RunUtils.createRunConfig(buildCtx.getProjectAction(), getProject(), null, Lookup.EMPTY);
if (cfg != null && cfg.getGoals().contains(GOAL_NATIVE_COMPILE)) {
LOG.log(Level.FINE, "Go explicit native compilation goal from the action");
explicitGraalvmGoal = true;
}
}
if (!explicitGraalvmGoal && !MicronautMavenConstants.PACKAGING_NATIVE.equals(model.getPackaging())) {
LOG.log(Level.FINE, "Unsupported packaging: {0}", model.getPackaging());
return Collections.emptyList();
}
List<ArtifactSpec> nativeStuff = new ArrayList<>();
if (LOG.isLoggable(Level.FINE)) {
LOG.log(Level.FINE, "Configured build plugins: {0}", model.getBuild().getPlugins());
}
boolean foundExecution = false;

for (Plugin p : model.getBuild().getPlugins()) {
if (!(MicronautMavenConstants.NATIVE_BUILD_PLUGIN_GROUP.equals(p.getGroupId()) && MicronautMavenConstants.NATIVE_BUILD_PLUGIN_ID.equals(p.getArtifactId()))) {
continue;
Expand All @@ -179,32 +197,49 @@ protected List<ArtifactSpec> compute() {
if (pe.getGoals().contains(MicronautMavenConstants.PLUGIN_GOAL_COMPILE_NOFORK)) { // NOI18N
Xpp3Dom dom = model.getGoalConfiguration(MicronautMavenConstants.NATIVE_BUILD_PLUGIN_GROUP, MicronautMavenConstants.NATIVE_BUILD_PLUGIN_ID, pe.getId(), MicronautMavenConstants.PLUGIN_GOAL_COMPILE_NOFORK); // NOI18N
if (dom != null) {
Xpp3Dom imageName = dom.getChild(PLUGIN_PARAM_IMAGENAME); // NOI18N
Xpp3Dom sharedLib = dom.getChild(PLUGIN_PARAM_SHAREDLIBRARY); // NOI18N

String name;
if (imageName == null) {
// project default, but should be injected / interpolated by Maven already.
name = model.getArtifactId();
} else {
name = imageName.getValue();
}

Path full = Paths.get(model.getBuild().getDirectory()).resolve(name);
nativeStuff.add(ArtifactSpec.builder(model.getGroupId(), model.getArtifactId(), model.getVersion(), pe)
.type(sharedLib != null && Boolean.parseBoolean(sharedLib.getValue()) ? MicronautMavenConstants.TYPE_DYNAMIC_LIBRARY : MicronautMavenConstants.TYPE_EXECUTABLE)
.location(full.toUri())
.forceLocalFile(FileUtil.toFileObject(full.toFile()))
.build()
);
LOG.log(Level.FINE, "Found bound execution for goals {0}", pe.getGoals());
addNativeExecutable(nativeStuff, model, dom, pe);
foundExecution = true;
}
}
}
}

if (!foundExecution && explicitGraalvmGoal) {
LOG.log(Level.FINE, "No bound execution found, but explicit native compilation requested, trying to search for plugin base config");
// try to get the configuration from PluginManagement, since the plugin is not directly in the build sequence.
Plugin p = model.getPluginManagement().getPluginsAsMap().get(MicronautMavenConstants.NATIVE_BUILD_PLUGIN_GROUP + ":" + MicronautMavenConstants.NATIVE_BUILD_PLUGIN_ID);
if (p != null && p.getConfiguration() != null) {
LOG.log(Level.FINE, "Found plugin configuration");
Xpp3Dom dom = (Xpp3Dom) p.getConfiguration();
addNativeExecutable(nativeStuff, model, dom, p);
}
}
return nativeStuff;
}

private void addNativeExecutable(List<ArtifactSpec> nativeStuff, MavenProject model, Xpp3Dom dom, Object data) {
Xpp3Dom imageName = dom.getChild(PLUGIN_PARAM_IMAGENAME); // NOI18N
Xpp3Dom sharedLib = dom.getChild(PLUGIN_PARAM_SHAREDLIBRARY); // NOI18N

String name;
if (imageName == null) {
// project default, but should be injected / interpolated by Maven already.
name = model.getArtifactId();
} else {
name = imageName.getValue();
}

Path full = Paths.get(model.getBuild().getDirectory()).resolve(name);
nativeStuff.add(ArtifactSpec.builder(model.getGroupId(), model.getArtifactId(), model.getVersion(), data)
.type(sharedLib != null && Boolean.parseBoolean(sharedLib.getValue()) ? MicronautMavenConstants.TYPE_DYNAMIC_LIBRARY : MicronautMavenConstants.TYPE_EXECUTABLE)
.location(full.toUri())
.forceLocalFile(FileUtil.toFileObject(full.toFile()))
.build()
);
}
}

@NbBundle.Messages({
"DN_MicronautArtifacts=Micronaut artifact support"
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@
</file>
</folder>
</folder>
<folder name="org.springframework.boot:spring-boot-maven-plugin">
<folder name="Lookup">
<file name="maven-project-actions.instance">
<attr name="instanceOf" stringvalue="org.netbeans.spi.project.LookupProvider"/>
<attr name="instanceCreate" methodvalue="org.netbeans.api.maven.MavenActions.forProjectLayer"/>
<attr name="resource" stringvalue="nbres:/org/netbeans/modules/micronaut/resources/spring-actions-maven.xml"/>
</file>
<file name="native-image-artifacts.instance">
<attr name="instanceOf" stringvalue="org.netbeans.spi.project.LookupProvider"/>
<attr name="instanceCreate" methodvalue="org.netbeans.modules.micronaut.maven.MicronautPackagingArtifactsImpl.projectLookup"/>
</file>
</folder>
</folder>
<folder name="LifecycleParticipants">
<folder name="org.graalvm.buildtools.maven.NativeExtension">
<attr name="ignoreOnModelLoad" boolvalue="true"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->

<actions>
<action>
<actionName>native-build</actionName>
<packagings>
<packaging>*</packaging>
</packagings>
<goals>
<goal>native:compile</goal>
</goals>
<activatedProfiles>
<activatedProfile>native</activatedProfile>
</activatedProfiles>
</action>
</actions>

0 comments on commit f9b6f8a

Please sign in to comment.