Skip to content

Mavenize #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open

Mavenize #7

wants to merge 12 commits into from

Conversation

cstamas
Copy link

@cstamas cstamas commented Mar 7, 2023

Just to pull the string with some honey on it.... 😄

But it would be better to adopt "standard" project layout (src/main/java, src/test/java) etc...

@cstamas
Copy link
Author

cstamas commented Mar 7, 2023

@vigna
Copy link
Owner

vigna commented Mar 7, 2023

Oh wow. That's a lot of information. Let me digest 😂. Thanks!

@cstamas
Copy link
Author

cstamas commented Mar 7, 2023

This is NOT to be committed, just a "demo" you can start from... But again, there is a lot more to be done:

  • reorganize sources layout
  • fix plugin versions in POM
  • sort out the "slow" tests
  • etc

As you want to end up with maven artifact, and want to deploy to Maven Central, unsure why is build still Ant and not Maven...

Just ask if anything more needed.

@cstamas
Copy link
Author

cstamas commented Mar 7, 2023

Will continue later... so you can track the changes. But again: DO NOT MERGE

@vigna
Copy link
Owner

vigna commented Mar 7, 2023

OK, there's no danger at the moment: I hate Maven and the way it forces you to do things his way. 😂

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

So, just try ./mvnw clean deploy -Dtest=void -P vigna-release and it does what you wanted 😄
(I tried but I have no perms to publish into it.unimi group on Central: https://gist.github.com/cstamas/f7b7da763657cbb6f37e02d9070abe4b)

One problem remaining: if you'd use Ivy, it would replace the POM added by this PR (the pom.xml in repo root).
Happy hacking!

IMHO, next step would be to adhere to standard project layout, drop Ant/Ivy build... and I think there is one more thing missing: the bnd osgi headers? DONE

See the updated README for some hints.

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

Also, maven does not force you to do anything, the point of maven is that whoever checks out the project, does not have to look left and right to find things, but there is "standard" layout. And same fol building, no need to sift thru ant XML, but mvnw clean package always does the thing. Standardize and lower the barriers with new project...

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

Layout reorganized, you can check how it looks here: https://github.com/cstamas/dsiutils/tree/mavenize

All tests collapsed as you did good job of naming them Test ans SlowTest, so the improvement here is that SlowTest always compile, so is easier to spot mistakes, but they run only if -P slow profile is activated.

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

Last bits are bash/, prngperf and setcp.sh, as am unsure what are they used to.... I'd like some hint here... the bash would most probably become some submodule, maybe prngperf as well....

Waiting for some input!

@vigna
Copy link
Owner

vigna commented Mar 8, 2023

bash is a directory containing scripts related to the project, but it has nothing to do with the build process. setcp.sh is a utility script that sets the classpath to the downloaded jars plus the current compiled jar. prngperf is a JMH setup and it's already handled by Maven.

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

Once you compare output of https://github.com/vigna/dsiutils/tree/master and https://github.com/cstamas/dsiutils/tree/mavenize and those match your expectations, you CAN merge 😄 to have maven build

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

Also,merge will give you CI as well, run of last commit https://github.com/cstamas/dsiutils/actions/runs/4364687079/jobs/7632309036

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

Hint: here https://github.com/cstamas/dsiutils/blob/mavenize/.github/workflows/maven.yml#L17 add to line end -P slow and GH CI will run ALL tests

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

To get Java CP:

[cstamas@urnebes dsiutils (mavenize)]$ mvn dependency:build-classpath 
[INFO] Scanning for projects...
[INFO] 
[INFO] -----------------------< it.unimi.dsi:dsiutils >------------------------
[INFO] Building DSI Utilities 2.7.4-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- dependency:2.8:build-classpath (default-cli) @ dsiutils ---
[WARNING] Parameter 'local' is deprecated core expression; Avoid use of ArtifactRepository type. If you need access to local repository, switch to '${repositorySystemSession}' expression and get LRM from it instead.
[INFO] Dependencies classpath:
/home/cstamas/.m2/repository-oss/org/slf4j/slf4j-api/2.0.3/slf4j-api-2.0.3.jar:/home/cstamas/.m2/repository-oss/ch/qos/logback/logback-core/1.3.4/logback-core-1.3.4.jar:/home/cstamas/.m2/repository-oss/ch/qos/logback/logback-classic/1.3.4/logback-classic-1.3.4.jar:/home/cstamas/.m2/repository-oss/com/sun/mail/javax.mail/1.6.2/javax.mail-1.6.2.jar:/home/cstamas/.m2/repository-oss/javax/activation/activation/1.1/activation-1.1.jar:/home/cstamas/.m2/repository-oss/it/unimi/dsi/fastutil/8.5.11/fastutil-8.5.11.jar:/home/cstamas/.m2/repository-oss/it/unimi/di/jsap/20210129/jsap-20210129.jar:/home/cstamas/.m2/repository-oss/org/apache/commons/commons-configuration2/2.8.0/commons-configuration2-2.8.0.jar:/home/cstamas/.m2/repository-oss/org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar:/home/cstamas/.m2/repository-oss/org/apache/commons/commons-text/1.9/commons-text-1.9.jar:/home/cstamas/.m2/repository-oss/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:/home/cstamas/.m2/repository-oss/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar:/home/cstamas/.m2/repository-oss/com/google/guava/guava/31.1-jre/guava-31.1-jre.jar:/home/cstamas/.m2/repository-oss/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/home/cstamas/.m2/repository-oss/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/home/cstamas/.m2/repository-oss/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/home/cstamas/.m2/repository-oss/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar:/home/cstamas/.m2/repository-oss/com/google/errorprone/error_prone_annotations/2.11.0/error_prone_annotations-2.11.0.jar:/home/cstamas/.m2/repository-oss/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/home/cstamas/.m2/repository-oss/junit/junit/4.13.2/junit-4.13.2.jar:/home/cstamas/.m2/repository-oss/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/home/cstamas/.m2/repository-oss/org/apache/commons/commons-collections4/4.4/commons-collections4-4.4.jar:/home/cstamas/.m2/repository-oss/com/github/luben/zstd-jni/1.5.4-2/zstd-jni-1.5.4-2.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.784 s
[INFO] Finished at: 2023-03-08T14:31:58+01:00
[INFO] ------------------------------------------------------------------------
[cstamas@urnebes dsiutils (mavenize)]$ 

@vigna
Copy link
Owner

vigna commented Mar 8, 2023

Well, really thanks, that was a lot of work. I'll check it—if I do this I'll have to do the same to all my projects, so I have understand exactly what I'm doing. Any way to download automatically last releases like I do with Ivy?

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

Well, the "download automatically last releases" goes against reproducible builds principle (so even a tagged commit would become "movable target" if there is a new release of some dependency).

With Maven it is "best practice" to keep versions locked down, and on next dev iteration "just ask" for new versions:

[cstamas@urnebes dsiutils (mavenize)]$ mvn versions:display-dependency-updates
[INFO] Scanning for projects...
[INFO] 
[INFO] -----------------------< it.unimi.dsi:dsiutils >------------------------
[INFO] Building DSI Utilities 2.7.4-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- versions:2.15.0:display-dependency-updates (default-cli) @ dsiutils ---
[INFO] The following dependencies in Dependencies have newer versions:
[INFO]   ch.qos.logback:logback-classic ........................ 1.3.4 -> 1.4.5
[INFO]   ch.qos.logback:logback-core ........................... 1.3.4 -> 1.4.5
[INFO]   it.unimi.dsi:fastutil ............................... 8.5.11 -> 8.5.12
[INFO]   org.slf4j:slf4j-api ................................... 2.0.3 -> 2.0.6
[INFO] 
[INFO] No dependencies in pluginManagement of plugins have newer versions.
[INFO] 
[INFO] No dependencies in Plugin Dependencies have newer versions.
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.860 s
[INFO] Finished at: 2023-03-08T14:34:50+01:00
[INFO] ------------------------------------------------------------------------
[cstamas@urnebes dsiutils (mavenize)]$ 

@vigna
Copy link
Owner

vigna commented Mar 8, 2023

What did you say about Maven not forcing you to do things his way? 🤔😂

This is a complicated topic. For a library, the fact that versions are nailed down doesn't mean much, because when the library will be used by someone else Maven will resolve conflicts and the library might and up running with a different version. Rust has truly reproducible builds, at the price of building everything from scratch and never relying on dynamic libraries.

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

Well, there are some misconceptions here, and probably my wrong choice of words....

When I said "lock down" versions, I mean "express versions".

What happens in YOUR project (when your project P is being built) is that you build your P project that has D1, D2, ... dependencies (those 1st level specified in POM/dependencies), and Maven "mediates" the dependencies as needed (your case can be called "trivial").

When some other project Q uses your project P as a dependency things are different. In that case again, the built project Q prevails, while the transitive dependencies enlisted by your project P are taken into account as "recommendations", and Maven sorts out any conflicts and mediation.

So to say, when dsiutils is used as library, then yes, user of this project as dependency may opt to choose newer SLF4J API for example. To avoid that (and cause many sleepless nights to downstream developers) specify your dependencies as "locked down" -- [1.3.4]. Maven will try and most probably fail to mediate, but this is not what you want and DO NOT DO THIS,

It is assumed developer of Q (consumer of P) "knows best" what he does, and also assume something like "semantic versioning", so 1.2.1 is binary compatible with 1.2.2 and so on.

Just to demonstrate this breakage that you dont want to do:

  • on dsiutils (patch on top of this PR)
diff --git a/pom.xml b/pom.xml
index 85f5a79..ace04bd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,7 +62,7 @@
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
-      <version>2.0.3</version>
+      <version>[2.0.3]</version>
     </dependency>
     <dependency>
       <groupId>ch.qos.logback</groupId>

Locks down slf4j-api strictly to 2.0.3.

  • the project Q POM:
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.cstamas.example</groupId>
  <artifactId>project</artifactId>
  <version>1.0-SNAPSHOT</version>
  
  <dependencies>
    <dependency>
      <groupId>it.unimi.dsi</groupId>
      <artifactId>dsiutils</artifactId>
      <version>2.7.4-SNAPSHOT</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>[2.0.4]</version>
    </dependency>
  </dependencies>
</project>

Would use dsiutil with strictly another slf4j-api version.

  • and Maven error when trying to build it:
[INFO] Scanning for projects...
[INFO] 
[INFO] --------------------< org.cstamas.example:project >---------------------
[INFO] Building project 1.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.317 s
[INFO] Finished at: 2023-03-08T15:20:26+01:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project project: Could not resolve dependencies for project org.cstamas.example:project:jar:1.0-SNAPSHOT: Failed to collect dependencies for org.cstamas.example:project:jar:1.0-SNAPSHOT: Could not resolve version conflict among [it.unimi.dsi:dsiutils:jar:2.7.4-SNAPSHOT -> org.slf4j:slf4j-api:jar:[2.0.3,2.0.3], it.unimi.dsi:dsiutils:jar:2.7.4-SNAPSHOT -> ch.qos.logback:logback-classic:jar:1.3.4 -> org.slf4j:slf4j-api:jar:2.0.1, org.slf4j:slf4j-api:jar:[2.0.4,2.0.4]] -> [Help 1]

It figures these two are doomed to fail.

@vigna
Copy link
Owner

vigna commented Mar 8, 2023

That's what I said. 🤷🏻‍♂️

@cstamas
Copy link
Author

cstamas commented Mar 8, 2023

But again, this above is complicated issue, as you mention.

But for me, bigger and much much worse issue is this one: if I check out git tag 2.7.2 after 5 years, and let's assume Ceki releases SLF4J 3.0.0, Ivy will pick it up happily. Meaning, that the git tag is not reproducible, it is a "moving target", something that does not happen with approach like this one.

Dev cycle is:

  • code change (Java and POM, dep updates)
  • release -> tag
  • GOTO 1

Meaning all your tags are reproducible, are not "moving targets". You can rebuild, since as you mention, rebuilding from source is something many (ie. Google) chooses to do even with Java.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants