mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-97324 Maven support cannot handle skinny wars for EAR deployments
This commit is contained in:
+94
@@ -16,26 +16,43 @@
|
||||
package org.jetbrains.jps.maven.compiler;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.StreamUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Base64;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.builders.BuildRootDescriptor;
|
||||
import org.jetbrains.jps.builders.artifacts.ArtifactBuildTaskProvider;
|
||||
import org.jetbrains.jps.builders.storage.BuildDataPaths;
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor;
|
||||
import org.jetbrains.jps.incremental.BuildTask;
|
||||
import org.jetbrains.jps.incremental.CompileContext;
|
||||
import org.jetbrains.jps.incremental.ProjectBuildException;
|
||||
import org.jetbrains.jps.incremental.artifacts.impl.JpsArtifactUtil;
|
||||
import org.jetbrains.jps.maven.model.JpsMavenExtensionService;
|
||||
import org.jetbrains.jps.maven.model.impl.MavenModuleResourceConfiguration;
|
||||
import org.jetbrains.jps.maven.model.impl.MavenProjectConfiguration;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsArtifactRootElement;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsFileCopyPackagingElement;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
@@ -72,6 +89,7 @@ public class MavenManifestGenerationBuildTaskProvider extends ArtifactBuildTaskP
|
||||
try {
|
||||
File output = new File(myArtifact.getOutputPath(), JarFile.MANIFEST_NAME);
|
||||
FileUtil.writeToFile(output, Base64.decode(moduleResourceConfiguration.manifest));
|
||||
handleSkinnyWars(context, projectConfiguration, moduleResourceConfiguration);
|
||||
}
|
||||
// do not fail the whole 'Make' if there is an invalid manifest cached (e.g. non encoded string generated by previous IDEA version)
|
||||
catch (Exception e) {
|
||||
@@ -80,6 +98,82 @@ public class MavenManifestGenerationBuildTaskProvider extends ArtifactBuildTaskP
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSkinnyWars(final CompileContext context,
|
||||
final MavenProjectConfiguration projectConfiguration,
|
||||
MavenModuleResourceConfiguration moduleResourceConfiguration) {
|
||||
if (!"ear".equals(moduleResourceConfiguration.modelMap.get("packaging"))) return;
|
||||
if (!Boolean.parseBoolean(moduleResourceConfiguration.modelMap.get("build.plugin.maven-ear-plugin.skinnyWars"))) return;
|
||||
|
||||
final String earClasspath = moduleResourceConfiguration.classpath;
|
||||
if (earClasspath == null) return;
|
||||
|
||||
final Map<String, String> earClasspathMap = ContainerUtil.map2Map(
|
||||
StringUtil.split(earClasspath, " "), new Function<String, Pair<String, String>>() {
|
||||
@Override
|
||||
public Pair<String, String> fun(String s) {
|
||||
final int idx = s.lastIndexOf("/");
|
||||
return Pair.create(s.substring(idx == -1 ? 0 : idx + 1), s);
|
||||
}
|
||||
});
|
||||
|
||||
JpsArtifactUtil.processPackagingElements(myArtifact.getRootElement(), new Processor<JpsPackagingElement>() {
|
||||
@Override
|
||||
public boolean process(JpsPackagingElement element) {
|
||||
if (!(element instanceof JpsFileCopyPackagingElement)) return true;
|
||||
|
||||
final String filePath = ((JpsFileCopyPackagingElement)element).getFilePath();
|
||||
final File skinnyManifest = new File(filePath);
|
||||
if (!"SKINNY_MANIFEST.MF".equals(skinnyManifest.getName())) return true;
|
||||
|
||||
final String skinnyWarModuleName = skinnyManifest.getParentFile().getParentFile().getName();
|
||||
final MavenModuleResourceConfiguration warConfiguration = projectConfiguration.moduleConfigurations.get(skinnyWarModuleName);
|
||||
if (warConfiguration == null || warConfiguration.classpath == null) return true;
|
||||
|
||||
try {
|
||||
final byte[] warManifestData = Base64.decode(warConfiguration.manifest);
|
||||
Manifest warManifest = new Manifest(new ByteArrayInputStream(warManifestData));
|
||||
|
||||
List<String> skinnyWarClasspath = ContainerUtil.newArrayList();
|
||||
for (String entry : StringUtil.split(warConfiguration.classpath, " ")) {
|
||||
final int idx = entry.lastIndexOf("/");
|
||||
final String entryName = entry.substring(idx == -1 ? 0 : idx + 1);
|
||||
final String earEntryPath = earClasspathMap.get(entryName);
|
||||
skinnyWarClasspath.add(earEntryPath == null ? entry : earEntryPath);
|
||||
}
|
||||
|
||||
final Attributes warManifestMainAttributes = warManifest.getMainAttributes();
|
||||
warManifestMainAttributes.putValue("Class-Path", StringUtil.join(skinnyWarClasspath, " "));
|
||||
|
||||
FileUtil.createParentDirs(skinnyManifest);
|
||||
FileOutputStream outputStream = new FileOutputStream(skinnyManifest);
|
||||
try {
|
||||
warManifest.write(outputStream);
|
||||
|
||||
final ProjectDescriptor projectDescriptor = context.getProjectDescriptor();
|
||||
final Collection<BuildRootDescriptor> descriptors =
|
||||
projectDescriptor.getBuildRootIndex().findAllParentDescriptors(skinnyManifest, context);
|
||||
for (BuildRootDescriptor descriptor : descriptors) {
|
||||
try {
|
||||
projectDescriptor.fsState.markDirty(context, skinnyManifest, descriptor, projectDescriptor.timestamps.getStorage());
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.debug(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
StreamUtil.closeStream(outputStream);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.debug(e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getModuleName(@NotNull String artifactName) {
|
||||
return StringUtil.substringBefore(artifactName, ":");
|
||||
|
||||
+5
@@ -45,6 +45,10 @@ public class MavenModuleResourceConfiguration {
|
||||
@Tag("manifest")
|
||||
public String manifest;
|
||||
|
||||
@Nullable
|
||||
@Tag("classpath")
|
||||
public String classpath;
|
||||
|
||||
@NotNull
|
||||
@Tag("delimiters-pattern")
|
||||
public String delimitersPattern;
|
||||
@@ -110,6 +114,7 @@ public class MavenModuleResourceConfiguration {
|
||||
result = 31 * result + (parentId != null ? parentId.hashCode() : 0);
|
||||
result = 31 * result + directory.hashCode();
|
||||
result = 31 * result + (manifest != null ? manifest.hashCode() : 0);
|
||||
result = 31 * result + (classpath != null ? classpath.hashCode() : 0);
|
||||
result = 31 * result + delimitersPattern.hashCode();
|
||||
result = 31 * result + modelMap.hashCode();
|
||||
result = 31 * result + properties.hashCode();
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ public abstract class ManifestImporter {
|
||||
String classpathPrefix = getClasspathPrefix(manifestConfiguration);
|
||||
for (MavenArtifact mavenArtifact : mavenProject.getDependencies()) {
|
||||
final DependencyScope scope = MavenModuleImporter.selectScope(mavenArtifact.getScope());
|
||||
if (scope.isForProductionRuntime()) {
|
||||
if (scope.isForProductionCompile() || scope.isForProductionRuntime()) {
|
||||
if (classpath.length() > 0) {
|
||||
classpath.append(" ");
|
||||
}
|
||||
|
||||
@@ -149,6 +149,12 @@ public abstract class MavenImporter {
|
||||
Map<MavenProject, String> mavenProjectToModuleName,
|
||||
List<MavenProjectsProcessorTask> postTasks);
|
||||
|
||||
public void postProcess(Module module,
|
||||
MavenProject mavenProject,
|
||||
MavenProjectChanges changes,
|
||||
MavenModifiableModelsProvider modifiableModelsProvider) {
|
||||
}
|
||||
|
||||
public boolean processChangedModulesOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
+25
@@ -159,6 +159,31 @@ public class MavenModuleImporter {
|
||||
});
|
||||
}
|
||||
|
||||
public void postConfigFacets() {
|
||||
MavenUtil.invokeAndWaitWriteAction(myModule.getProject(), new Runnable() {
|
||||
public void run() {
|
||||
if (myModule.isDisposed()) return;
|
||||
|
||||
final ModuleType moduleType = ModuleType.get(myModule);
|
||||
|
||||
for (final MavenImporter importer : getSuitableImporters()) {
|
||||
final MavenProjectChanges changes;
|
||||
if (myMavenProjectChanges == null) {
|
||||
if (importer.processChangedModulesOnly()) continue;
|
||||
changes = MavenProjectChanges.NONE;
|
||||
}
|
||||
else {
|
||||
changes = myMavenProjectChanges;
|
||||
}
|
||||
|
||||
if (importer.getModuleType() == moduleType) {
|
||||
importer.postProcess(myModule, myMavenProject, changes, myModifiableModelsProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<MavenImporter> getSuitableImporters() {
|
||||
return myMavenProject.getSuitableImporters();
|
||||
}
|
||||
|
||||
+6
-2
@@ -431,7 +431,7 @@ public class MavenProjectImporter {
|
||||
javacOptions.ADDITIONAL_OPTIONS_STRING = options;
|
||||
}
|
||||
|
||||
private void importModules(final List<MavenProjectsProcessorTask> postTasks) {
|
||||
private void importModules(final List<MavenProjectsProcessorTask> tasks) {
|
||||
Map<MavenProject, MavenProjectChanges> projectsWithChanges = myProjectsToImportWithChanges;
|
||||
|
||||
Set<MavenProject> projectsWithNewlyCreatedModules = new THashSet<MavenProject>();
|
||||
@@ -471,7 +471,11 @@ public class MavenProjectImporter {
|
||||
}
|
||||
|
||||
for (MavenModuleImporter importer : importers) {
|
||||
importer.configFacets(postTasks);
|
||||
importer.configFacets(tasks);
|
||||
}
|
||||
|
||||
for (MavenModuleImporter importer : importers) {
|
||||
importer.postConfigFacets();
|
||||
}
|
||||
|
||||
setMavenizedModules(modulesToMavenize, true);
|
||||
|
||||
+9
@@ -129,6 +129,8 @@ public class MavenResourceCompilerConfigurationGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
addEarModelMapEntries(mavenProject, resourceConfig.modelMap);
|
||||
|
||||
Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin");
|
||||
|
||||
resourceConfig.outputDirectory = getResourcesPluginGoalOutputDirectory(mavenProject, pluginConfiguration, "resources");
|
||||
@@ -190,6 +192,12 @@ public class MavenResourceCompilerConfigurationGenerator {
|
||||
});
|
||||
}
|
||||
|
||||
private static void addEarModelMapEntries(@NotNull MavenProject mavenProject, @NotNull Map<String, String> modelMap) {
|
||||
Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-ear-plugin");
|
||||
final String skinnyWars = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "skinnyWars", "false");
|
||||
modelMap.put("build.plugin.maven-ear-plugin.skinnyWars", skinnyWars);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getResourcesPluginGoalOutputDirectory(@NotNull MavenProject mavenProject,
|
||||
@Nullable Element pluginConfiguration,
|
||||
@@ -234,6 +242,7 @@ public class MavenResourceCompilerConfigurationGenerator {
|
||||
finally {
|
||||
StreamUtil.closeStream(outputStream);
|
||||
}
|
||||
resourceConfig.classpath = ManifestBuilder.getClasspath(mavenProject);
|
||||
}
|
||||
catch (ManifestBuilder.ManifestBuilderException e) {
|
||||
LOG.warn("Unable to generate artifact manifest", e);
|
||||
|
||||
@@ -67,18 +67,7 @@ public class ManifestBuilder {
|
||||
@NotNull
|
||||
public java.util.jar.Manifest build() throws ManifestBuilderException {
|
||||
try {
|
||||
Element mavenPackagingPluginConfiguration = null;
|
||||
final String packaging = myMavenProject.getPackaging();
|
||||
if (StringUtil.isEmpty(packaging)) {
|
||||
mavenPackagingPluginConfiguration = myMavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-jar-plugin");
|
||||
}
|
||||
else {
|
||||
final String pluginArtifactId = PACKAGING_PLUGINS.get(StringUtil.toLowerCase(packaging));
|
||||
if (pluginArtifactId != null) {
|
||||
mavenPackagingPluginConfiguration = myMavenProject.getPluginConfiguration("org.apache.maven.plugins", pluginArtifactId);
|
||||
}
|
||||
}
|
||||
|
||||
Element mavenPackagingPluginConfiguration = getMavenPackagingPluginConfiguration(myMavenProject);
|
||||
final Element mavenArchiveConfiguration =
|
||||
mavenPackagingPluginConfiguration != null ? mavenPackagingPluginConfiguration.getChild("archive") : null;
|
||||
|
||||
@@ -110,6 +99,16 @@ public class ManifestBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getClasspath(@NotNull MavenProject mavenProject) {
|
||||
Element mavenPackagingPluginConfiguration = getMavenPackagingPluginConfiguration(mavenProject);
|
||||
final Element mavenArchiveConfiguration =
|
||||
mavenPackagingPluginConfiguration != null ? mavenPackagingPluginConfiguration.getChild("archive") : null;
|
||||
final Element manifestConfiguration = mavenArchiveConfiguration != null ? mavenArchiveConfiguration.getChild("manifest") : null;
|
||||
final ManifestImporter manifestImporter = ManifestImporter.getManifestImporter(mavenProject.getPackaging());
|
||||
return manifestImporter.getClasspath(mavenProject, manifestConfiguration);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getClasspathPrefix(@Nullable Element manifestConfiguration) {
|
||||
String classpathPrefix = MavenJDOMUtil.findChildValueByPath(manifestConfiguration, "classpathPrefix", "").replaceAll("\\\\", "/");
|
||||
@@ -119,6 +118,22 @@ public class ManifestBuilder {
|
||||
return classpathPrefix;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Element getMavenPackagingPluginConfiguration(@NotNull MavenProject mavenProject) {
|
||||
Element mavenPackagingPluginConfiguration = null;
|
||||
final String packaging = mavenProject.getPackaging();
|
||||
if (StringUtil.isEmpty(packaging)) {
|
||||
mavenPackagingPluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-jar-plugin");
|
||||
}
|
||||
else {
|
||||
final String pluginArtifactId = PACKAGING_PLUGINS.get(StringUtil.toLowerCase(packaging));
|
||||
if (pluginArtifactId != null) {
|
||||
mavenPackagingPluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", pluginArtifactId);
|
||||
}
|
||||
}
|
||||
return mavenPackagingPluginConfiguration;
|
||||
}
|
||||
|
||||
|
||||
private static Map<String, String> getManifestEntries(Element manifestEntries) {
|
||||
boolean hasManifestEntries = manifestEntries != null && manifestEntries.getContentSize() > 0;
|
||||
|
||||
Reference in New Issue
Block a user