diff --git a/biz.aQute.bndlib/src/aQute/bnd/osgi/OSInformation.java b/biz.aQute.bndlib/src/aQute/bnd/osgi/OSInformation.java index be85917554..5be55527ba 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/osgi/OSInformation.java +++ b/biz.aQute.bndlib/src/aQute/bnd/osgi/OSInformation.java @@ -11,9 +11,9 @@ import aQute.bnd.osgi.resource.CapabilityBuilder; import aQute.bnd.osgi.resource.ResourceUtils; -import aQute.bnd.version.MavenVersion; import aQute.bnd.version.Version; import aQute.lib.strings.Strings; +import aQute.service.reporter.Reporter; /** * OS specific information, used by the native_capability macro for @@ -187,14 +187,7 @@ static class NativeCapability { * @return a provide capability clause for the native environment */ public static String getNativeCapabilityClause(Processor p, String args[]) throws Exception { - NativeCapability clause = new NativeCapability(); - - parseNativeCapabilityArgs(p, args, clause); - - validateNativeCapability(clause); - - Capability cap = createCapability(clause); - + Capability cap = getNativeCapability(p, args); return ResourceUtils.toProvideCapability(cap); } @@ -217,32 +210,9 @@ static void validateNativeCapability(NativeCapability clause) { throw new IllegalArgumentException("processor/osgi.native.processor not set in ${native_capability}"); } - static void parseNativeCapabilityArgs(Processor p, String[] args, NativeCapability clause) throws Exception { - if (args.length == 1) { - - OSInformation osi = new OSInformation(); - clause.osname.addAll(Strings.split(osi.osnames)); - clause.osversion = osi.osversion; - String[] processorAliases = getProcessorAliases(System.getProperty("os.arch")); - if (processorAliases != null && processorAliases.length > 0) { - Collections.addAll(clause.processor, processorAliases); - } - clause.language = Locale.getDefault() - .toString(); - - StringBuilder sb = new StringBuilder(); - sb.append("osname=") - .append(System.getProperty("os.name")); - sb.append(";") - .append("osversion=") - .append(MavenVersion.cleanupVersion(System.getProperty("os.version"))); - sb.append(";") - .append("processor=") - .append(System.getProperty("os.arch")); - sb.append(";") - .append("lang=") - .append(clause.language); - String advice = sb.toString(); + static void parseNativeCapabilityArgs(Reporter p, String[] args, NativeCapability clause) throws Exception { + if (args.length <= 1) { + setDefaults(clause); } else { String osname = null; @@ -321,6 +291,18 @@ static void parseNativeCapabilityArgs(Processor p, String[] args, NativeCapabili } } + private static void setDefaults(NativeCapability clause) { + OSInformation osi = new OSInformation(); + clause.osname.addAll(Strings.split(osi.osnames)); + clause.osversion = osi.osversion; + String[] processorAliases = getProcessorAliases(System.getProperty("os.arch")); + if (processorAliases != null && processorAliases.length > 0) { + Collections.addAll(clause.processor, processorAliases); + } + clause.language = Locale.getDefault() + .toString(); + } + public static class OSNameVersion { public Version osversion; public String osnames; @@ -370,4 +352,35 @@ public static OSNameVersion getOperatingSystemAliases(String sysPropOsName, Stri } return nc; } + + /** + * Return a native capability based on the given specification. + * + * @param p the processor for the error reporting + * @param args a set of assignments. The following keys are supported: + * osgi.native.processor,osname, osgi.native.osname, + * osversion,osgi.native.osversion, osgi.native.language, lang + * @return a native capability + */ + + public static Capability getNativeCapability(Reporter p, String... args) throws Exception { + NativeCapability clause = new NativeCapability(); + + parseNativeCapabilityArgs(p, args, clause); + + validateNativeCapability(clause); + + return createCapability(clause); + } + + /** + * Return the default capability for the current platform + * + * @return a default capability for the current platform + */ + public static Capability getDefaultNativeCapability() throws Exception { + NativeCapability clause = new NativeCapability(); + setDefaults(clause); + return createCapability(clause); + } } diff --git a/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java b/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java index cadb91fd2d..ba0255c836 100644 --- a/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java +++ b/biz.aQute.resolve/src/biz/aQute/resolve/BndrunResolveContext.java @@ -20,6 +20,7 @@ import java.util.jar.Manifest; import org.osgi.framework.namespace.IdentityNamespace; +import org.osgi.framework.namespace.NativeNamespace; import org.osgi.resource.Capability; import org.osgi.resource.Requirement; import org.osgi.resource.Resource; @@ -38,6 +39,7 @@ import aQute.bnd.osgi.Constants; import aQute.bnd.osgi.Domain; import aQute.bnd.osgi.Jar; +import aQute.bnd.osgi.OSInformation; import aQute.bnd.osgi.Processor; import aQute.bnd.osgi.repository.AggregateRepository; import aQute.bnd.osgi.repository.AugmentRepository; @@ -59,6 +61,8 @@ * BndEditModel & Project */ public class BndrunResolveContext extends AbstractResolveContext { + private static final String ALWAYS_TRUE = "(!(_+_foo=bar))"; + private final static Logger logger = LoggerFactory .getLogger(BndrunResolveContext.class); @@ -226,6 +230,11 @@ public synchronized void init() { loadPath(system, runpath, Constants.RUNPATH); } + if (system.findCapabilities(NativeNamespace.NATIVE_NAMESPACE, ALWAYS_TRUE) + .isEmpty()) { + Capability cap = OSInformation.getDefaultNativeCapability(); + system.addCapability(cap); + } // // We've not gathered all the capabilities of the system // so we can create the resource and set it as the system resource diff --git a/biz.aQute.resolve/src/biz/aQute/resolve/ProjectResolver.java b/biz.aQute.resolve/src/biz/aQute/resolve/ProjectResolver.java index 5a6e71ec27..4bc1ea79f3 100644 --- a/biz.aQute.resolve/src/biz/aQute/resolve/ProjectResolver.java +++ b/biz.aQute.resolve/src/biz/aQute/resolve/ProjectResolver.java @@ -32,6 +32,8 @@ * which is a Run which extends Project). This class is supposed to simplify the * sometimes bewildering number of moving cogs in resolving. It is a processor * and uses the facilities to provide the different logging schemes used. + *

+ * See RunResolution for a replacement */ @Deprecated diff --git a/biz.aQute.resolve/test/biz/aQute/resolve/ResolveTest.java b/biz.aQute.resolve/test/biz/aQute/resolve/ResolveTest.java index 9dcfd7cde9..1ae8cc2aae 100644 --- a/biz.aQute.resolve/test/biz/aQute/resolve/ResolveTest.java +++ b/biz.aQute.resolve/test/biz/aQute/resolve/ResolveTest.java @@ -124,6 +124,40 @@ public void testDefaultVersionsForJava() throws Exception { } } + /** + * Check if we add a native capability when no native is around + */ + + @Test + public void testDefaultNativeCapability() throws Exception { + try (Bndrun run = (Bndrun) Bndrun.createRun(null, IO.getFile("testdata/nativecap/native.bndrun"))) { + // require _any_ native capability + run.setProperty("-runrequires", "osgi.native;filter:=\"(osgi.native.osname=*)\""); + RunResolution resolve = run.resolve(); + // only resolves when there was at least 1 native capability + assertThat(resolve.getRequired()).hasSize(1); + } + + } + + /** + * Check if we do not add a native capability when no native is around + */ + + @Test + public void testNoDefaultNativeCapability() throws Exception { + try (Bndrun run = (Bndrun) Bndrun.createRun(null, IO.getFile("testdata/nativecap/native.bndrun"))) { + // require _any_ native capability + run.setProperty("-runrequires", "osgi.native;filter:=\"(osgi.native.osname=*)\""); + // provide an invalid native capability so the previous filter does + // not match but we also do not add a capability + run.setProperty("-runsystemcapabilities", "osgi.native;foobar=1"); + RunResolution resolve = run.resolve(); + assertThat(resolve.getRequired()).isNull(); + } + + } + /** * The enRoute base guard resolved but is missing bundles, the runbundles do * not run diff --git a/biz.aQute.resolve/testdata/nativecap/native.bndrun b/biz.aQute.resolve/testdata/nativecap/native.bndrun new file mode 100644 index 0000000000..e69de29bb2