Comments (5)
Hmm... this is a tricky one.
One idea would be to try and run revapi in a specific maven profile that would provide the "correct" dependencies? Not sure if that would work though, because you'd probably end up with both legacy and non-legacy modules on the classpath.
Other than that, I see no other option but to be able to somehow replace the dependencies during the dependency resolution.
I think this change would be isolated to Revapi's revapi-maven-utils
module and somehow massaging Maven's RepositorySystemSession
to modify its dependency collection... Would you have any experience with how to accomplish such things in Maven (plugin)?
from revapi.
Oh! I know this is an old issue but I think I have an idea how you would be able to achieve this using Revapi...
There's https://revapi.org/revapi-java-spi/0.24.0/_attachments/apidocs/org/revapi/java/spi/JarExtractor.html which basically allows one to supply the jar file for an archive. It is meant for extracting data from war files, or Jenkins are using it for extracting code from Jenkins plugins (https://github.com/jenkinsci/lib-revapi-hpi-extractor).
If you made your custom jar extractor that would look at the name of the supplied archive (which in case of maven build is (I think) just a GAV of the maven artifact), it could figure out whether there is the legacy alternative available for it and supply its jar somehow (this might be tricky because you'd have to resolve those jars from maven, theoretically, but it's doable).
from revapi.
You can also read https://revapi.org/revapi-java-spi/0.24.0/index.html#_handling_new_packaging_of_code and look at https://github.com/revapi/revapi/blob/main/revapi-java/src/main/java/org/revapi/java/extract/WarJarExtractor.java for more discussion and examples...
from revapi.
Hi @metlos Thanks for the idea and sorry for replying so late!
Using your idea, I guess the following would be needed:
In the XWiki custom JarExtractor implementation, for the current maven artifact being checked and for all its transitive dependencies, use Maven Aether to try resolving a legacy JAR with a GAV computed based on the current artifact name. For example for a dependency like the following for the current maven project being anayzed:
<dependency>
<groupId>org.xwiki.platform</groupId>
<artifactId>xwiki-platform-oldcore</artifactId>
<version>${project.version}</version>
</dependency>
We would substitute xwiki-platform-oldcore
with xwiki-platform-legacy-oldcore
and thus try to find if org.xwiki.platform:xwiki-platform-oldcore:<revapi version checked>
exists.
If it does, then an InputStream
to that legacy JAR would be returned. If it doesn't then the input stream to the passed org.revapi.Archive
would be returned.
I have some thoughts/questions:
- I guess
JarExtractor#extract()
is going to be called for the main artifact and all its transitive dependencies, isn't it? - I see a potential performance issue since it means that for all the transitive dependencies starting with
xwiki-
in their names, we would use Maven Aether to try to resolve/download the matching legacy JAR and overall with tens or hundreds of deps for each maven module this will be quite performance intensive. I can think of 2 ideas to work around this:- A local FS or memory cache (would need to be very careful for SNAPSHOT versions) of the found or not found legacy artifacts so that the resolving is done once per artifact.
- Implement a static list of known legacy modules in the XWiki JarExtractor implementation and whenever we add a new legacy module we also add it to the static list. Since we don't add that many legacy modules, it could work out.
- In order for Revapi to use our extension, we would need to declare it as a maven dependency of the Maven Revapi plugin, and Revapi will auto-discover the extension and register it, right? Something like:
<plugin> <groupId>org.revapi</groupId> <artifactId>revapi-maven-plugin</artifactId> <version>0.14.7</version> <dependencies> <dependency> <groupId>org.revapi</groupId> <artifactId>revapi-java</artifactId> <version>0.27.0</version> </dependency> <dependency> <groupId>org.xwiki.commons</groupId> <artifactId>xwiki-commons-revapi</artifactId> <version>14.10</version> </dependency> </dependencies>
Thanks again!
from revapi.
I guess JarExtractor#extract() is going to be called for the main artifact and all its transitive dependencies, isn't it?
Yes, it should be called separately for each archive.
A local FS or memory cache (would need to be very careful for SNAPSHOT versions) of the found or not found legacy artifacts so that the resolving is done once per artifact.
Aether, or rather maven-resolver, should use the local maven cache, so maybe most of the complexity would be hidden there... You can take a look at https://github.com/revapi/revapi/tree/main/revapi-maven-utils that is using the maven resolver to find the previous releases in Revapi.
Implement a static list of known legacy modules in the XWiki JarExtractor implementation and whenever we add a new legacy module we also add it to the static list. Since we don't add that many legacy modules, it could work out.
The extractors can be configurable in Revapi, so you could provide this list somewhere the pom and not hardcode it in the code. See for example how the war extractor is configured here https://revapi.org/revapi-java/0.27.0/non-jar-archives.html#_handling_war_archives (using its extensionId
under the /revapi.java/extract
path and how it receives the configuration here https://github.com/revapi/revapi/blob/main/revapi-java/src/main/java/org/revapi/java/extract/WarJarExtractor.java#L168.
I've played with initializing the maven repository system etc in my https://github.com/metlos/maven-repo-jboss-modules project, for example in https://github.com/metlos/maven-repo-jboss-modules/blob/master/src/main/java/pw/krejci/modules/maven/MavenBootstrap.java. You can take some inspiration from there if you don't have experience with this kind of stuff yourselves.
from revapi.
Related Issues (20)
- Possibly false-positive java.class.externalClassExposedInAPI HOT 4
- Version format check is too restrictive HOT 4
- Making a public constructor protected in an abstract class should not be reported as breakage HOT 2
- Maven site for revapi fails miserably
- Revapi produces inconsistent results
- Enforcing criticality HOT 2
- Running into an endless Loop at org.jvnet.hudson HOT 3
- Infinite loop in differences HOT 2
- externalClassExposedInAPI in dependencies ? HOT 15
- "Invalid element" when upgrading to revapi-java 0.27.0 HOT 2
- Potential NullPointerException in ClasspathScanner$Scanner HOT 5
- Add Concept for String or Pattern Match
- Ability to Enforce TreeFilter Ordering HOT 1
- revapi dependency org.apache.logging.log4j:log4j-core has multiple CVE against it
- how could a enum class be excluded from java.field.enumConstantOrderChanged? HOT 4
- Fix warnings reported by Maven when using the Revapi plugin
- Class visibility reduction from `public` to `package` is reported as `java.class.removed` in latest version
- Plugin breaks in Maven4 HOT 2
- update of standalone or reporting-text ? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from revapi.