Git Product home page Git Product logo

Comments (5)

metlos avatar metlos commented on June 16, 2024

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.

metlos avatar metlos commented on June 16, 2024

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.

metlos avatar metlos commented on June 16, 2024

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.

vmassol avatar vmassol commented on June 16, 2024

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.

metlos avatar metlos commented on June 16, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.