Skip to content

Commit f268330

Browse files
ctruedengselzer
authored andcommitted
Tweak SciJava plugin metadata aggregation hack
Generally speaking, it is not correct to mix the contents of target/classes/META-INF/org.scijava.plugin.Plugin into target/test-classes/META-INF/org.scijava.plugin.Plugin, because it creates duplicate plugin entries across the two classpath elements. The reason for the script-maven-plugin hack is to avoid module-path woes, where (if I understand correctly) the target/classes directory is on the module path but the target/test-classes directory is on the classpath, which somehow results in the unit tests not being able to discover plugins in the target/classes folder, even though the src/main/java/module-info.java includes e.g. `opens org.scijava.persist to org.scijava`. And similarly for SciJava Ops, not being able to notice the `target/classes/ops.yaml` from unit tests. This is an unfortunate situation, which we have tried to resolve by introducing a `src/test/java/module-info.java` as well, but have never quite been able to make it work correctly. Strangely, the scijava-ops-benchmark component introduces a single `@Plugin` of type `net.imagej.ops.Op` in its main scope, which as per the script hack gets propagated into both target/classes and target/test-classes... but then the unit tests *do* see both of these files and read them both, resulting in an ImageJ Ops environment containing that Op plugin twice, which results in the dreaded "Multiple ops of priority 0.0" error. I do not understand why the behavior differs between modules. Nonetheless, this commit seeks to avoid the issue by only combining META-INF/org.scijava.plugin.Plugin metadata files between target/classes and target/test-classes for the one component that actually needs it, which is scijava-persist.
1 parent d7b0327 commit f268330

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@
235235
end
236236

237237
# Read in main and test scope plugin annotations.
238-
['ops.yaml', 'META-INF/json/org.scijava.plugin.Plugin'].each do |pluginsPath|
238+
['ops.yaml'].each do |pluginsPath|
239239
mainPluginsPath = "#{basedir}/target/classes/#{pluginsPath}"
240240
testPluginsPath = "#{basedir}/target/test-classes/#{pluginsPath}"
241241
mainPlugins = read_plugins(mainPluginsPath)

scijava-persist/pom.xml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,65 @@
113113
</repositories>
114114

115115
<build>
116+
<pluginManagement>
117+
<plugins>
118+
<plugin>
119+
<groupId>com.alexecollins.maven.plugin</groupId>
120+
<artifactId>script-maven-plugin</artifactId>
121+
<version>${script-maven-plugin.version}</version>
122+
<executions>
123+
<execution>
124+
<id>union-metadata-indices</id>
125+
<phase>process-test-classes</phase>
126+
<goals>
127+
<goal>execute</goal>
128+
</goals>
129+
<configuration>
130+
<language>ruby</language>
131+
<script>
132+
# Append the source plugin annotations to the test plugin annotations
133+
require 'set'
134+
135+
# Handle windows paths
136+
basedir = '${project.basedir}'.gsub /\\+/, '\\\\'
137+
138+
# Reads plugin metadata into a set of strings, one per plugin declaration.
139+
def read_plugins(path)
140+
delim = 'UNIQUE-SEQUENCE-THAT-NO-PLUGIN-WILL-EVER-USE'
141+
return File.exist?(path) ? File.read(path).sub('}{', '}' + delim + '{').split(delim).to_set : Set.new()
142+
end
143+
144+
# Read in main and test scope plugin annotations.
145+
['META-INF/json/org.scijava.plugin.Plugin'].each do |pluginsPath|
146+
mainPluginsPath = "#{basedir}/target/classes/#{pluginsPath}"
147+
testPluginsPath = "#{basedir}/target/test-classes/#{pluginsPath}"
148+
mainPlugins = read_plugins(mainPluginsPath)
149+
testPlugins = read_plugins(testPluginsPath)
150+
151+
# Write out unioned plugin annotations to test scope plugin annotations.
152+
# Without this, the test scope code does not know of the main scope plugins.
153+
allPlugins = mainPlugins.union(testPlugins)
154+
unless allPlugins.empty?()
155+
require 'fileutils'
156+
FileUtils.mkdir_p File.dirname(testPluginsPath)
157+
File.write(testPluginsPath, allPlugins.to_a.join(''))
158+
end
159+
end
160+
</script>
161+
</configuration>
162+
</execution>
163+
</executions>
164+
<dependencies>
165+
<dependency>
166+
<groupId>org.jruby</groupId>
167+
<artifactId>jruby-complete</artifactId>
168+
<version>${jruby.version}</version>
169+
<scope>runtime</scope>
170+
</dependency>
171+
</dependencies>
172+
</plugin>
173+
</plugins>
174+
</pluginManagement>
116175
<plugins>
117176
<plugin>
118177
<artifactId>maven-compiler-plugin</artifactId>

0 commit comments

Comments
 (0)