Unable to include dynlib resources
I am trying to include some native libraries which are in a maven repository using:
lib/=${repo;org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-x86-64;4.4.0.-dcm};lib:=true,\
lib/=${repo;org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-x86;4.4.0.-dcm};lib:=true,\
lib/=${repo;org.weasis.thirdparty.org.opencv:libopencv_java:jnilib:macosx-x86-64;4.4.0.-dcm};lib:=true,\
lib/=${repo;org.weasis.thirdparty.org.opencv:opencv_java:dll:windows-x86-64;4.4.0.-dcm};lib:=true,\
lib/=${repo;org.weasis.thirdparty.org.opencv:opencv_java:dll:windows-x86;4.4.0.-dcm};lib:=true,\
First of all the 4.4.0.-dcm format really threw me. It is bizarre having to put . before the -. I couldn't find the documentation for this. I did eventually find the regex in:
https://github.com/bndtools/bnd/blob/d8755373c89f689eb94f6819007f2f54f3fee623/biz.aQute.bndlib/src/aQute/bnd/version/MavenVersion.java#L17
After working around that gotcha, these all work fine except for the macOS one. It will fail because a file that ends in lib is assumed to be some kind of library:
https://github.com/bndtools/bnd/blob/d8755373c89f689eb94f6819007f2f54f3fee623/biz.aQute.bndlib/src/aQute/bnd/build/Project.java#L1475-L1479
When then blows up because of course a dynlib is a dynamically linked library, not a text file so this doesn't work: https://github.com/bndtools/bnd/blob/d8755373c89f689eb94f6819007f2f54f3fee623/biz.aQute.bndlib/src/aQute/bnd/build/Container.java#L244-L261
Thanks @steinybot for the report.
Any reason why you are using lib:=true ?
According to the example https://bnd.bndtools.org/instructions/includeresource.html#assignment-form
-includeresource: libraries/fancylibrary.jar=lib/fancylibrary-3.12.jar; lib:=trueCopy lib/fancylibrary-3.1.2.jar from project into libraries folder of the target JAR, and place it on the Bundle-Classpath (BCP). It will make sure the BCP starts with ‘.’ and then each include resource that is included will be added to the BCP
Is that needed for a native library? Maybe if it is not on the bundle classpath then Bnd will not process it?
Regarding Problem a) the MavenVersion.VERSIONSTRING: I just found this commit which did something on the version parsing https://github.com/bndtools/bnd/commit/d590cf35207b8a34cecc70bbcfbdd01ae82dc754 So maybe this gives clues why it is the way it is or maybe there is a bug.
Regarding your version problem:
Could you provide some more info?
- What is the exact path / folder structure to that library in your maven repo? (org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-x86-64;4.4.0-dcm)
- What kind of error do you get, where? Any stacktrace / call stack, which helps finding the code path which causes you trouble?
I quickly checked new MavenVersion("4.4.0-dcm") and it accepts it. Although MavenVersion.cleanupVersion() turns it into "4.4.0.dcm" because it assumes dcm is the qualifier.
So I would like to find out how things look on your file system / local maven repo, to find the problematic code path which forces you to add the dash (4.4.0.-dcm)
UPDATE: The method complaining about "4.4.0-dcm" is: aQute.bnd.osgi.Verifier.isVersion(String)
- Verifier.isVersion("4.4.0-dcm") -> false
- Verifier.isVersion("4.4.0.-dcm") -> true
I believe the latter works because 4.4.0.-dmc can properly parse by into the major/micro/minor/qualifier parts
new aQute.bnd.version.Version.Version("4.4.0.-dmc")
The regEx complaining is
https://github.com/bndtools/bnd/blob/d8755373c89f689eb94f6819007f2f54f3fee623/biz.aQute.bndlib/src/aQute/bnd/osgi/Verifier.java#L103
which is called as part of
https://github.com/bndtools/bnd/blob/d8755373c89f689eb94f6819007f2f54f3fee623/biz.aQute.bndlib/src/aQute/bnd/build/Project.java#L1286-L1290
which is called as part of the ${repo;} macro (https://bnd.bndtools.org/macros/repo.html) you use in your -includeresource
I have a suspicion, but I first want to wait for you to get back to get a sense of confirmation.
Then we could think about if and what could be done. I believe it is some kind of discrepancy between OSGi Version Strings and Maven Version Strings and what is expected/allowed in the ${repo;} macro (which calls aQute.bnd.build.Project.getBundle(String, String, Strategy, Map<String, String>))
Any reason why you are using lib:=true ?
Good catch. That was a mistake. That causes it to fail later on.
Hmm yeah, I would have expected this test to fail: https://github.com/bndtools/bnd/blob/6e0b150b13324e425e4d1deedaedbd42bd7f6bed/biz.aQute.bndlib.tests/test/test/MavenVersionTest.java#L164-L165
Oh right yeah I think you are right, it was Verifier not MavenVersion. I was trying to find it after the fact via the web search as I have to report from my personal GitHub account since we are EMU and can't comment on public issues.
The repository structure is here: https://github.com/nroduit/mvn-repo/tree/master/org/weasis/thirdparty/org/opencv/libopencv_java/4.4.0-dcm
It's weird I know, but it works. You can see that the linux and mac libraries are in the same location. The pom.xml only specifies <packaging>so</packaging> which could be part of the problem but I don't think so.
I thought that the resolution was working ok and it ends up with the correct file path in the local cache but now I'm not so sure. I don't have my debug environment setup to debug this properly anymore. Here is what I have locally:
As for the exception, with:
-includeresource: \
linux-x86-64/libopencv_java.so=${repo;org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-x86-64;4.6.0.-dcm},\
windows-x86-64/opencv_java.dll=${repo;org.weasis.thirdparty.org.opencv:opencv_java:dll:windows-x86-64;4.6.0.-dcm},\
macosx-x86-64/libopencv_java.jnilib=${repo;org.weasis.thirdparty.org.opencv:libopencv_java:jnilib:macosx-x86-64;4.6.0.-dcm}
I get:
warning: No translation found for macro: repo;org.weasis.thirdparty.org.opencv:libopencv_java:jnilib:macosx-x86-64;4.6.0.-dcm
error : /Users/jason.pickens/.m2/repository/org/weasis/thirdparty/org/opencv/libopencv_java/4.6.0-dcm/libopencv_java-4.6.0-dcm-macosx-x86-64.jnilib, for cmd: repo, arguments; [repo, org.weasis.thirdparty.org.opencv:libopencv_java:jnilib:macosx-x86-64, 4.6.0.-dcm]
error : Exception: java.util.regex.PatternSyntaxException: Unclosed group near index 9
\$(?:repo
at java.base/java.util.regex.Pattern.error(Pattern.java:2028)
at java.base/java.util.regex.Pattern.accept(Pattern.java:1878)
at java.base/java.util.regex.Pattern.group0(Pattern.java:3063)
at java.base/java.util.regex.Pattern.sequence(Pattern.java:2124)
at java.base/java.util.regex.Pattern.expr(Pattern.java:2069)
at java.base/java.util.regex.Pattern.compile(Pattern.java:1783)
at java.base/java.util.regex.Pattern.<init>(Pattern.java:1429)
at java.base/java.util.regex.Pattern.compile(Pattern.java:1095)
at aQute.libg.glob.Glob.toPattern(Glob.java:158)
at aQute.libg.glob.Glob.<init>(Glob.java:31)
at aQute.libg.glob.Glob.<init>(Glob.java:27)
at aQute.bnd.osgi.Analyzer.jarsFromName(Analyzer.java:1779)
at aQute.bnd.osgi.Analyzer.getJarsFromName(Analyzer.java:1767)
at aQute.bnd.osgi.Builder.noSuchFile(Builder.java:1247)
at aQute.bnd.osgi.Builder.doIncludeResource(Builder.java:990)
at aQute.bnd.osgi.Builder.doIncludeResource(Builder.java:922)
at aQute.bnd.osgi.Builder.doIncludeResource(Builder.java:915)
at aQute.bnd.osgi.Builder.doIncludeResources(Builder.java:909)
at aQute.bnd.osgi.Builder.build(Builder.java:119)
at aQute.bnd.osgi.Builder.builds(Builder.java:1425)
at aQute.bnd.build.ProjectBuilder.builds(ProjectBuilder.java:756)
at aQute.bnd.build.Project.buildLocal(Project.java:1891)
at aQute.bnd.build.Project.build(Project.java:1706)
at aQute.bnd.build.Project.build(Project.java:2455)
at aQute.bnd.build.Project$build$19.call(Unknown Source)
at aQute.bnd.gradle.BndPlugin$_apply_closure1$_closure13$_closure62.doCall(BndPlugin.groovy:310)
at jdk.internal.reflect.GeneratedMethodAccessor445.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035)
at groovy.lang.Closure.call(Closure.java:412)
at groovy.lang.Closure.call(Closure.java:428)
at org.gradle.api.internal.AbstractTask$ClosureTaskAction.doExecute(AbstractTask.java:744)
at org.gradle.api.internal.AbstractTask$ClosureTaskAction.lambda$execute$0(AbstractTask.java:731)
at org.gradle.configuration.internal.DefaultUserCodeApplicationContext$CurrentApplication.reapply(DefaultUserCodeApplicationContext.java:98)
at org.gradle.api.internal.AbstractTask$ClosureTaskAction.execute(AbstractTask.java:731)
at org.gradle.api.internal.AbstractTask$ClosureTaskAction.execute(AbstractTask.java:706)
at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:236)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:221)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:204)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:187)
at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:165)
at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:89)
at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:40)
at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:53)
at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:50)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:50)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:40)
at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:68)
at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:38)
at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41)
at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74)
at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:29)
at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.executeDelegateBroadcastingChanges(CaptureStateAfterExecutionStep.java:124)
at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:80)
at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:58)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:48)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:36)
at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:181)
at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$1(BuildCacheStep.java:71)
at org.gradle.internal.Either$Right.fold(Either.java:175)
at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:59)
at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:69)
at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:47)
at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:36)
at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:25)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:36)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:22)
at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:110)
at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$2(SkipUpToDateStep.java:56)
at java.base/java.util.Optional.orElseGet(Optional.java:369)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:56)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:38)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:73)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:44)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:89)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:50)
at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:114)
at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:57)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:76)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:50)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNoEmptySources(SkipEmptyWorkStep.java:254)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNoEmptySources(SkipEmptyWorkStep.java:209)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:88)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:56)
at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:32)
at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:21)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:43)
at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:31)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:40)
at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:281)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:40)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:44)
at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:33)
at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:76)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:139)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:128)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:77)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:69)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:327)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:314)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:307)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:293)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:417)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:339)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Without the macos one then everything works as expected.
-includeresource: \ linux-x86-64/libopencv_java.so=${repo;org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-x86-64;4.6.0.-dcm},\ windows-x86-64/opencv_java.dll=${repo;org.weasis.thirdparty.org.opencv:opencv_java:dll:windows-x86-64;4.6.0.-dcm},\ macosx-x86-64/libopencv_java.jnilib=${repo;org.weasis.thirdparty.org.opencv:libopencv_java:jnilib:macosx-x86-64;4.6.0.-dcm}error : Exception: java.util.regex.PatternSyntaxException: Unclosed group near index 9
This is strange. I get this error when I use 4.6.0-dcm (without the dot .).
When I add the dot . I get a different exception but not that 'PatternSyntaxException'.
Question about your repository: In order to use ${repo} you must have a repository in bnd defined with this. Can you post how that looks?
It looks like it is failing to retrieve the library:
e = {FileNotFoundException@10780} "java.io.FileNotFoundException: https://rhapsody.jfrog.io/rhapsody/libs-release/org/weasis/thirdparty/org/opencv/libopencv_java/4.6.0-dcm/libopencv_java-4.6.0-dcm-macosx-x86-64.jnilib"
backtrace = {Object[5]@10817}
detailMessage = "https://rhapsody.jfrog.io/rhapsody/libs-release/org/weasis/thirdparty/org/opencv/libopencv_java/4.6.0-dcm/libopencv_java-4.6.0-dcm-macosx-x86-64.jnilib"
cause = {FileNotFoundException@10780} "java.io.FileNotFoundException: https://rhapsody.jfrog.io/rhapsody/libs-release/org/weasis/thirdparty/org/opencv/libopencv_java/4.6.0-dcm/libopencv_java-4.6.0-dcm-macosx-x86-64.jnilib"
stackTrace = {StackTraceElement[15]@10824}
0 = {StackTraceElement@10833} "java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1957)"
1 = {StackTraceElement@10834} "java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1557)"
2 = {StackTraceElement@10835} "java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)"
3 = {StackTraceElement@10836} "java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:334)"
4 = {StackTraceElement@10837} "aQute.bnd.http.HttpClient$HttpConnection.doConnect(HttpClient.java:628)"
5 = {StackTraceElement@10838} "aQute.bnd.http.HttpClient$HttpConnection.lambda$connect$0(HttpClient.java:590)"
6 = {StackTraceElement@10839} "aQute.bnd.http.HttpClient.connectWithProxy(HttpClient.java:233)"
7 = {StackTraceElement@10840} "aQute.bnd.http.HttpClient$HttpConnection.connect(HttpClient.java:590)"
8 = {StackTraceElement@10841} "aQute.bnd.http.HttpClient$HttpConnection.doCached0(HttpClient.java:554)"
9 = {StackTraceElement@10842} "aQute.bnd.http.HttpClient$HttpConnection.doCached(HttpClient.java:448)"
10 = {StackTraceElement@10843} "aQute.bnd.http.HttpClient$HttpConnection.call(HttpClient.java:398)"
11 = {StackTraceElement@10844} "org.osgi.util.promise.DeferredPromiseImpl$Submit.run(DeferredPromiseImpl.java:658)"
12 = {StackTraceElement@10845} "java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)"
13 = {StackTraceElement@10846} "java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)"
14 = {StackTraceElement@10847} "java.base/java.lang.Thread.run(Thread.java:829)"
This ends up getting handled and you never see it but I think then the repo macro isn't replaced and that's what leads to the PatternSyntaxException
It is configured with:
-plugin.2.Atrifactory: \
aQute.bnd.repository.maven.provider.MavenBndRepository; \
releaseUrl=https://rhapsody.jfrog.io/rhapsody/libs-release/; \
snapshotUrl=https://rhapsody.jfrog.io/rhapsody/libs-snapshot/; \
index=${.}/maven.repo; \
readOnly=true; \
name="Maven via Artifactory"
Is that what you were asking about? I didn't set this up so not entirely sure.
These are Artifactory virtual repositories which pull through from a bunch of upstream maven repos, one of them being https://raw.github.com/nroduit/mvn-repo/master/.
Woops so they renamed the macos one from jnilib to dylib.
Ok so now that I change it to:
org.weasis.thirdparty.org.opencv:libopencv_java:dylib:macosx-x86-64:4.6.0-dcm
and:
macosx-x86-64/libopencv_java.dylib=${repo;org.weasis.thirdparty.org.opencv:libopencv_java:dylib:macosx-x86-64;4.6.0.-dcm},\
I get the original error that I noticed back again:
e = {MalformedInputException@66330} "java.nio.charset.MalformedInputException: Input length = 1"
inputLength = 1
backtrace = {Object[5]@66344}
detailMessage = null
cause = {MalformedInputException@66330} "java.nio.charset.MalformedInputException: Input length = 1"
stackTrace = {StackTraceElement[174]@66348}
0 = {StackTraceElement@66350} "java.base/java.nio.charset.CoderResult.throwException(CoderResult.java:274)"
1 = {StackTraceElement@66351} "java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:350)"
2 = {StackTraceElement@66352} "java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:179)"
3 = {StackTraceElement@66353} "java.base/java.io.BufferedReader.fill(BufferedReader.java:161)"
4 = {StackTraceElement@66354} "java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)"
5 = {StackTraceElement@66355} "java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)"
6 = {StackTraceElement@66356} "aQute.bnd.build.Container.getMembers(Container.java:237)"
7 = {StackTraceElement@66357} "aQute.bnd.build.Project.add(Project.java:1664)"
8 = {StackTraceElement@66358} "aQute.bnd.build.Project._repo(Project.java:1657)"
9 = {StackTraceElement@66359} "aQute.bnd.osgi.Macro.lambda$null$5(Macro.java:461)"
10 = {StackTraceElement@66360} "aQute.bnd.osgi.Macro.doCommand(Macro.java:475)"
11 = {StackTraceElement@66361} "aQute.bnd.osgi.Macro.doCommands(Macro.java:401)"
12 = {StackTraceElement@66362} "aQute.bnd.osgi.Macro.getMacro(Macro.java:274)"
13 = {StackTraceElement@66363} "aQute.bnd.osgi.Macro.replace(Macro.java:355)"
14 = {StackTraceElement@66364} "aQute.bnd.osgi.Macro.process(Macro.java:148)"
15 = {StackTraceElement@66365} "aQute.bnd.osgi.Macro.process(Macro.java:164)"
16 = {StackTraceElement@66366} "aQute.bnd.osgi.Macro.process(Macro.java:127)"
17 = {StackTraceElement@66367} "aQute.bnd.osgi.Macro.process(Macro.java:122)"
18 = {StackTraceElement@66368} "aQute.bnd.osgi.Processor.getLiteralProperty(Processor.java:1455)"
19 = {StackTraceElement@66369} "aQute.bnd.osgi.Processor.lambda$getWildcardProperty$7(Processor.java:1415)"
20 = {StackTraceElement@66370} "java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)"
21 = {StackTraceElement@66371} "java.base/java.util.ArrayList.forEach(ArrayList.java:1541)"
22 = {StackTraceElement@66372} "java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)"
23 = {StackTraceElement@66373} "java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)"
24 = {StackTraceElement@66374} "java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)"
25 = {StackTraceElement@66375} "java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)"
26 = {StackTraceElement@66376} "java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)"
27 = {StackTraceElement@66377} "java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)"
28 = {StackTraceElement@66378} "java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)"
29 = {StackTraceElement@66379} "aQute.bnd.osgi.Processor.getWildcardProperty(Processor.java:1417)"
30 = {StackTraceElement@66380} "aQute.bnd.osgi.Processor.getProperty(Processor.java:1407)"
31 = {StackTraceElement@66381} "aQute.bnd.osgi.Processor.mergeProperties(Processor.java:2663)"
32 = {StackTraceElement@66382} "aQute.bnd.osgi.Processor.mergeProperties(Processor.java:2651)"
33 = {StackTraceElement@66383} "aQute.bnd.osgi.Builder.doIncludeResources(Builder.java:903)"
34 = {StackTraceElement@66384} "aQute.bnd.osgi.Builder.build(Builder.java:119)"
35 = {StackTraceElement@66385} "aQute.bnd.osgi.Builder.builds(Builder.java:1425)"
36 = {StackTraceElement@66386} "aQute.bnd.build.ProjectBuilder.builds(ProjectBuilder.java:756)"
37 = {StackTraceElement@66387} "aQute.bnd.build.Project.buildLocal(Project.java:1891)"
38 = {StackTraceElement@66388} "aQute.bnd.build.Project.build(Project.java:1706)"
39 = {StackTraceElement@66389} "aQute.bnd.build.Project.build(Project.java:2455)"
40 = {StackTraceElement@66390} "aQute.bnd.build.Project$build$19.call(Unknown Source)"
41 = {StackTraceElement@66391} "org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)"
42 = {StackTraceElement@66392} "org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)"
43 = {StackTraceElement@66393} "org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)"
44 = {StackTraceElement@66394} "aQute.bnd.gradle.BndPlugin$_apply_closure1$_closure13$_closure62.doCall(BndPlugin.groovy:310)"
45 = {StackTraceElement@66395} "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)"
46 = {StackTraceElement@66396} "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)"
47 = {StackTraceElement@66397} "java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)"
48 = {StackTraceElement@66398} "java.base/java.lang.reflect.Method.invoke(Method.java:566)"
49 = {StackTraceElement@66399} "org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)"
50 = {StackTraceElement@66400} "groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)"
51 = {StackTraceElement@66401} "org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274)"
52 = {StackTraceElement@66402} "groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035)"
53 = {StackTraceElement@66403} "groovy.lang.Closure.call(Closure.java:412)"
54 = {StackTraceElement@66404} "groovy.lang.Closure.call(Closure.java:428)"
55 = {StackTraceElement@66405} "org.gradle.api.internal.AbstractTask$ClosureTaskAction.doExecute(AbstractTask.java:744)"
...
Is that what you were asking about? I didn't set this up so not entirely sure.
Yes, thanks. But is this a public repo? I think I cannot access it.
We clearly need a proper way to reproduce it better, in order to help. Can you provide a small public github repo which produces the exact problem? I have come so far that I think it is somewhere related to the Version parsing (regex... and there are difference between Maven-versions and OSGi version ... OSGi is stricter and allows no dash (-)), but not sure if we should touch that.
My question is:
In your initial post you said:
After working around that gotcha, these all work fine except for the macOS one. It will fail because a file that ends in
libis assumed to be some kind of library:
I think this was because of the lib:=true which was not needed and you removed, right?
I would think it should now work for you. Of course, still with the weired dot (.) stuff...
First of all the
4.4.0.-dcmformat really threw me. It is bizarre having to put.before the-. I couldn't find the documentation for this. I did eventually find the regex in:
This branch (https://github.com/steinybot/bug-reports/tree/bnd/no-translation-found-for-macro) has a reproduction of the first problem:
❯ ./gradlew build
> Task :org.example.impl:jar FAILED
warning: No translation found for macro: repo;org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-aarch64;4.6.0-dcm
warning: No translation found for macro: repo;org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-x86-64;4.6.0-dcm
error : Invalid syntax for version: 4.6.0-dcm, for cmd: repo, arguments; [repo, org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-aarch64, 4.6.0-dcm]
error : Invalid syntax for version: 4.6.0-dcm, for cmd: repo, arguments; [repo, org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-x86-64, 4.6.0-dcm]
error : Exception: java.util.regex.PatternSyntaxException: Unclosed group near index 9
\$(?:repo
at java.base/java.util.regex.Pattern.error(Pattern.java:2204)
at java.base/java.util.regex.Pattern.accept(Pattern.java:2054)
at java.base/java.util.regex.Pattern.group0(Pattern.java:3232)
at java.base/java.util.regex.Pattern.sequence(Pattern.java:2300)
at java.base/java.util.regex.Pattern.expr(Pattern.java:2245)
at java.base/java.util.regex.Pattern.compile(Pattern.java:1945)
at java.base/java.util.regex.Pattern.<init>(Pattern.java:1576)
at java.base/java.util.regex.Pattern.compile(Pattern.java:1134)
at aQute.libg.glob.Glob.toPattern(Glob.java:162)
at aQute.libg.glob.Glob.<init>(Glob.java:35)
at aQute.libg.glob.Glob.<init>(Glob.java:31)
at aQute.bnd.osgi.Analyzer.jarsFromName(Analyzer.java:1813)
at aQute.bnd.osgi.Analyzer.getJarsFromName(Analyzer.java:1801)
at aQute.bnd.osgi.Builder.noSuchFile(Builder.java:1282)
at aQute.bnd.osgi.Builder.doIncludeResource(Builder.java:1021)
at aQute.bnd.osgi.Builder.doIncludeResource(Builder.java:953)
at aQute.bnd.osgi.Builder.doIncludeResources(Builder.java:941)
at aQute.bnd.osgi.Builder.build(Builder.java:141)
at aQute.bnd.osgi.Builder.builds(Builder.java:1527)
at aQute.bnd.build.ProjectBuilder.builds(ProjectBuilder.java:842)
at aQute.bnd.build.Project.buildLocal(Project.java:1856)
at aQute.bnd.build.Project.build(Project.java:1667)
at aQute.bnd.build.Project.build(Project.java:2447)
at aQute.bnd.gradle.BndPlugin$3.execute(BndPlugin.java:574)
at aQute.bnd.gradle.BndPlugin$3.execute(BndPlugin.java:569)
...
Then if you change it to:
-includeresource: \
linux-aarch64/libopencv_java.so=${repo;org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-aarch64;4.6.0.-dcm},\
linux-x86-64/libopencv_java.so=${repo;org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-x86-64;4.6.0.-dcm}
As shown in https://github.com/steinybot/bug-reports/tree/bnd/illegal-argument-exception
You get:
./gradlew build --debug
...
2025-10-15T16:52:33.773+1300 [DEBUG] [aQute.bnd.repository.maven.provider.IndexFile] loaded index [org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-x86-64:4.6.0-dcm, org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-aarch64:4.6.0-dcm]
2025-10-15T16:52:33.773+1300 [DEBUG] [aQute.maven.provider.MavenRemoteRepository] Fetching org/weasis/thirdparty/org/opencv/libopencv_java/4.6.0-dcm/libopencv_java-4.6.0-dcm-linux-x86-64.so
2025-10-15T16:52:33.773+1300 [DEBUG] [aQute.maven.provider.MavenRemoteRepository] Fetching org/weasis/thirdparty/org/opencv/libopencv_java/4.6.0-dcm/libopencv_java-4.6.0-dcm-linux-aarch64.so
...
2025-10-15T16:52:35.603+1300 [DEBUG] [aQute.bnd.repository.maven.provider.IndexFile] Failed to get org.weasis.thirdparty.org.opencv:libopencv_java:so:linux-x86-64:4.6.0-dcm: illegal format /Users/jason.pickens/.m2/repository/org/weasis/thirdparty/org/opencv/libopencv_java/4.6.0-dcm/libopencv_java-4.6.0-dcm-linux-x86-64.so
java.lang.IllegalArgumentException: illegal format /Users/jason.pickens/.m2/repository/org/weasis/thirdparty/org/opencv/libopencv_java/4.6.0-dcm/libopencv_java-4.6.0-dcm-linux-x86-64.so
at aQute.bnd.osgi.resource.ResourceBuilder.parse(ResourceBuilder.java:1040)
at aQute.bnd.osgi.resource.ResourceBuilder.lambda$addFile$8(ResourceBuilder.java:996)
at aQute.bnd.osgi.resource.FileResourceCache.lambda$getResource$1(FileResourceCache.java:65)
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
at aQute.bnd.osgi.resource.FileResourceCache.getResource(FileResourceCache.java:65)
at aQute.bnd.osgi.resource.ResourceBuilder.addFile(ResourceBuilder.java:996)
at aQute.bnd.repository.maven.provider.IndexFile.parseSingle(IndexFile.java:332)
at aQute.bnd.repository.maven.provider.IndexFile.parseSingleOrMultiFile(IndexFile.java:313)
at aQute.bnd.repository.maven.provider.IndexFile.lambda$update$13(IndexFile.java:270)
at org.osgi.util.promise.DeferredPromiseImpl$Map.accept(DeferredPromiseImpl.java:500)
at org.osgi.util.promise.DeferredPromiseImpl.result(DeferredPromiseImpl.java:151)
at org.osgi.util.promise.DeferredPromiseImpl$Map.run(DeferredPromiseImpl.java:492)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.util.zip.ZipException: The JAR/ZIP file (/Users/jason.pickens/.m2/repository/org/weasis/thirdparty/org/opencv/libopencv_java/4.6.0-dcm/libopencv_java-4.6.0-dcm-linux-x86-64.so) seems corrupted, error: zip END header not found
at aQute.bnd.osgi.Jar.buildFromZip(Jar.java:310)
at aQute.bnd.osgi.Jar.<init>(Jar.java:137)
at aQute.bnd.osgi.Jar.<init>(Jar.java:235)
at aQute.bnd.osgi.resource.ResourceBuilder.parse(ResourceBuilder.java:1025)
... 14 more
Caused by: java.util.zip.ZipException: zip END header not found
at java.base/java.util.zip.ZipFile$Source.findEND(ZipFile.java:1649)
at java.base/java.util.zip.ZipFile$Source.initCEN(ZipFile.java:1657)
at java.base/java.util.zip.ZipFile$Source.<init>(ZipFile.java:1495)
at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1458)
at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:724)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:251)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:180)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:194)
at aQute.bnd.osgi.Jar.buildFromZip(Jar.java:299)
... 17 more
...
Note the debug flag which shows the real problem, without it then appears as though the problem is because the file doesn't exist.
This seems to be much worse in 7.1.0 than it was in 6.4.0. In 6.4.0 it was anything ending in lib would be a problem so just our macOS builds were broken. Now it looks like it is any file that is not a ZIP so builds are broken for every platform.