aether-based JPS builder for remote artifact dependency resolution, initial

This commit is contained in:
Eugene Zhuravlev
2016-08-19 10:44:08 +02:00
parent 7c0b081b0c
commit 6173c1d8b4
12 changed files with 459 additions and 9 deletions
+2 -1
View File
@@ -11,6 +11,7 @@
<module fileurl="file://$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" filepath="$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/plugins/ShortcutPromoter/ShortcutPromoter.iml" filepath="$PROJECT_DIR$/plugins/ShortcutPromoter/ShortcutPromoter.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/android/adt-branding/adt-branding.iml" filepath="$PROJECT_DIR$/android/adt-branding/adt-branding.iml" group="android" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/aether-dependency-resolver/aether-dependency-resolver.iml" filepath="$PROJECT_DIR$/plugins/maven/aether-dependency-resolver/aether-dependency-resolver.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/analysis-api/analysis-api.iml" filepath="$PROJECT_DIR$/platform/analysis-api/analysis-api.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/analysis-impl/analysis-impl.iml" filepath="$PROJECT_DIR$/platform/analysis-impl/analysis-impl.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/android/android/android.iml" filepath="$PROJECT_DIR$/android/android/android.iml" group="android" />
@@ -182,8 +183,8 @@
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven-server-api/maven-server-api.iml" filepath="$PROJECT_DIR$/plugins/maven/maven-server-api/maven-server-api.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven2-server-impl/maven2-server-impl.iml" filepath="$PROJECT_DIR$/plugins/maven/maven2-server-impl/maven2-server-impl.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven3-server-common/maven3-server-common.iml" filepath="$PROJECT_DIR$/plugins/maven/maven3-server-common/maven3-server-common.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven30-server-impl/maven30-server-impl.iml" filepath="$PROJECT_DIR$/plugins/maven/maven30-server-impl/maven30-server-impl.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven3-server-impl/maven3-server-impl.iml" filepath="$PROJECT_DIR$/plugins/maven/maven3-server-impl/maven3-server-impl.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven30-server-impl/maven30-server-impl.iml" filepath="$PROJECT_DIR$/plugins/maven/maven30-server-impl/maven30-server-impl.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/android/tools-base/ninepatch/ninepatch.iml" filepath="$PROJECT_DIR$/android/tools-base/ninepatch/ninepatch.iml" group="android/sdktools" />
<module fileurl="file://$PROJECT_DIR$/java/openapi/openapi.iml" filepath="$PROJECT_DIR$/java/openapi/openapi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/android/tools-base/perflib/perflib.iml" filepath="$PROJECT_DIR$/android/tools-base/perflib/perflib.iml" group="android/sdktools" />
@@ -267,6 +267,10 @@ class CommunityLibraryLicenses {
license: "Apache 2.0", url: "http://maven.apache.org/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"),
new LibraryLicense(name: "plexus-util", version: "2.0.6", license: "Apache 2.0", url: "http://maven.apache.org/",
libraryName: 'plexus-utils-2.0.6.jar', licenseUrl: "http://apache.org/licenses/LICENSE-2.0"),
new LibraryLicense(name: "aether", version: "1.1.0", license: "Eclipse Public License 1.0", url: "http://www.eclipse.org/aether/",
libraryName: 'aether-1.1.0-all.jar', licenseUrl: "http://www.eclipse.org/legal/epl-v10.html"),
new LibraryLicense(name: "maven-aether-provider", version: "3.3.9", license: "Apache 2.0", url: "http://maven.apache.org/ref/3.3.9/maven-aether-provider",
libraryName: 'maven-aether-provider-3.3.9-all.jar', licenseUrl: "http://apache.org/licenses/LICENSE-2.0"),
new LibraryLicense(name: "Plexus Utils", libraryName: "plexus-utils-1.5.5.jar", version: "1.5.5", license: "Apache 2.0",
url: "http://plexus.codehaus.org/plexus-utils"),
new LibraryLicense(name: "pockets", attachedTo: "python-helpers", version: "0.2.4", license: "BSD", url: "http://pockets.readthedocs.org/"),
+4 -5
View File
@@ -15,11 +15,7 @@
*/
import org.jetbrains.intellij.build.BuildContext
import org.jetbrains.intellij.build.BuildOptions
import org.jetbrains.intellij.build.BuildTasks
import org.jetbrains.intellij.build.IdeaCommunityProperties
import org.jetbrains.intellij.build.ProprietaryBuildTools
import org.jetbrains.intellij.build.*
import org.jetbrains.jps.util.JpsPathUtil
import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
@@ -340,6 +336,9 @@ public def layoutCommunityPlugins(String home, BuildContext buildContext = null)
jar("maven-jps-plugin.jar") {
module("maven-jps-plugin")
}
jar("aether-dependency-resolver.jar") {
module("aether-dependency-resolver")
}
jar("maven-server-api.jar") {
module("maven-server-api")
}
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="annotations" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../lib/aether-1.1.0-all.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../lib/maven-aether-provider-3.3.9-all.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>
@@ -0,0 +1,143 @@
package org.jetbrains.idea.maven.aether;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResult;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transfer.TransferListener;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.eclipse.aether.util.artifact.JavaScopes;
import org.eclipse.aether.util.filter.DependencyFilterUtils;
import org.eclipse.aether.util.version.GenericVersionScheme;
import org.eclipse.aether.version.InvalidVersionSpecificationException;
import org.eclipse.aether.version.Version;
import org.eclipse.aether.version.VersionScheme;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author Eugene Zhuravlev
* Date: 20-Jun-16
*
* Aether-based repository manager and dependency resolver using maven implementation of this functionality.
*
* instance of this component should be managed by the code which requires dependency resolution functionality
* all necessary params like path to local repo should be passed in constructor
*
*/
public class ArtifactRepositoryManager {
private static final String ARTIFACT_EXTENSION = "jar";
private final VersionScheme myVersioning = new GenericVersionScheme();
private final DefaultRepositorySystemSession mySession;
// todo: more remotes? make remote repos configurable?
public static final List<RemoteRepository> REMOTE_REPOSITORIES = Collections.singletonList(
new RemoteRepository.Builder("central", "default", "http://central.maven.org/maven2/").build()
);
private static final RepositorySystem ourSystem;
static {
final DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler() {
public void serviceCreationFailed(Class<?> type, Class<?> impl, Throwable exception) {
if (exception != null) {
throw new RuntimeException(exception);
}
}
});
ourSystem = locator.getService(RepositorySystem.class);
}
public ArtifactRepositoryManager(@NotNull File localRepositoryPath) {
this(localRepositoryPath, ProgressConsumer.DEAF);
}
public ArtifactRepositoryManager(@NotNull File localRepositoryPath, @NotNull final ProgressConsumer progressConsumer) {
final DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
if (progressConsumer != ProgressConsumer.DEAF) {
session.setTransferListener((TransferListener)Proxy
.newProxyInstance(session.getClass().getClassLoader(), new Class[]{TransferListener.class}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final Object event = args[0];
if (event instanceof TransferEvent) {
progressConsumer.consume(event.toString());
//if (((TransferEvent)event).getType() != TransferEvent.EventType.PROGRESSED) {
// progressConsumer.consume(event.toString());
//}
}
return null;
}
}));
}
// setup session here
session.setLocalRepositoryManager(ourSystem.newLocalRepositoryManager(session, new LocalRepository(localRepositoryPath)));
session.setReadOnly();
mySession = session;
}
public Collection<File> resolveDependency(String groupId, String artifactId, String version) throws Exception {
final DependencyRequest dependencyRequest = new DependencyRequest(
createCollectRequest(groupId, artifactId, toVersion(version)),
DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE)
);
final DependencyResult result = ourSystem.resolveDependencies(mySession, dependencyRequest);
final List<File> files = new ArrayList<File>();
for (ArtifactResult artifactResult : result.getArtifactResults()) {
files.add(artifactResult.getArtifact().getFile());
}
return files;
}
private static CollectRequest createCollectRequest(String groupId, String artifactId, Version version) {
return createCollectRequest(groupId, artifactId, Collections.singleton(version));
}
private static CollectRequest createCollectRequest(String groupId, String artifactId, Collection<Version> versions) {
CollectRequest request = new CollectRequest();
for (Artifact artifact : toArtifacts(groupId, artifactId, versions)) {
request.addDependency(new Dependency(artifact, JavaScopes.COMPILE));
}
return request.setRepositories(REMOTE_REPOSITORIES);
}
private Version toVersion(String version) throws InvalidVersionSpecificationException {
return myVersioning.parseVersion(version);
}
private static List<Artifact> toArtifacts(String groupId, String artifactId, Collection<Version> versions) {
if (versions.isEmpty()) {
return Collections.emptyList();
}
final List<Artifact> result = new ArrayList<Artifact>(versions.size());
for (Version version : versions) {
result.add(new DefaultArtifact(groupId, artifactId, ARTIFACT_EXTENSION, version.toString()));
}
return result;
}
}
@@ -0,0 +1,14 @@
package org.jetbrains.idea.maven.aether;
/**
* @author Eugene Zhuravlev
* Date: 12-Aug-16
*/
public interface ProgressConsumer {
ProgressConsumer DEAF = new ProgressConsumer() {
public void consume(String message) {
}
};
void consume(String message);
}
@@ -23,6 +23,6 @@
</library>
</orderEntry>
<orderEntry type="module" module-name="jps-serialization-tests" scope="TEST" />
<orderEntry type="module" module-name="aether-dependency-resolver" />
</component>
</module>
</module>
@@ -0,0 +1,253 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed 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.
*/
package org.jetbrains.jps.maven.compiler;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.SmartHashSet;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.aether.ArtifactRepositoryManager;
import org.jetbrains.idea.maven.aether.ProgressConsumer;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.api.CanceledStatus;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
import org.jetbrains.jps.maven.model.RepositoryLibraryDescriptor;
import org.jetbrains.jps.maven.model.impl.JpsMavenRepositoryLibraryType;
import org.jetbrains.jps.model.JpsSimpleElement;
import org.jetbrains.jps.model.library.JpsLibrary;
import org.jetbrains.jps.model.library.JpsOrderRootType;
import org.jetbrains.jps.model.library.JpsTypedLibrary;
import org.jetbrains.jps.model.module.JpsDependencyElement;
import org.jetbrains.jps.model.module.JpsLibraryDependency;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.serialization.JpsModelSerializationDataService;
import org.jetbrains.jps.model.serialization.JpsPathVariablesConfiguration;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
/**
* @author Eugene Zhuravlev
* Date: 21-Jun-16
*/
public class DependencyResolvingBuilder extends ModuleLevelBuilder{
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.maven.compiler.DependencyResolvingBuilder");
private static final String NAME = "Maven Dependency Resolver";
private static final String MAVEN_REPOSITORY_PATH_VAR = "MAVEN_REPOSITORY";
private static final String DEFAULT_MAVEN_REPOSITORY_PATH = ".m2/repository";
private static final Key<ArtifactRepositoryManager> MANAGER_KEY = Key.create("_artifact_repository_manager_");
private static final Key<Exception> RESOLVE_ERROR_KEY = Key.create("_artifact_repository_resolve_error_");
public DependencyResolvingBuilder() {
super(BuilderCategory.INITIAL);
}
@NotNull
@Override
public String getPresentableName() {
return NAME;
}
public void buildStarted(CompileContext context) {
ResourceGuard.init(context);
}
@Override
public void chunkBuildStarted(CompileContext context, ModuleChunk chunk) {
try {
checkDependencies(context, chunk);
}
catch (Exception e) {
context.putUserData(RESOLVE_ERROR_KEY, e);
}
}
@Override
public ExitCode build(CompileContext context,
ModuleChunk chunk,
DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
OutputConsumer outputConsumer) throws ProjectBuildException, IOException {
final Exception error = context.getUserData(RESOLVE_ERROR_KEY);
if (error != null) {
final StringBuilder builder = new StringBuilder().append("Error resolving dependencies for ").append(chunk.getPresentableShortName());
final String details = error.getMessage();
if (details != null) {
builder.append(": ").append(details);
}
final String msg = builder.toString();
LOG.info(msg, error);
context.processMessage(new CompilerMessage(NAME, BuildMessage.Kind.ERROR, msg));
return ExitCode.ABORT;
}
return ExitCode.OK;
}
private static void checkDependencies(CompileContext context, ModuleChunk chunk) throws Exception {
final Collection<JpsTypedLibrary<JpsSimpleElement<RepositoryLibraryDescriptor>>> libs = getRepositoryLibraries(chunk);
if (!libs.isEmpty()) {
final ArtifactRepositoryManager repoManager = getRepositoryManager(context);
for (JpsTypedLibrary<JpsSimpleElement<RepositoryLibraryDescriptor>> lib : libs) {
final RepositoryLibraryDescriptor descriptor = lib.getProperties().getData();
final ResourceGuard guard = ResourceGuard.get(context, descriptor);
if (guard.requestProcessing(context.getCancelStatus())) {
try {
final Collection<File> resolved = repoManager.resolveDependency(descriptor.getGroupId(), descriptor.getArtifactId(), descriptor.getVersion());
syncPaths(resolved, lib);
}
finally {
guard.finish();
}
}
}
}
}
private static void syncPaths(@NotNull Collection<File> resolved, @NotNull JpsTypedLibrary<JpsSimpleElement<RepositoryLibraryDescriptor>> lib) throws Exception {
if (resolved.isEmpty()) {
LOG.info("No artifacts were resolved for repository dependency " + lib.getProperties().getData().getMavenId());
return;
}
final THashSet<File> libFiles = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
libFiles.addAll(lib.getFiles(JpsOrderRootType.COMPILED));
libFiles.removeAll(resolved);
if (!libFiles.isEmpty()) {
Map<String, File> nameToArtifactMap = null;
for (File file : libFiles) {
if (file.exists()) {
continue;
}
if (nameToArtifactMap == null) { // lazy init
nameToArtifactMap = new THashMap<String, File>(FileUtil.PATH_HASHING_STRATEGY);
for (File f : resolved) {
final File prev = nameToArtifactMap.put(f.getName(), f);
if (prev != null) {
throw new Exception("Ambiguous artifacts with the same name: " + prev.getPath() + " and " + f.getPath());
}
}
}
final File resolvedArtifact = nameToArtifactMap.get(file.getName());
if (resolvedArtifact != null) {
FileUtil.copy(resolvedArtifact, file);
}
}
}
}
private static final class ResourceGuard {
private static final Key<ConcurrentMap<RepositoryLibraryDescriptor, ResourceGuard>> CONTEXT_KEY = GlobalContextKey.create("_artifact_repository_resolved_libraries_");
private static final byte INITIAL = 0;
private static final byte PROGRESS = 1;
private static final byte FINISHED = 2;
private byte myState = INITIAL;
synchronized boolean requestProcessing(final CanceledStatus cancelStatus) {
if (myState == INITIAL) {
myState = PROGRESS;
return true;
}
while (myState == PROGRESS) {
if (cancelStatus.isCanceled()) {
break;
}
try {
this.wait(1000L);
}
catch (InterruptedException ignored) {
}
}
return false;
}
synchronized void finish() {
myState = FINISHED;
this.notifyAll();
}
static void init(CompileContext context) {
context.putUserData(CONTEXT_KEY, ContainerUtil.<RepositoryLibraryDescriptor, ResourceGuard>newConcurrentMap());
}
@NotNull
static ResourceGuard get(CompileContext context, RepositoryLibraryDescriptor descriptor) {
final ConcurrentMap<RepositoryLibraryDescriptor, ResourceGuard> map = context.getUserData(CONTEXT_KEY);
assert map != null;
final ResourceGuard g = new ResourceGuard();
final ResourceGuard existing = map.putIfAbsent(descriptor, g);
return existing != null? existing : g;
}
}
@NotNull
private static Collection<JpsTypedLibrary<JpsSimpleElement<RepositoryLibraryDescriptor>>> getRepositoryLibraries(ModuleChunk chunk) {
final Collection<JpsTypedLibrary<JpsSimpleElement<RepositoryLibraryDescriptor>>> result = new SmartHashSet<JpsTypedLibrary<JpsSimpleElement<RepositoryLibraryDescriptor>>>();
for (JpsModule module : chunk.getModules()) {
for (JpsDependencyElement dep : module.getDependenciesList().getDependencies()) {
if (dep instanceof JpsLibraryDependency) {
final JpsLibrary _lib = ((JpsLibraryDependency)dep).getLibrary();
final JpsTypedLibrary<JpsSimpleElement<RepositoryLibraryDescriptor>> lib = _lib != null ? _lib.asTyped(JpsMavenRepositoryLibraryType.INSTANCE) : null;
if (lib != null) {
result.add(lib);
}
}
}
}
return result;
}
private static ArtifactRepositoryManager getRepositoryManager(final CompileContext context) {
ArtifactRepositoryManager manager = MANAGER_KEY.get(context);
if (manager == null) {
manager = new ArtifactRepositoryManager(getLocalRepoDir(context), new ProgressConsumer() {
public void consume(String message) {
context.processMessage(new ProgressMessage(message));
}
});
// further init manager here
MANAGER_KEY.set(context, manager);
}
return manager;
}
@NotNull
private static File getLocalRepoDir(CompileContext context) {
final JpsPathVariablesConfiguration pvConfig = JpsModelSerializationDataService.getPathVariablesConfiguration(context.getProjectDescriptor().getModel().getGlobal());
final String localRepoPath = pvConfig != null? pvConfig.getUserVariableValue(MAVEN_REPOSITORY_PATH_VAR) : null;
if (localRepoPath != null) {
return new File(localRepoPath);
}
final String root = System.getProperty("user.home", null);
return root != null ? new File(root, DEFAULT_MAVEN_REPOSITORY_PATH) : new File(DEFAULT_MAVEN_REPOSITORY_PATH);
}
}
@@ -18,6 +18,7 @@ package org.jetbrains.jps.maven.compiler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildTargetType;
import org.jetbrains.jps.incremental.BuilderService;
import org.jetbrains.jps.incremental.ModuleLevelBuilder;
import org.jetbrains.jps.incremental.TargetBuilder;
import org.jetbrains.jps.maven.model.impl.MavenResourcesTargetType;
@@ -41,4 +42,9 @@ public class MavenBuilderService extends BuilderService{
public List<? extends TargetBuilder<?, ?>> createBuilders() {
return Collections.singletonList(new MavenResourcesBuilder());
}
@NotNull
public List<? extends ModuleLevelBuilder> createModuleLevelBuilders() {
return Collections.singletonList(new DependencyResolvingBuilder());
}
}
Binary file not shown.
@@ -71,7 +71,7 @@
<junitPatcher implementation="org.jetbrains.idea.maven.execution.MavenJUnitPatcher" />
<compileServer.plugin classpath="maven-jps-plugin.jar;maven3/lib/plexus-utils-2.0.6.jar"/>
<compileServer.plugin classpath="maven-jps-plugin.jar;aether-dependency-resolver.jar;aether-1.1.0-all.jar;maven-aether-provider-3.3.9-all.jar;maven3/lib/plexus-utils-2.0.6.jar"/>
<languageInjector implementation="org.jetbrains.idea.maven.plugins.api.MavenPluginConfigurationLanguageInjector"/>