org.eclipse.tycho.compiler.AbstractOsgiCompilerMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tycho-compiler-plugin
Show all versions of tycho-compiler-plugin
A plugin for compiling OSGi bundles
/*
* Copyright 2006 The Apache Software Foundation.
*
* 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.eclipse.tycho.compiler;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.ProjectArtifact;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.toolchain.ToolchainManagerPrivate;
import org.apache.maven.toolchain.java.DefaultJavaToolChain;
import org.codehaus.plexus.compiler.CompilerConfiguration;
import org.codehaus.plexus.compiler.util.scan.InclusionScanException;
import org.codehaus.plexus.compiler.util.scan.SimpleSourceInclusionScanner;
import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner;
import org.codehaus.plexus.compiler.util.scan.StaleSourceScanner;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.tycho.classpath.ClasspathEntry;
import org.eclipse.tycho.classpath.ClasspathEntry.AccessRule;
import org.eclipse.tycho.classpath.JavaCompilerConfiguration;
import org.eclipse.tycho.classpath.SourcepathEntry;
import org.eclipse.tycho.core.BundleProject;
import org.eclipse.tycho.core.TychoConstants;
import org.eclipse.tycho.core.TychoProject;
import org.eclipse.tycho.core.ee.StandardExecutionEnvironment;
import org.eclipse.tycho.core.ee.shared.ExecutionEnvironment;
import org.eclipse.tycho.core.maven.ToolchainProvider;
import org.eclipse.tycho.core.maven.ToolchainProvider.JDKUsage;
import org.eclipse.tycho.core.osgitools.BundleReader;
import org.eclipse.tycho.core.osgitools.DefaultClasspathEntry;
import org.eclipse.tycho.core.osgitools.DefaultClasspathEntry.DefaultAccessRule;
import org.eclipse.tycho.core.osgitools.DefaultReactorProject;
import org.eclipse.tycho.core.osgitools.OsgiBundleProject;
import org.eclipse.tycho.core.osgitools.project.BuildOutputJar;
import org.eclipse.tycho.core.osgitools.project.EclipsePluginProject;
import org.eclipse.tycho.core.utils.TychoProjectUtils;
import org.eclipse.tycho.runtime.Adaptable;
import copied.org.apache.maven.plugin.AbstractCompilerMojo;
public abstract class AbstractOsgiCompilerMojo extends AbstractCompilerMojo implements JavaCompilerConfiguration,
Adaptable {
public static final String RULE_SEPARATOR = File.pathSeparator;
/**
* Exclude all but keep looking for other another match
*/
public static final String RULE_EXCLUDE_ALL = "?**/*";
private static final Set MATCH_ALL = Collections.singleton("**/*");
private static final String PREFS_FILE_PATH = ".settings" + File.separator + "org.eclipse.jdt.core.prefs";
@Parameter(property = "project", readonly = true)
private MavenProject project;
/**
* Transitively add specified maven artifacts to compile classpath in addition to elements
* calculated according to OSGi rules. All packages from additional entries will be accessible
* at compile time.
*
* Useful when OSGi runtime classpath contains elements not defined using normal dependency
* mechanisms. For example, when Eclipse Equinox is started from application server with
* -Dosgi.parentClassloader=fwk parameter.
*/
@Parameter
private Dependency[] extraClasspathElements;
@Parameter(property = "session", readonly = true)
private MavenSession session;
@Component
private RepositorySystem repositorySystem;
/**
* Which JDK to use for compilation. Default value is SYSTEM which means the currently running
* JDK. If BREE is specified, MANIFEST header Bundle-RequiredExecutionEnvironment
* is used to define the JDK to compile against. In this case, you need to provide a toolchains.xml
* configuration file. The value of BREE will be matched against the id of the toolchain
* elements in toolchains.xml. Example:
*
*
* <toolchains>
* <toolchain>
* <type>jdk</type>
* <provides>
* <id>J2SE-1.5</id>
* </provides>
* <configuration>
* <jdkHome>/path/to/jdk/1.5</jdkHome>
* </configuration>
* </toolchain>
* </toolchains>
*
*
* The default value of the bootclasspath used for compilation is
* <jdkHome>/lib/*;<jdkHome>/lib/ext/*;<jdkHome>/lib/endorsed/* .
*
* For JDKs with different filesystem layouts, the bootclasspath can be specified explicitly in
* the configuration section.
*
* Example:
*
*
* <configuration>
* <jdkHome>/path/to/jdk/1.5</jdkHome>
* <bootClassPath>
* <includes>
* <include>jre/lib/amd64/default/jclSC160/*.jar</include>
* </includes>
* <excludes>
* <exclude>**/alt-*.jar</exclude>
* </excludes>
* </bootClassPath>
* </configuration>
*
*
*/
@Parameter(defaultValue = "SYSTEM")
private JDKUsage useJDK;
@Component
private ToolchainManagerPrivate toolChainManager;
/**
* A list of inclusion filters for the compiler.
*/
@Parameter
private Set includes = new HashSet<>();
/**
* A list of exclusion filters for the compiler.
*/
@Parameter
private Set excludes = new HashSet<>();
/**
* A list of exclusion filters for non-java resource files which should not be copied to the
* output directory.
*/
@Parameter
private Set excludeResources = new HashSet<>();
/**
* Whether a bundle is required to explicitly import non-java.* packages from the JDK. This is
* the design-time equivalent to the equinox runtime option osgi.compatibility.bootdelegation.
*/
@Parameter(defaultValue = "false")
private boolean requireJREPackageImports;
/**
* If set to false
(the default) issue a warning if effective compiler target level
* is incompatible with bundle minimal execution environment. If set to true
will
* fail the build if effective compiler target and minimal BREE are incompatible.
*/
@Parameter(defaultValue = "false")
private boolean strictCompilerTarget;
/**
* If set to true
, the settings file
* ${project.basedir}/.settings/org.eclipse.jdt.core.prefs will be passed to the compiler. If
* the file is not present, the build will not fail.
*/
@Parameter(defaultValue = "true")
private boolean useProjectSettings;
/**
* Current build output jar
*/
private BuildOutputJar outputJar;
@Component(role = TychoProject.class)
private Map projectTypes;
@Component
private BundleReader bundleReader;
/**
* Whether all resources in the source folders should be copied to
* ${project.build.outputDirectory}.
*
* true
(default) means that all resources are copied from the source folders to
* ${project.build.outputDirectory}
.
*
* false
means that no resources are copied from the source folders to
* ${project.build.outputDirectory}
.
*
* Set this to false
in case you want to keep resources separate from java files in
* src/main/resources
and handle them using maven-resources-plugin
* (e.g. for resource
* filtering.
*
*/
@Parameter(defaultValue = "true")
private boolean copyResources;
/**
* The directory where the compiler log files should be placed. For each output jar a log file
* will be created and stored in this directory. Logging into files is only enabled if
* {@link #log} is specified. Default: ${project.build.directory}/compile-logs
*/
@Parameter(defaultValue = "${project.build.directory}/compile-logs")
private File logDirectory;
/**
* The format of the compiler log file. plain
will log into a plain text file
* (.log), xml
will log in xml format (.xml). If omitted, no logging into files is
* done. The log file name is derived from the jar file name:
*
*
* Example:
* build.properties:
*
* output.lib1/library.jar = lib1bin/
* output.lib2/library.jar = lib2bin/
* output.. = bin/
*
* And a configuration:
*
* <configuration>
* <logEnabled>true</logEnabled>
* <logDirectory>${project.build.directory}/logfiles</logDirectory>
* <log>xml</log>
* </configuration>
*
* Will produce the following log files
*
* ${project.build.directory}/logfiles/@dot.xml
* ${project.build.directory}/logfiles/lib1_library.jar.xml
* ${project.build.directory}/logfiles/lib2_library.jar.xml
*
*/
@Parameter
private String log;
@Component
ToolchainProvider toolchainProvider;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
StandardExecutionEnvironment[] manifestBREEs = bundleReader.loadManifest(project.getBasedir())
.getExecutionEnvironments();
getLog().debug("Manifest BREEs: " + Arrays.toString(manifestBREEs));
getLog().debug("Effective EE: " + getTargetExecutionEnvironment());
String effectiveTargetLevel = getTargetLevel();
getLog().debug("Effective source/target: " + getSourceLevel() + "/" + effectiveTargetLevel);
checkTargetLevelCompatibleWithManifestBREEs(effectiveTargetLevel, manifestBREEs);
for (BuildOutputJar jar : getEclipsePluginProject().getOutputJars()) {
this.outputJar = jar;
this.outputJar.getOutputDirectory().mkdirs();
super.execute();
doCopyResources();
}
// this does not include classes from nested jars
BuildOutputJar dotOutputJar = getEclipsePluginProject().getDotOutputJar();
if (dotOutputJar != null) {
project.getArtifact().setFile(dotOutputJar.getOutputDirectory());
}
}
/*
* mimics the behavior of the PDE incremental builder which by default copies all (non-java)
* resource files in source directories into the target folder
*/
private void doCopyResources() throws MojoExecutionException {
if (!copyResources) {
return;
}
for (String sourceRoot : getCompileSourceRoots()) {
// StaleSourceScanner.getIncludedSources throws IllegalStateException
// if directory doesnt't exist
File sourceRootFile = new File(sourceRoot);
if (!sourceRootFile.isDirectory()) {
getLog().warn("Source directory " + sourceRoot + " does not exist");
continue;
}
Set excludes = new HashSet<>();
excludes.addAll(excludeResources);
excludes.addAll(getEclipsePluginProject().getBuildProperties().getBinExcludes());
excludes.add("**/*.java");
StaleSourceScanner scanner = new StaleSourceScanner(0L, MATCH_ALL, excludes);
CopyMapping copyMapping = new CopyMapping();
scanner.addSourceMapping(copyMapping);
try {
scanner.getIncludedSources(sourceRootFile, this.outputJar.getOutputDirectory());
for (CopyMapping.SourceTargetPair sourceTargetPair : copyMapping.getSourceTargetPairs()) {
FileUtils.copyFile(new File(sourceRoot, sourceTargetPair.source), sourceTargetPair.target);
}
} catch (InclusionScanException e) {
throw new MojoExecutionException("Exception while scanning for resource files in " + sourceRoot, e);
} catch (IOException e) {
throw new MojoExecutionException("Exception copying resource files from " + sourceRoot + " to "
+ this.outputJar.getOutputDirectory(), e);
}
}
}
/** public for testing purposes */
public EclipsePluginProject getEclipsePluginProject() throws MojoExecutionException {
return ((OsgiBundleProject) getBundleProject()).getEclipsePluginProject(DefaultReactorProject.adapt(project));
}
@Override
protected File getOutputDirectory() {
return outputJar.getOutputDirectory();
}
@Override
public List getClasspathElements() throws MojoExecutionException {
final List classpath = new ArrayList<>();
for (ClasspathEntry cpe : getClasspath()) {
for (File location : cpe.getLocations()) {
classpath.add(location.getAbsolutePath() + toString(cpe.getAccessRules()));
}
}
return classpath;
}
private BundleProject getBundleProject() throws MojoExecutionException {
TychoProject projectType = projectTypes.get(project.getPackaging());
if (!(projectType instanceof BundleProject)) {
throw new MojoExecutionException("Not a bundle project " + project.toString());
}
return (BundleProject) projectType;
}
private String toString(List rules) {
StringBuilder result = new StringBuilder(); // include all
if (rules != null) {
result.append("[");
for (AccessRule rule : rules) {
if (result.length() > 1)
result.append(RULE_SEPARATOR);
result.append(rule.isDiscouraged() ? "~" : "+");
result.append(rule.getPattern());
}
if (result.length() > 1)
result.append(RULE_SEPARATOR);
result.append(RULE_EXCLUDE_ALL);
result.append("]");
} else {
// include everything, not strictly necessary, but lets make this obvious
//result.append("[+**/*]");
}
return result.toString();
}
@Override
protected final List getCompileSourceRoots() throws MojoExecutionException {
ArrayList roots = new ArrayList<>();
for (File folder : outputJar.getSourceFolders()) {
roots.add(new File(folder.getAbsoluteFile().toURI().normalize()).toString());
}
return roots;
}
@Override
public List getSourcepath() throws MojoExecutionException {
ArrayList entries = new ArrayList<>();
for (BuildOutputJar jar : getEclipsePluginProject().getOutputJars()) {
final File outputDirectory = jar.getOutputDirectory();
for (final File sourcesRoot : jar.getSourceFolders()) {
SourcepathEntry entry = new SourcepathEntry() {
@Override
public File getSourcesRoot() {
return sourcesRoot;
}
@Override
public File getOutputDirectory() {
return outputDirectory;
}
@Override
public List getIncludes() {
return null;
}
@Override
public List getExcludes() {
return null;
}
};
entries.add(entry);
}
}
return entries;
}
@Override
protected SourceInclusionScanner getSourceInclusionScanner(int staleMillis) {
SourceInclusionScanner scanner = null;
if (includes.isEmpty() && excludes.isEmpty()) {
scanner = new StaleSourceScanner(staleMillis);
} else {
if (includes.isEmpty()) {
includes.add("**/*.java");
}
scanner = new StaleSourceScanner(staleMillis, includes, excludes);
}
return scanner;
}
@Override
protected SourceInclusionScanner getSourceInclusionScanner(String inputFileEnding) {
SourceInclusionScanner scanner = null;
if (includes.isEmpty() && excludes.isEmpty()) {
includes = Collections.singleton("**/*." + inputFileEnding);
scanner = new SimpleSourceInclusionScanner(includes, Collections. emptySet());
} else {
if (includes.isEmpty()) {
includes.add("**/*." + inputFileEnding);
}
scanner = new SimpleSourceInclusionScanner(includes, excludes);
}
return scanner;
}
@Override
protected CompilerConfiguration getCompilerConfiguration(List compileSourceRoots)
throws MojoExecutionException, MojoFailureException {
CompilerConfiguration compilerConfiguration = super.getCompilerConfiguration(compileSourceRoots);
if (useProjectSettings) {
String prefsFilePath = project.getBasedir() + File.separator + PREFS_FILE_PATH;
if (!new File(prefsFilePath).exists()) {
getLog().warn(
"Parameter 'useProjectSettings' is set to true, but preferences file '" + prefsFilePath
+ "' could not be found!");
} else {
compilerConfiguration.addCompilerCustomArgument("-properties", prefsFilePath);
}
}
String encoding = getEclipsePluginProject().getBuildProperties().getJarToJavacDefaultEncodingMap()
.get(outputJar.getName());
if (encoding != null) {
compilerConfiguration.setSourceEncoding(encoding);
}
configureSourceAndTargetLevel(compilerConfiguration);
configureJavaHome(compilerConfiguration);
configureBootclasspathAccessRules(compilerConfiguration);
configureCompilerLog(compilerConfiguration);
return compilerConfiguration;
}
private void configureCompilerLog(CompilerConfiguration compilerConfiguration) throws MojoFailureException {
if (log == null) {
return;
}
if (compilerConfiguration.getCustomCompilerArgumentsAsMap().containsKey("-log")) {
throw new MojoFailureException("Compiler logging is configured by the 'log' compiler"
+ " plugin parameter and the custom compiler argument '-log'. Only either of them is allowed.");
}
logDirectory.mkdirs();
String logFileName = null;
if (".".equals(outputJar.getName())) {
logFileName = "@dot";
} else {
logFileName = outputJar.getName().replaceAll("/", "_");
}
String logPath = logDirectory.getAbsolutePath();
if (!logPath.endsWith(File.separator)) {
logPath = logPath + File.separator;
}
String fileExtension = log;
if ("plain".equals(log)) {
fileExtension = "log";
}
logPath = logPath + logFileName + "." + fileExtension;
compilerConfiguration.addCompilerCustomArgument("-log", logPath);
}
private void configureBootclasspathAccessRules(CompilerConfiguration compilerConfiguration)
throws MojoExecutionException {
List accessRules = new ArrayList<>();
if (requireJREPackageImports) {
accessRules.addAll(getStrictBootClasspathAccessRules());
} else {
accessRules.add(new DefaultAccessRule("java/**", false));
for (String pkg : getTargetExecutionEnvironment().getSystemPackages()) {
accessRules.add(new DefaultAccessRule(pkg.trim().replace('.', '/') + "/*", false));
}
// now add packages exported by framework extension bundles
accessRules.addAll(getBundleProject().getBootClasspathExtraAccessRules(project));
}
if (accessRules.size() > 0) {
compilerConfiguration
.addCompilerCustomArgument("org.osgi.framework.system.packages", toString(accessRules));
}
}
@SuppressWarnings("unchecked")
private List getStrictBootClasspathAccessRules() throws MojoExecutionException {
return (List) project
.getContextValue(TychoConstants.CTX_ECLIPSE_PLUGIN_STRICT_BOOTCLASSPATH_ACCESSRULES);
}
private void configureJavaHome(CompilerConfiguration compilerConfiguration) throws MojoExecutionException {
if (useJDK != JDKUsage.BREE) {
return;
}
String toolchainId = getTargetExecutionEnvironment().getProfileName();
DefaultJavaToolChain toolChain = toolchainProvider.findMatchingJavaToolChain(session, toolchainId);
if (toolChain == null) {
throw new MojoExecutionException("useJDK = BREE configured, but no toolchain of type 'jdk' with id '"
+ toolchainId + "' found. See http://maven.apache.org/guides/mini/guide-using-toolchains.html");
}
compilerConfiguration.addCompilerCustomArgument("use.java.home", toolChain.getJavaHome());
configureBootClassPath(compilerConfiguration, toolChain);
}
private void configureBootClassPath(CompilerConfiguration compilerConfiguration, DefaultJavaToolChain javaToolChain) {
Xpp3Dom config = (Xpp3Dom) javaToolChain.getModel().getConfiguration();
if (config != null) {
Xpp3Dom bootClassPath = config.getChild("bootClassPath");
if (bootClassPath != null) {
Xpp3Dom includeParent = bootClassPath.getChild("includes");
if (includeParent != null) {
Xpp3Dom[] includes = includeParent.getChildren("include");
if (includes.length > 0) {
compilerConfiguration.addCompilerCustomArgument(
"-bootclasspath",
scanBootclasspath(javaToolChain.getJavaHome(), includes,
bootClassPath.getChild("excludes")));
}
}
}
}
}
private String scanBootclasspath(String javaHome, Xpp3Dom[] includes, Xpp3Dom excludeParent) {
DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir(javaHome);
scanner.setIncludes(getValues(includes));
if (excludeParent != null) {
Xpp3Dom[] excludes = excludeParent.getChildren("exclude");
if (excludes.length > 0) {
scanner.setExcludes(getValues(excludes));
}
}
scanner.scan();
StringBuilder bootClassPath = new StringBuilder();
String[] includedFiles = scanner.getIncludedFiles();
for (int i = 0; i < includedFiles.length; i++) {
if (i > 0) {
bootClassPath.append(File.pathSeparator);
}
bootClassPath.append(new File(javaHome, includedFiles[i]).getAbsolutePath());
}
return bootClassPath.toString();
}
private static String[] getValues(Xpp3Dom[] doms) {
String[] values = new String[doms.length];
for (int i = 0; i < values.length; i++) {
values[i] = doms[i].getValue();
}
return values;
}
private void configureSourceAndTargetLevel(CompilerConfiguration compilerConfiguration)
throws MojoExecutionException {
ExecutionEnvironment ee = getTargetExecutionEnvironment();
compilerConfiguration.setSourceVersion(getSourceLevel(ee));
compilerConfiguration.setTargetVersion(getTargetLevel(ee));
}
private ExecutionEnvironment getTargetExecutionEnvironment() throws MojoExecutionException {
// never null
return TychoProjectUtils.getExecutionEnvironmentConfiguration(project).getFullSpecification();
}
@Override
public List getClasspath() throws MojoExecutionException {
TychoProject projectType = getBundleProject();
ArrayList classpath = new ArrayList<>(
((BundleProject) projectType).getClasspath(project));
if (extraClasspathElements != null) {
ArtifactRepository localRepository = session.getLocalRepository();
List remoteRepositories = project.getRemoteArtifactRepositories();
for (Dependency extraDependency : extraClasspathElements) {
Artifact artifact = repositorySystem.createDependencyArtifact(extraDependency);
ArtifactResolutionRequest request = new ArtifactResolutionRequest();
request.setArtifact(artifact);
request.setLocalRepository(localRepository);
request.setRemoteRepositories(remoteRepositories);
request.setResolveRoot(true);
request.setResolveTransitively(true);
ArtifactResolutionResult result = repositorySystem.resolve(request);
if (result.hasExceptions()) {
throw new MojoExecutionException("Could not resolve extra classpath entry", result.getExceptions()
.get(0));
}
for (Artifact b : result.getArtifacts()) {
MavenProject bProject = null;
if (b instanceof ProjectArtifact) {
bProject = ((ProjectArtifact) b).getProject();
}
ArrayList bLocations = new ArrayList<>();
bLocations.add(b.getFile()); // TODO properly handle multiple project locations maybe
classpath.add(new DefaultClasspathEntry(DefaultReactorProject.adapt(bProject), null, bLocations,
null));
}
}
}
return classpath;
}
@Override
public String getExecutionEnvironment() throws MojoExecutionException {
return getTargetExecutionEnvironment().getProfileName();
}
@Override
public String getSourceLevel() throws MojoExecutionException {
return getSourceLevel(getTargetExecutionEnvironment());
}
private String getSourceLevel(ExecutionEnvironment ee) throws MojoExecutionException {
// first, explicit POM configuration
if (source != null) {
return source;
}
// then, build.properties
String javacSource = getEclipsePluginProject().getBuildProperties().getJavacSource();
if (javacSource != null) {
return javacSource;
}
// then, execution environment
String eeSource = ee.getCompilerSourceLevelDefault();
if (eeSource != null) {
return eeSource;
}
return DEFAULT_SOURCE_VERSION;
}
@Override
public String getTargetLevel() throws MojoExecutionException {
return getTargetLevel(getTargetExecutionEnvironment());
}
public String getTargetLevel(ExecutionEnvironment ee) throws MojoExecutionException {
// first, explicit POM configuration
if (target != null) {
return target;
}
// then, build.properties
String javacTarget = getEclipsePluginProject().getBuildProperties().getJavacTarget();
if (javacTarget != null) {
return javacTarget;
}
// then, execution environment
String eeTarget = ee.getCompilerTargetLevelDefault();
if (eeTarget != null) {
return eeTarget;
}
return DEFAULT_TARGET_VERSION;
}
private void checkTargetLevelCompatibleWithManifestBREEs(String effectiveTargetLevel,
StandardExecutionEnvironment[] manifestBREEs) throws MojoExecutionException {
List incompatibleBREEs = new ArrayList<>();
for (StandardExecutionEnvironment ee : manifestBREEs) {
if (!ee.isCompatibleCompilerTargetLevel(effectiveTargetLevel)) {
incompatibleBREEs.add(ee.getProfileName() + " (assumes " + ee.getCompilerTargetLevelDefault() + ")");
}
}
if (!incompatibleBREEs.isEmpty()) {
String message = "The effective compiler target level " + effectiveTargetLevel
+ " is incompatible with the following OSGi execution environments: " + incompatibleBREEs + " @ "
+ project;
if (strictCompilerTarget) {
throw new MojoExecutionException(message);
}
getLog().warn(message);
}
}
@Override
public T getAdapter(Class adapter) {
if (adapter.isAssignableFrom(JavaCompilerConfiguration.class)) {
return adapter.cast(this);
}
return null;
}
}