Simplify version logic in plugin/SPI compatibility check#12006
Simplify version logic in plugin/SPI compatibility check#12006findepi merged 1 commit intotrinodb:masterfrom
Conversation
The check relied on the fact that plugin version and SPI version match for all plugins maintained within Trino. While this is true, loading plugin version from jar's manifest isn't exactly same as loading the version from a maven-filtered resource. This in turn lead to discrepancies in reported version when a tagged version was rebuilt with local modifications. (Of course, this remains not a recommended practice). This commit replaces the jar's manifest and with explicit maven-filtered resource on the plugin side. The filtered resource is within trino-plugin-toolkit, so the check still depends on SPI, Trino plugins and the plugin toolkit being versioned together and so remains appropriate only for the plugins maintained within the project.
losipiuk
left a comment
There was a problem hiding this comment.
LGTM though it proved tricky enough times already - so you never know...
There was a problem hiding this comment.
Apologies, but without a test to show the code being invoked / expected results, this is very hard to reason about.
Also, the compiler will inline a static string - should SPI_VERSION be the result of a method call (not a class initialization?).
Again - without tests to show the expected behaviour, I would be wary of merging this.
Here's an example of some tests / refactoring to make it self-documenting:
master...leveyja:leveyja/trino-spi-version
(and an example of intentionally inlining the version - if we generated a class that allowed Context.getSpiVersion() {return SpiVersionHolder.ACTUAL_STRING_TO_BE_INLINED;}, it could be another avenue (obviously without a value at compile time the current SPI_VERSION can't be inlined - but it might be an avenue to investigate?)
The implemented logic is now requivalent to loading resources plus
Indeed, the code (as currently published on that branch), verifies that
SPI_VERSION is not a "compile-time constant", cannot be inlined.
I thought about that. Thank you @leveyja for teaching me how to do this, I didn't know that. For posterity <plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<file>src/main/resources/io/trino/plugin/base/CompileVersionHolder.java.template</file>
<outputFile>src/main/java/io/trino/plugin/base/CompileVersionHolder.java</outputFile>
<replacements>
<replacement>
<token>@project.version@</token>
<value>${project.version}</value>
</replacement>
</replacements>
</configuration>
</plugin>When this technique is used within plugin-toolkit, it's equivalent to loading the information from a resource file. This is because compile-time and runtime version of the plugin toolkit is always the same (unless someone tinkers with with plugin internal classpath, but that's not a problem we're trying to solve here). It would be useful if we wanted the SPI to publish it's compile-time version as a compile-time constant so that it gets inlined. However, I rejected this idea because I didn't find relying on compile-time constants implicit inlining to be a very readable "API". |
The check relied on the fact that plugin version and SPI version match
for all plugins maintained within Trino. While this is true, loading
plugin version from jar's manifest isn't exactly same as loading the
version from a maven-filtered resource. This in turn lead to
discrepancies in reported version when a tagged version was rebuilt with
local modifications. (Of course, this remains not a recommended
practice).
This commit replaces the jar's manifest and with explicit maven-filtered
resource on the plugin side. The filtered resource is within
trino-plugin-toolkit, so the check still depends on SPI, Trino plugins
and the plugin toolkit being versioned together and so remains
appropriate only for the plugins maintained within the project.