Showing posts with label maven. Show all posts
Showing posts with label maven. Show all posts

Saturday, June 22, 2019

maven-install-plugin copies files to your local .m2 repo

http://maven.apache.org/plugins/maven-install-plugin/usage.html

you can run this command from anywhere, no need for a pom.xml:


$ mvn install:install-file -Dfile=/c/pierre/downloads/apache-maven-3.5.3-bin.zip -DgroupId=pippo -DartifactId=pluto -Dpackaging=zip -Dversion=3.0
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-install-plugin:2.4:install-file (default-cli) @ standalone-pom ---
[INFO] Installing C:\pierre\downloads\apache-maven-3.5.3-bin.zip to c:\pierre\.m2\repository\pippo\pluto\3.0\pluto-3.0.zip
[INFO] Installing C:\Users\pierl\AppData\Local\Temp\mvninstall5440042488979291271.pom to c:\pierre\.m2\repository\pippo\pluto\3.0\pluto-3.0.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.689 s
[INFO] Finished at: 2019-06-22T16:08:57+02:00
[INFO] ------------------------------------------------------------------------




and the generated pom.xml is

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>pippo</groupId>
  <artifactId>pluto</artifactId>
  <version>3.0</version>
  <packaging>zip</packaging>
  <description>POM was created from install:install-file</description>
</project>



Wednesday, June 19, 2019

maven common plugins

For a very good overall tutorial on Maven, read this https://www.baeldung.com/maven

For a list of most plugins https://maven.apache.org/plugins/



https://www.baeldung.com/executable-jar-with-maven


maven-dependency-plugin



maven-jar-plugin

maven-assembly-plugin

maven-shade-plugin

com.jolira.onejar-maven-plugin

spring-boot-maven-plugin

tomcat7-maven-plugin


https://www.baeldung.com/maven-profiles

maven-help-plugin


https://www.baeldung.com/maven-dependency-latest-version


versions-maven-plugin

https://www.baeldung.com/maven-enforcer-plugin


maven-enforcer-plugin


https://www.mojohaus.org/build-helper-maven-plugin/usage.html

build-helper-maven-plugin

https://www.baeldung.com/maven-release-nexus
https://www.baeldung.com/install-local-jar-with-maven/

maven-install-plugin
maven-deploy-plugin
maven-release-plugin
nexus-staging-maven-plugin


https://www.baeldung.com/integration-testing-with-the-maven-cargo-plugin

maven-surefire-plugin



Monday, May 6, 2019

JDK maven Nexus and HTTPS

If your Nexus repository uses certificates signed by your own Root CA, chances are that a JDK doesn't trust them.

Then when you run

mvn package

you get


sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target


Go to your JAVA_HOME\jre\lib\security folder, where the cacerts file is located, and issue

keytool -list -v -keystore cacerts

enter "changeit" as password

this shold tell you all your trusted CAs

You should import your own CA certificate to into this keystore.


I have tried also setting:


set MAVEN_OPTS="-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true"

but it disn't work for me.




Tuesday, March 26, 2019

Monday, December 24, 2018

Maven Artifact Resolver

https://github.com/shrinkwrap/resolver#introduction-to-shrinkwrap-resolvers

add dependency org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-depchain:3.1.3 (default scope, not test scope)

package org.pierre.artifactresolver;

import java.io.File;

import org.jboss.shrinkwrap.resolver.api.maven.Maven;

public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
        File[] files = Maven.resolver().resolve("org.apache.commons:commons-lang3:3.8.1").withTransitivity().asFile();
        for (File file : files) {
         System.out.println(file.getAbsolutePath());
        }
        
    }
}



this prints:


Hello World!
c:\pierre\.m2\repository\org\apache\commons\commons-lang3\3.8.1\commons-lang3-3.8.1.jar




Monday, September 17, 2018

Nexus Maven repository migration

I need to migrate a Nexus 2.14 Maven repository to Nexus 3.10.

Unfortunately the Nexus product doesn't care much about migrations... probably they believe that, once installed, their product is immovable, like a sick elephant.

With a Nexus 2.14 to Nexus 2.14 migration, the repository structure is so simple that you can do it with a rsync.
But Nexus 3.10 is a totally different beast.

Luckily there are people who wrote tools:


https://github.com/simpligility/maven-repository-tools



I have to migrate from http://localhost:8081/nexus/content/repositories/releases/ (Nexus 2.14) to http://localhost:8181/repository/releases/ (Nexus 3.10)

git clone https://github.com/simpligility/maven-repository-tools.git
cd maven-repository-tools
mvn package
java -jar maven-repository-provisioner/target/maven-repository-provisioner-1.3.2-SNAPSHOT-jar-with-dependencies.jar

java -jar maven-repository-provisioner/target/maven-repository-provisioner-1.3.2-SNAPSHOT-jar-with-dependencies.jar -s http://localhost:8081/nexus/content/repositories/releases/ -t http://localhost:8181/repository/releases/ -u admin -p admin123 -a org.pierre:pvjoinfacestest:war:1.0


tragically, the tool doesn't allow wildcards.... so you must know in advance the gav of ALL the artifacts you have to migrate.... my impression is also that the .war is not really uploaded!


I am trying this one https://github.com/DarthHater/nexus-repository-import-scripts

copy https://github.com/DarthHater/nexus-repository-import-scripts/blob/master/mavenimport.sh to my /home/centos/nexus214/sonatype-work/nexus/storage/releases folder, then run

./mavenimport.sh -r http://localhost:8181/repository/releases/ -u admin -p admin123

and it works!



Tuesday, May 29, 2018

Sanity check on a Nexus 2 Maven Proxy repo

The task is: verify that all the JARs in a Nexus 2 repo are still in Maven Central.

I did a
find /path/to/nexusdata/central -name "*.jar" > alljarsfiltered.txt


and then run this Java application:


package mavenchecker;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Stream;

public class MavenChecker {
 public static ArrayList<String> errors = new ArrayList<String>();
 public static ArrayList<String> nonexisting = new ArrayList<String>();
 static int count  = 0;

 public static void main(String[] args) {

  String fileName = "/home/centos/Downloads/alljarsfiltered.txt";
  
  // read file into stream, try-with-resources
  try (Stream<String> stream = Files.lines(Paths.get(fileName)).parallel()) {

   stream.forEach((line) -> checkLine(line));
   

  } catch (IOException e) {
   e.printStackTrace();
  }

  for (String error : errors) {
   System.out.println("ERROR : " + error);
  }

  for (String nonexistingItem : nonexisting) {
   System.out.println("nonexisting : " + nonexistingItem);
  }

 }

 private static void checkLine(String line) {
  count++;
  if (count % 100 == 0) {
   System.out.println("COUNT " + count);
  }
  if (!line.endsWith(".jar"))
   return;

  String gavstring = line.replace("/path/to/nexusdata/central/", "");
  String[] parts = gavstring.split("/");
  int len = parts.length;
  if (len < 4) {
   System.err.println("invalid length for gavstring " + gavstring + " len = " + len + " should be at least 4");
   errors.add(gavstring);
  } else {
   String filename = parts[len - 1];
   String version = parts[len - 2];
   String artifactid = parts[len - 3];
   String group = String.join(".", Arrays.copyOfRange(parts, 0, len - 3));
   String message = "filename=" + filename + " group=" + group + " artifactid=" + artifactid + " version=" + version;
   //System.out.println(message);
   boolean exists = exists("https://repo.maven.apache.org/maven2/" + gavstring);
   if (!exists) nonexisting.add(gavstring);
   
   
  }

 }
 
 public static boolean exists(String URLName){
     try {
       HttpURLConnection.setFollowRedirects(false);
       // note : you may also need
       //        HttpURLConnection.setInstanceFollowRedirects(false)
       HttpURLConnection con =
          (HttpURLConnection) new URL(URLName).openConnection();
       con.setRequestMethod("HEAD");
       return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
     }
     catch (Exception e) {
        e.printStackTrace();
        return false;
     }
   }

}




Saturday, May 19, 2018

Jenkins Pipeline and OWASP dependency check

a) in Jenkins, configure a M3 instance in your "Global Tools" configuration section

b) make sure you have installed the OWASP dependency check plugin

c) create a Pipeline Jenkins project, name "owasptest", and simply paste this pipeline (it's a copy from the sample built-in "github and maven" pipeline):

node {
   def mvnHome
   stage('Preparation') { // for display purposes
      // Get some code from a GitHub repository
      git 'https://github.com/jglick/simple-maven-project-with-tests.git'
      // Get the Maven tool.
      // ** NOTE: This 'M3' Maven tool must be configured
      // **       in the global configuration.           
      mvnHome = tool 'M3'
   }
   stage('Build') {
      // Run the maven build
      if (isUnix()) {
         sh "'${mvnHome}/bin/mvn' -Dmaven.test.failure.ignore clean package"
      } else {
         bat(/"${mvnHome}\bin\mvn" -Dmaven.test.failure.ignore clean package/)
      }
   }
   stage('Results') {
      junit '**/target/surefire-reports/TEST-*.xml'
      archive 'target/*.jar'
   }
     stage("Dependency Check") {
    dependencyCheckAnalyzer datadir: 'dependency-check-data', isFailOnErrorDisabled: true, hintsFile: '', includeCsvReports: false, includeHtmlReports: false, includeJsonReports: false, isAutoupdateDisabled: false, outdir: '', scanpath: '', skipOnScmChange: false, skipOnUpstreamChange: false, suppressionFile: '', zipExtensions: ''

    dependencyCheckPublisher canComputeNew: false, defaultEncoding: '', healthy: '', pattern: '', unHealthy: ''

    archiveArtifacts allowEmptyArchive: true, artifacts: '**/dependency-check-report.xml', onlyIfSuccessful: true
  }
  
}



and leave "Use Groovy Sandbox" checked




Building jar: /home/centos/.jenkins/workspace/owasptest/target/simple-maven-project-with-tests-1.0-SNAPSHOT.jar

[DependencyCheck] Executing Dependency-Check with the following options:
[DependencyCheck] -name = owasptest
[DependencyCheck] -scanPath = /home/centos/.jenkins/workspace/owasptest
[DependencyCheck] -outputDirectory = /home/centos/.jenkins/workspace/owasptest
[DependencyCheck] -dataDirectory = /home/centos/.jenkins/workspace/owasptest/dependency-check-data
[DependencyCheck] -dataMirroringType = none
[DependencyCheck] -isQuickQueryTimestampEnabled = true
[DependencyCheck] -jarAnalyzerEnabled = true
[DependencyCheck] -nodePackageAnalyzerEnabled = true
[DependencyCheck] -nspAnalyzerEnabled = true
[DependencyCheck] -composerLockAnalyzerEnabled = true
[DependencyCheck] -pythonDistributionAnalyzerEnabled = true
[DependencyCheck] -pythonPackageAnalyzerEnabled = true
[DependencyCheck] -rubyBundlerAuditAnalyzerEnabled = false
[DependencyCheck] -rubyGemAnalyzerEnabled = true
[DependencyCheck] -cocoaPodsAnalyzerEnabled = true
[DependencyCheck] -swiftPackageManagerAnalyzerEnabled = true
[DependencyCheck] -archiveAnalyzerEnabled = true
[DependencyCheck] -assemblyAnalyzerEnabled = true
[DependencyCheck] -centralAnalyzerEnabled = true
[DependencyCheck] -nuspecAnalyzerEnabled = true
[DependencyCheck] -nexusAnalyzerEnabled = false
[DependencyCheck] -autoconfAnalyzerEnabled = true
[DependencyCheck] -cmakeAnalyzerEnabled = true
[DependencyCheck] -opensslAnalyzerEnabled = true
[DependencyCheck] -showEvidence = true
[DependencyCheck] -formats = XML
[DependencyCheck] -autoUpdate = true
[DependencyCheck] -updateOnly = false
[DependencyCheck] Data directory created
[DependencyCheck] Scanning: /home/centos/.jenkins/workspace/owasptest
[DependencyCheck] Analyzing Dependencies

[Pipeline] dependencyCheckPublisher

[DependencyCheck] Collecting Dependency-Check analysis files...
[DependencyCheck] Searching for all files in /home/centos/.jenkins/workspace/owasptest that match the pattern **/dependency-check-report.xml
[DependencyCheck] Parsing 1 file in /home/centos/.jenkins/workspace/owasptest
[DependencyCheck] Successfully parsed file /home/centos/.jenkins/workspace/owasptest/dependency-check-report.xml with 0 unique warnings and 0 duplicates.


At this point you can view the report in http://localhost:9090/job/owasptest/lastSuccessfulBuild/artifact/dependency-check-report.xml



To get interesting result you should use https://github.com/WebGoat/WebGoat.git

At the end, a monster DB (330 MB) is built at /home/centos/.jenkins/workspace/owasptest/dependency-check-data/dc.h2.db
To learn mode about this DB, read here https://github.com/jeremylong/DependencyCheck/tree/master/core/src/main/resources/data
and here https://github.com/jeremylong/DependencyCheck/blob/master/core/src/main/resources/dependencycheck.properties

Ref: https://issues.jenkins-ci.org/browse/JENKINS-37437




Saturday, May 5, 2018

httpproxy with littleproxy

great product https://github.com/adamfisk/LittleProxy

git clone https://github.com/adamfisk/LittleProxy
cd LittleProxy
./run.bash


To intercept HTTP requests, edit org.littleshoot.proxy.Launcher and insert the line with "withFiltersSource":

System.out.println("About to start...");
bootstrap.withFiltersSource(new MyHttpFiltersSourceAdapter());
bootstrap.start();



package org.littleshoot.proxy.impl;

import org.littleshoot.proxy.HttpFilters;
import org.littleshoot.proxy.HttpFiltersAdapter;
import org.littleshoot.proxy.HttpFiltersSource;
import java.util.Arrays;

import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.DefaultHttpRequest;

public class MyHttpFiltersSourceAdapter implements HttpFiltersSource {
    private static final String HTTP_REPO1_MAVEN_ORG_MAVEN2 = "http://repo1.maven.org/maven2/";
    public HttpFiltersAdapter filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) {
        return new HttpFiltersAdapter(originalRequest) {
            @Override
            public HttpResponse clientToProxyRequest(HttpObject httpObject) {
                // TODO: implement your filtering here
             System.out.println("clientToProxyRequest invoked");
             System.out.println(httpObject.toString());
             if (httpObject instanceof DefaultHttpRequest) {
              DefaultHttpRequest request = (DefaultHttpRequest)httpObject;
              System.out.println("it's a DefaultHttpRequest with uri:");
              String uri = request.getUri()
              System.out.println(uri);
              System.out.println(request.toString());
              System.out.println(request.headers());
  if (uri.startsWith(HTTP_REPO1_MAVEN_ORG_MAVEN2)) {
   String gavstring = uri.substring(HTTP_REPO1_MAVEN_ORG_MAVEN2.length());
   System.out.println("gavstring=" + gavstring);
   String[] parts = gavstring.split("/");
   int len = parts.length;
   if (len < 4) {
    System.err.println("invalid length for gavstring " + gavstring + " len = " + len + " should be at least 4");
   }
   else {
    String filename =  parts[len-1];
    String version =  parts[len-2];
    String artifactid = parts[len-3];
    String group = String.join(".", Arrays.copyOfRange(parts, 0, len - 3));
    System.out.println("filename=" + filename + " version=" + version + " artifactid=" + artifactid + " group=" + group);
   }
   
   
    }
    }
         System.out.println();
        return null;
    }

    @Override
    public HttpObject serverToProxyResponse(HttpObject httpObject) {
             System.out.println("serverToProxyResponse invoked");
             System.out.println(httpObject.toString());
             System.out.println();
                return httpObject;
            }
        };
    }

    @Override
    public int getMaximumRequestBufferSizeInBytes() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int getMaximumResponseBufferSizeInBytes() {
        // TODO Auto-generated method stub
    return 0;
    }
}

This is priceless to analyze what is going on between Nexus repository and Maven central: make sure your maven uses Nexus as a mirror: vi /home/centos/apache-maven-3.5.0/conf/settings.xml
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>

then make sure that Nexus "maven-central" proxy repo (http://localhost:8081/repository/maven-central/) points to http://repo1.maven.org/maven2/ and not to https://repo1.maven.org/maven2/ (it's easier to trace http traffic than https) then configure Nexus 3.11 (login as admin/admin123, menu System/HTTP, set HTTP proxy to localhost and 8080) let's prepare a Maven project to compile: git clone https://github.com/gabrielf/maven-samples cd maven-samples/ mvn package to make sure a give jar is missing from the m2 repository, delete it before each build: rm -rf /home/centos/.m2/repository/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.jar and remove it also from Nexus (Search/Maven, search for plexus-utils 3.0, Delete component) What you see in the LittleProxy stdout is:
clientToProxyRequest invoked
DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)
GET http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.jar HTTP/1.1
Host: repo1.maven.org
Proxy-Connection: Keep-Alive
User-Agent: Nexus/3.11.0-01 (OSS; Linux; 3.10.0-693.17.1.el7.x86_64; amd64; 1.8.0_141)
Accept-Encoding: gzip,deflate
As you can read in https://github.com/adamfisk/LittleProxy/blob/master/src/main/java/org/littleshoot/proxy/HttpFilters.java for the method clientToProxyRequest, if you return null the request will be further processed; if you return a io.netty.handler.codec.http.HttpResponse, then you effectively break the flow and you can stop the request. It's worth mentioning also https://github.com/lightbody/browsermob-proxy as a superset of Littleproxy





Tuesday, April 17, 2018

Docker run a command in an image

How many times you are baffled because you run

docker run myregistry/maven:3-alpine

and it simply exists without doing anything.

Then you do

docker run myregistry/maven:3-alpine /bin/bash

and the same thing happens

Then you inspect the image:

docker image inspect myregistry/maven:3-alpine


and you notice

           "Cmd": [
                "mvn"
            ],

          "Entrypoint": [
                "/usr/local/bin/mvn-entrypoint.sh"
            ],


and you wonder what is actually executed....

Luckily you can simply OVERRIDE the entrypoint (see https://gist.github.com/mitchwongho/11266726 ) :


docker run -it --entrypoint /bin/bash myregistry/maven:3-alpine

so you enter directly a bash shell, without executing the original Entrypoint of course.


The documentation of this precious Maven image is https://hub.docker.com/_/maven/ here

mvn settings are in /usr/share/maven/ref/settings-docker.xml and (maybe) in /usr/share/maven/conf/settings.xml
mvn binaries are in /usr/bin/mvn -> /usr/share/maven/bin/mvn


Ref: docker run https://docs.docker.com/engine/reference/commandline/run/#options


Priceless, to debug Maven: mvn -X help:effective-settings



Saturday, March 24, 2018

Maven/Eclipse Horror Show

I have updated recently my Maven binaries, of course I forgot to change The "User Settings" property in Eclipse to point to the new location of the settings.xml.

Of course Eclipse silently fails to report the issue (unless you go and open the Maven tab in Preferences)

And all of a sudden nothing works and when I open my pom.xml I get this:

Project build error: Non-resolvable parent POM for org.wildfly.quickstarts:quickstart-parent:13.0.0-SNAPSHOT: Could not transfer artifact org.jboss:jboss-parent:pom:25 from/to jboss-enterprise-maven-repository (https://maven.repository.redhat.com/ga/): NullPointerException and 'parent.relativePath' points at no local POM


Working with Maven and Eclipse I feel young again.... it feels like the 1985 - actually my Pascal compiler on Apple II was far more sophisticated that these modern products.




Monday, February 5, 2018

Maven version sorting with Java 8

You can easily sort versions in Maven using org.apache.maven.artifact.versioning.ComparableVersion :

pom.xml:

<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.pierre</groupId>
  <artifactId>mavensort</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
   <dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-artifact</artifactId>
    <version>3.5.2</version>
   </dependency>
  </dependencies>
</project>

package mavensort;

import org.apache.maven.artifact.versioning.ComparableVersion;

public class Artifact implements Comparable<Artifact> {
 int id;
 String version;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getVersion() {
  return version;
 }
 public void setVersion(String version) {
  this.version = version;
 }
 public Artifact(int id, String version) {
  super();
  this.id = id;
  this.version = version;
 }

 public int compareTo(Artifact o) {
  
  ComparableVersion cv1 = new ComparableVersion(version);
  ComparableVersion cv2 = new ComparableVersion(o.getVersion());
  int compareTo = cv1.compareTo(cv2);
  System.out.println("compareTo " + version + " " + o.getVersion() + " " + compareTo);
  return compareTo;
 }
 

}


package mavensort;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.apache.maven.artifact.versioning.ComparableVersion;
import org.junit.Test;

public class ArtifactTest {

 @Test
 public void testSort() {
  String version1 = "1.2";
  ComparableVersion cv1 = new ComparableVersion(version1);
  String version2 = "1.12";
  ComparableVersion cv2 = new ComparableVersion(version2);
  assert(cv1.compareTo(cv2) < 0);

 }
 
 @Test
 public void testSortCollection() {
  Artifact a1 = new Artifact(1, "1.2");
  Artifact a2 = new Artifact(2, "1.12");
  Artifact a3 = new Artifact(3, "0.12");
  List<Artifact> list = Arrays.asList(a1, a2, a3);
  Supplier<List<Artifact>> supplier = () -> new ArrayList<Artifact>();
  List<Artifact> sortedList = list.stream().sorted().collect(Collectors.toCollection(supplier));
  sortedList.forEach(item -> System.out.println(item.version));
  
 }

}


The use of streams and Supplier just to sort a collection is voodoistic. One can simply code this:

Collections.sort(list);
list.forEach(item -> System.out.println(item.version));


You can use also an external comparator:

@Test
 public void testSortCollectionExternalComparator() {
  Artifact a1 = new Artifact(1, "1.2");
  Artifact a2 = new Artifact(2, "1.12");
  Artifact a3 = new Artifact(3, "0.12");
  List<Artifact> list = Arrays.asList(a1, a2, a3);
  list.sort(new ArtifactComparator());
  list.forEach(item -> System.out.println(item.version));
  
 }


public class ArtifactComparator implements Comparator<Artifact> {

 @Override
 public int compare(Artifact o1, Artifact o2) {
  ComparableVersion cv1 = new ComparableVersion(o1.getVersion());
  ComparableVersion cv2 = new ComparableVersion(o2.getVersion());
  int compareTo = cv1.compareTo(cv2);
  System.out.println("C2 compareTo " + o1.getVersion() + " " + o2.getVersion() + " " + compareTo);
  return compareTo;
 }

}



Maven dependency is

<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.6.0</version>
</dependency>





The external dependency is not necessary, you can simply copy the class https://raw.githubusercontent.com/apache/maven/master/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java into your project, luckily it has no other dependencies to other classes in the same package

Ref: https://www.geeksforgeeks.org/collections-sort-java-examples/ for comparators



Wednesday, January 31, 2018

debug maven settings

mvn archetype:generate -DarchetypeArtifactId=wildfly-javaee7-webapp-archetype -DarchetypeGroupId=org.wildfly.archetype -DarchetypeVersion=8.2.0.Final

(create a nexustests artifactId)

cd nexustests/
mvn -X help:effective-settings

Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T09:58:13+02:00)
Maven home: /home/centos/apache-maven-3.5.2
Java version: 1.8.0_161, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-693.11.6.el7.x86_64", arch: "amd64", family: "unix"


[DEBUG] Reading global settings from /home/centos/apache-maven-3.5.2/conf/settings.xml
[DEBUG] Reading user settings from /home/centos/.m2/settings.xml
[DEBUG] Reading global toolchains from /home/centos/apache-maven-3.5.2/conf/toolchains.xml
[DEBUG] Reading user toolchains from /home/centos/.m2/toolchains.xml
[DEBUG] Using local repository at /home/centos/.m2/repository



[DEBUG] Dependency collection stats: {ConflictMarker.analyzeTime=1779672, ConflictMarker.markTime=809680, ConflictMarker.nodeCount=135, ConflictIdSorter.graphTime=1026621, ConflictIdSorter.topsortTime=610945, ConflictIdSorter.conflictIdCount=39, ConflictIdSorter.conflictIdCycleCount=0, ConflictResolver.totalTime=8120595, ConflictResolver.conflictItemCount=95, DefaultDependencyCollector.collectTime=4585627924, DefaultDependencyCollector.transformTime=15642922}
[DEBUG] org.apache.maven.plugins:maven-help-plugin:jar:2.2:
[DEBUG]    org.apache.maven:maven-artifact:jar:2.2.1:compile
[DEBUG]    org.apache.maven:maven-core:jar:2.2.1:compile
[DEBUG]       org.slf4j:slf4j-jdk14:jar:1.5.6:runtime
[DEBUG]          org.slf4j:slf4j-api:jar:1.5.6:runtime
[DEBUG]       org.slf4j:jcl-over-slf4j:jar:1.5.6:runtime
[DEBUG]       org.apache.maven.reporting:maven-reporting-api:jar:2.2.1:compile
[DEBUG]          org.apache.maven.doxia:doxia-sink-api:jar:1.1:compile
[DEBUG]          org.apache.maven.doxia:doxia-logging-api:jar:1.1:compile
[DEBUG]       org.apache.maven:maven-repository-metadata:jar:2.2.1:compile
[DEBUG]       org.apache.maven:maven-error-diagnostics:jar:2.2.1:compile
[DEBUG]       commons-cli:commons-cli:jar:1.2:compile
[DEBUG]       org.apache.maven:maven-artifact-manager:jar:2.2.1:compile
[DEBUG]          backport-util-concurrent:backport-util-concurrent:jar:3.1:compile
[DEBUG]       classworlds:classworlds:jar:1.1:compile
[DEBUG]       org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3:compile
[DEBUG]          org.sonatype.plexus:plexus-cipher:jar:1.4:compile
[DEBUG]    org.apache.maven:maven-model:jar:2.2.1:compile
[DEBUG]    org.apache.maven:maven-plugin-api:jar:2.2.1:compile
[DEBUG]    org.apache.maven:maven-plugin-descriptor:jar:2.2.1:compile
[DEBUG]    org.apache.maven:maven-project:jar:2.2.1:compile
[DEBUG]       org.apache.maven:maven-plugin-registry:jar:2.2.1:compile
[DEBUG]       org.codehaus.plexus:plexus-interpolation:jar:1.11:compile
[DEBUG]    org.apache.maven:maven-settings:jar:2.2.1:compile
[DEBUG]    org.apache.maven:maven-profile:jar:2.2.1:compile
[DEBUG]    org.apache.maven:maven-monitor:jar:2.2.1:compile
[DEBUG]    org.apache.maven:maven-plugin-parameter-documenter:jar:2.2.1:compile
[DEBUG]    org.apache.maven.plugin-tools:maven-plugin-tools-api:jar:2.4.3:compile
[DEBUG]       jtidy:jtidy:jar:4aug2000r7-dev:compile
[DEBUG]    org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9:compile
[DEBUG]       junit:junit:jar:3.8.1:compile
[DEBUG]    org.codehaus.plexus:plexus-interactivity-api:jar:1.0-alpha-4:compile
[DEBUG]    org.codehaus.plexus:plexus-utils:jar:1.5.7:compile
[DEBUG]    jdom:jdom:jar:1.0:compile
[DEBUG]    com.thoughtworks.xstream:xstream:jar:1.4.3:compile
[DEBUG]       xmlpull:xmlpull:jar:1.1.3.1:compile
[DEBUG]       xpp3:xpp3_min:jar:1.1.4c:compile
[DEBUG]    commons-lang:commons-lang:jar:2.4:compile



and a whole lot of other information that I have removed....


Awesome tool to troubleshoot STINKY Maven



Saturday, December 30, 2017

maven wildfly archetype push to github

To get started with a basic webapp for wildfly:

mvn archetype:generate -DarchetypeArtifactId=wildfly-javaee7-webapp-archetype -DarchetypeGroupId=org.wildfly.archetype -DarchetypeVersion=8.2.0.Final


https://mvnrepository.com/artifact/org.wildfly.archetype/wildfly-javaee7-webapp-archetype/8.2.0.Final


once you have created the project (groupid=org.pierre, artifactid=aostapictures)
you do the following:

create a repository in gthub, named aostapictures (not sure if you can do it with git command line...I did with github web ui)

cd aostapictures/
git init
echo "/target/" > .gitignore
git add *
git add .cheatsheet.xml
git add .gitignore
git add .classpath
git add .factorypath
git add .project
git add .settings/
git commit -am "first commit"
git remote add origin https://github.com/vernetto/aostapictures.git
git push --set-upstream origin master
git push -u origin master


see also https://help.github.com/articles/adding-a-remote/

Thursday, November 30, 2017

Another poorly implemented feature of Eclipse: repository search

Eclipse is a champion at implementing in an extremely unappealing and inefficient way even the simplest feature.


Window/Show view/ Maven Repository, right click on central , "Full Index Enabled". Then "Rebuild Index" (this especially useful if you get an error about the index having to be rebuilt for Lucene 6)

Then open the POM.XML, click on the Dependencies tab, add, and where it says "enter groupId, artifactId..." type *junit*

On the status bar on the bottom right you will see "repository search" and an animated icon...

It's AMAZING how slow it is....

much faster to google for "maven junit" and you get immediately the GAV

Eclipse: Erroneous Clumsy Ludicrous Inefficient Pathetic Shitty Elephant


See http://www.vogella.com/tutorials/EclipseMaven/article.html

Thursday, November 16, 2017

PGP verification of Maven artifacts

I run the following commands:

git clone https://github.com/gabrielf/maven-samples
cd maven-samples
mvn com.github.s4u.plugins:pgpverify-maven-plugin:check

and I get this interesting results:


Downloading: https://repo.maven.apache.org/maven2/junit/junit-dep/4.10/junit-dep-4.10.jar.asc
[WARNING] Could not validate integrity of download from https://repo.maven.apache.org/maven2/junit/junit-dep/4.10/junit-dep-4.10.jar.asc: Checksum validation failed, no checksums available
[WARNING] Checksum validation failed, no checksums available for https://repo.maven.apache.org/maven2/junit/junit-dep/4.10/junit-dep-4.10.jar.asc
Downloaded: https://repo.maven.apache.org/maven2/junit/junit-dep/4.10/junit-dep-4.10.jar.asc (535 B at 3.2 kB/s)
Downloading: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.2.1/hamcrest-core-1.2.1.jar.asc
[WARNING] Could not validate integrity of download from https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.2.1/hamcrest-core-1.2.1.jar.asc: Checksum validation failed, no checksums available
[WARNING] Checksum validation failed, no checksums available for https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.2.1/hamcrest-core-1.2.1.jar.asc
Downloaded: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.2.1/hamcrest-core-1.2.1.jar.asc (832 B at 5.7 kB/s)
Downloading: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-library/1.2.1/hamcrest-library-1.2.1.jar.asc
[WARNING] Could not validate integrity of download from https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-library/1.2.1/hamcrest-library-1.2.1.jar.asc: Checksum validation failed, no checksums available
[WARNING] Checksum validation failed, no checksums available for https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-library/1.2.1/hamcrest-library-1.2.1.jar.asc
Downloaded: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-library/1.2.1/hamcrest-library-1.2.1.jar.asc (832 B at 4.5 kB/s)
Downloading: https://repo.maven.apache.org/maven2/org/mockito/mockito-core/1.8.5/mockito-core-1.8.5.jar.asc
[WARNING] No signature for org.mockito:mockito-core:jar:1.8.5
Downloading: https://repo.maven.apache.org/maven2/org/objenesis/objenesis/1.0/objenesis-1.0.jar.asc
[WARNING] Could not validate integrity of download from https://repo.maven.apache.org/maven2/org/objenesis/objenesis/1.0/objenesis-1.0.jar.asc: Checksum validation failed, no checksums available
[WARNING] Checksum validation failed, no checksums available for https://repo.maven.apache.org/maven2/org/objenesis/objenesis/1.0/objenesis-1.0.jar.asc
Downloaded: https://repo.maven.apache.org/maven2/org/objenesis/objenesis/1.0/objenesis-1.0.jar.asc (189 B at 1.4 kB/s)
Downloading: https://repo.maven.apache.org/maven2/org/objenesis/objenesis/1.0/objenesis-1.0.pom.asc
[WARNING] Could not validate integrity of download from https://repo.maven.apache.org/maven2/org/objenesis/objenesis/1.0/objenesis-1.0.pom.asc: Checksum validation failed, no checksums available
[WARNING] Checksum validation failed, no checksums available for https://repo.maven.apache.org/maven2/org/objenesis/objenesis/1.0/objenesis-1.0.pom.asc
Downloaded: https://repo.maven.apache.org/maven2/org/objenesis/objenesis/1.0/objenesis-1.0.pom.asc (189 B at 1.3 kB/s)
Downloading: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-library/1.2.1/hamcrest-library-1.2.1.pom.asc
[WARNING] Could not validate integrity of download from https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-library/1.2.1/hamcrest-library-1.2.1.pom.asc: Checksum validation failed, no checksums available
[WARNING] Checksum validation failed, no checksums available for https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-library/1.2.1/hamcrest-library-1.2.1.pom.asc
Downloaded: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-library/1.2.1/hamcrest-library-1.2.1.pom.asc (832 B at 5.1 kB/s)
Downloading: https://repo.maven.apache.org/maven2/org/mockito/mockito-core/1.8.5/mockito-core-1.8.5.pom.asc
[WARNING] No signature for org.mockito:mockito-core:pom:1.8.5
Downloading: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.2.1/hamcrest-core-1.2.1.pom.asc
[WARNING] Could not validate integrity of download from https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.2.1/hamcrest-core-1.2.1.pom.asc: Checksum validation failed, no checksums available
[WARNING] Checksum validation failed, no checksums available for https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.2.1/hamcrest-core-1.2.1.pom.asc
Downloaded: https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.2.1/hamcrest-core-1.2.1.pom.asc (832 B at 4.6 kB/s)
Downloading: https://repo.maven.apache.org/maven2/junit/junit-dep/4.10/junit-dep-4.10.pom.asc
[WARNING] Could not validate integrity of download from https://repo.maven.apache.org/maven2/junit/junit-dep/4.10/junit-dep-4.10.pom.asc: Checksum validation failed, no checksums available
[WARNING] Checksum validation failed, no checksums available for https://repo.maven.apache.org/maven2/junit/junit-dep/4.10/junit-dep-4.10.pom.asc
Downloaded: https://repo.maven.apache.org/maven2/junit/junit-dep/4.10/junit-dep-4.10.pom.asc (535 B at 3.0 kB/s)
[INFO] Receive key: 5A01BE76E757922C to d:\pierre\.m2\repository\pgpkeys-cache\5A\01\5A01BE76E757922C.asc
[INFO] org.hamcrest:hamcrest-core:jar:1.2.1 PGP Signature OK
KeyId: 0x5A01BE76E757922C UserIds: [Marc von Renteln ]
[INFO] Receive key: 7C7D8456294423BA to d:\pierre\.m2\repository\pgpkeys-cache\7C\7D\7C7D8456294423BA.asc
[INFO] org.objenesis:objenesis:pom:1.0 PGP Signature OK
KeyId: 0x7C7D8456294423BA UserIds: [Henri Tremblay ]
[INFO] org.hamcrest:hamcrest-library:jar:1.2.1 PGP Signature OK
KeyId: 0x5A01BE76E757922C UserIds: [Marc von Renteln ]
[INFO] org.objenesis:objenesis:jar:1.0 PGP Signature OK
KeyId: 0x7C7D8456294423BA UserIds: [Henri Tremblay ]
[INFO] org.hamcrest:hamcrest-library:pom:1.2.1 PGP Signature OK
KeyId: 0x5A01BE76E757922C UserIds: [Marc von Renteln ]
[INFO] org.hamcrest:hamcrest-core:pom:1.2.1 PGP Signature OK
KeyId: 0x5A01BE76E757922C UserIds: [Marc von Renteln ]
[INFO] Receive key: 88AA1FEE831A7E89 to d:\pierre\.m2\repository\pgpkeys-cache\88\AA\88AA1FEE831A7E89.asc
[INFO] junit:junit-dep:jar:4.10 PGP Signature OK
KeyId: 0x88AA1FEE831A7E89 UserIds: [David Saff ]
[INFO] junit:junit-dep:pom:4.10 PGP Signature OK
KeyId: 0x88AA1FEE831A7E89 UserIds: [David Saff ]




In fact, as reported by http://branchandbound.net/blog/security/2012/08/verify-dependencies-using-pgp/ , only 2 percent of companies verify PGP signature, and a signature is mandatory in Maven Central only for last 3 years, so old components most of the time have NO SIGNATURE!





Wednesday, November 15, 2017

Not using SSL to connect to Maven? dilettante (=amateur) !

https://max.computer/blog/how-to-take-over-the-computer-of-any-java-or-clojure-or-scala-developer/

If you want to play a trick on your friends, you can use Dilettante to man-in-the-middle a Maven Repository request and inject some bad behaviour, the source code is here https://github.com/mveytsman/dilettante but don't do in your company, you might not win friends.

Very interesting reading https://stackoverflow.com/a/24987915/651288

You can upgrade your URL to HTTPS at no cost (it used to be a paying service) https://support.sonatype.com/hc/en-us/articles/213465458

Use this https://repo1.maven.org/maven2/ , not http://repo1.maven.org/maven2/

To run a verification of your build dependent artifacts:

mvn com.github.s4u.plugins:pgpverify-maven-plugin:check

you can create locally a gpg key:

gpg
gpg --gen-key
gpg --list-keys
gpg --list-secret-keys

to verify a component:
gpg --verify plexus-cipher-1.7.jar.asc plexus-chipher-1.7.jar


Very good article on XBI (cross build injection) http://branchandbound.net/blog/security/2012/03/crossbuild-injection-how-safe-is-your-build/

and about verifying components using MIT key repo : http://branchandbound.net/blog/security/2012/08/verify-dependencies-using-pgp/


Interesting Maven plugin to whitelist components in a build http://gary-rowe.com/agilestack/2013/07/03/preventing-dependency-chain-attacks-in-maven/

and here another similar Maven plugin to check PGP signature https://www.simplify4u.org/pgpverify-maven-plugin/index.html




Tuesday, October 31, 2017

Maven to Repository protocol

I have used this minimalistic proxy service:

http://www.jcgonzalez.com/java-simple-proxy-socket-server-examples#1

and just added a "System.out.println("read: " + new String(request));" after the "outToServer.flush();"

then in my settings.xml I point the mirror to localhost instead of the real Nexus Repository service, and I start my proxy pointing to Nexus and listening on port 80. This way, I can intercept all http request issued by Maven.


The result is quite simple:


Starting proxy for nexus-java:80 on port 80
read: GET /content/repositories/approved-from-central/commons-logging/commons-logging-api/1.1/commons-logging-api-1.1.pom HTTP/1.1
Cache-control: no-cache
Cache-store: no-store
Pragma: no-cache
Expires: 0
Accept-Encoding: gzip
User-Agent: Apache-Maven/3.3.9 (Java 1.8.0_102; Windows 7 6.1)
Host: localhost
Connection: Keep-Alive



read: GET /content/repositories/approved-from-central/commons-logging/commons-logging-api/1.1/commons-logging-api-1.1.pom.sha1 HTTP/1.1
Cache-control: no-cache
Cache-store: no-store
Pragma: no-cache
Expires: 0
Accept-Encoding: gzip
User-Agent: Apache-Maven/3.3.9 (Java 1.8.0_102; Windows 7 6.1)
Host: localhost
Connection: Keep-Alive


read: GET /content/repositories/approved-from-central/commons-logging/commons-logging-api/1.1/commons-logging-api-1.1.jar HTTP/1.1
Cache-control: no-cache
Cache-store: no-store
Pragma: no-cache
Expires: 0
Accept-Encoding: gzip
User-Agent: Apache-Maven/3.3.9 (Java 1.8.0_102; Windows 7 6.1)
Host: localhost
Connection: Keep-Alive


read: GET /content/repositories/approved-from-central/commons-logging/commons-logging-api/1.1/commons-logging-api-1.1.jar.sha1 HTTP/1.1
Cache-control: no-cache
Cache-store: no-store
Pragma: no-cache
Expires: 0
Accept-Encoding: gzip
User-Agent: Apache-Maven/3.3.9 (Java 1.8.0_102; Windows 7 6.1)
Host: localhost
Connection: Keep-Alive


read: GET /content/repositories/approved-from-central/commons-lang/commons-lang/2.1/commons-lang-2.1.pom HTTP/1.1
Cache-control: no-cache
Cache-store: no-store
Pragma: no-cache
Expires: 0
Accept-Encoding: gzip
User-Agent: Apache-Maven/3.3.9 (Java 1.8.0_102; Windows 7 6.1)
Host: localhost
Connection: Keep-Alive


read: GET /content/repositories/approved-from-central/commons-lang/commons-lang/2.1/commons-lang-2.1.pom.sha1 HTTP/1.1
Cache-control: no-cache
Cache-store: no-store
Pragma: no-cache
Expires: 0
Accept-Encoding: gzip
User-Agent: Apache-Maven/3.3.9 (Java 1.8.0_102; Windows 7 6.1)
Host: localhost
Connection: Keep-Alive


read: GET /content/repositories/approved-from-central/commons-lang/commons-lang/2.1/commons-lang-2.1.jar HTTP/1.1
Cache-control: no-cache
Cache-store: no-store
Pragma: no-cache
Expires: 0
Accept-Encoding: gzip
User-Agent: Apache-Maven/3.3.9 (Java 1.8.0_102; Windows 7 6.1)
Host: localhost
Connection: Keep-Alive


read: GET /content/repositories/approved-from-central/commons-lang/commons-lang/2.1/commons-lang-2.1.jar.sha1 HTTP/1.1
Cache-control: no-cache
Cache-store: no-store
Pragma: no-cache
Expires: 0
Accept-Encoding: gzip
User-Agent: Apache-Maven/3.3.9 (Java 1.8.0_102; Windows 7 6.1)
Host: localhost
Connection: Keep-Alive




so it's extremely easy to parse the GET command and implement a firewall/filter to block components that you know are harmful.







Saturday, October 28, 2017

Setting up Maven to retrieve ojdbc8.jar

googling around in StackOverflow there is a huge variety of approaches to this very common problem: you must add the artifact to your build, but it's not available in Maven Central.... what to do?

Some resort to downloading it manually and deploying it to the local Maven repo. Some even include the file in their WEB-INF/lib folder in their SCM project. Some use some third party public repositories (like Atlassian, code.lds.org, ... ) who graciously host these artifacts.... all fine when you play on your PC, but in a serious company with strict security control all this would not be allowed. Some folks simply cowboy-style put it somewhere in their HD and add the external JAR to Eclipse.... what happens next, they don't really care, as long as it works on their machine.

Oracle hosts these artifacts in their Public Oracle Maven repository, but you need to authenticate yourself (for which reason, it's totally obscure to me!)

https://docs.oracle.com/middleware/1213/core/MAVEN/config_maven_repo.htm#MAVEN9016 here how to setup maven to connect to the Oracle repo (basically: in settings.xml you have to declare the server maven.oracle.com authenticating with your user, the in your pom.xml you must declare a rerpository with id matching this maven.oracle.com server, then a pluginRepository with id again maven.oracle.com. At this point you can declare the dependency

<dependency>
   <groupId>com.oracle.jdbc</groupId>
   <artifactId>ojdbc8</artifactId>
   <version>12.2.0.1</version>
  </dependency>

This post explains it in a lot of detail https://blogs.oracle.com/dev2dev/get-oracle-jdbc-drivers-and-ucp-from-oracle-maven-repository-without-ides

To make things much more complicated, the repository is not browsable https://maven.oracle.com/com/oracle/ojdbc8/ ... how to determine it content, no clue!


See also https://stackoverflow.com/questions/9898499/oracle-jdbc-ojdbc6-jar-as-a-maven-dependency] and https://stackoverflow.com/questions/1074869/find-oracle-jdbc-driver-in-maven-repository

https://mvnrepository.com/artifact/com.oracle/ojdbc6/12.1.0.1-atlassian-hosted to get ojdbc6.jar from maven (atlassian hosted!)

https://developer.atlassian.com/docs/advanced-topics/working-with-maven/atlassian-maven-repositories to configure atlassian repo in pom.xml



IMPORTANT: when running in Eclipse, make sure you are NOT using the Embedded installation of Maven while you are configuring an EXTERNAL Maven configuration.... this multiplicity of installations and configurations only makes the developer's life more miserable.... IMHO it's better to have an independent, external, universal installation rather than an embedded one.... again another major fuck-up in Eclipse design. Forget Eclipse, use Netbeans and Intellij.


CODE: a working pom.xml is available here https://github.com/vernetto/JavaMonAmour/tree/master/oracletest



Wednesday, September 27, 2017

Maven deploy-file for batch upload

Unfortunately in the Nexus 3.5 and 3.6 version there is no batch upload of artifacts (in Nexus 2.X it was much easier: just rsync your Maven repo and "rebuild index"

http://maven.apache.org/plugins/maven-deploy-plugin/deploy-file-mojo.html

git clone https://github.com/gabrielf/maven-samples

git clone https://github.com/ronbadur/maven-artifacts-uploader

I start nexus with https://github.com/sonatype/docker-nexus3

sample command:

mvn -e -X deploy:deploy-file -q -DpomFile=/home/centos/myrepo/org/vafer/jdependency/1.1/jdependency-1.1.pom -Dfile=/home/centos/myrepo/org/vafer/jdependency/1.1/jdependency-1.1.jar -DrepositoryId=nexus -Durl=http://localhost:8081/repository/maven-releases/ -Dpackaging=jar


maven's settings.xml should contain

<server>
      <id>nexus</id>
      <username>admin</username>
      <password>admin123</password>
    </server>




If you get "ReasonPhrase: Repository does not allow updating assets: maven-releases." , make sure you set "allow redeploy" in the Deployment policy"

If you get "Cannot deploy artifact from the local repository:" it's because your source file is inside the .m2/repository folder - which is forbidden

See Sonatype help on this topic https://support.sonatype.com/hc/en-us/articles/213465818-How-can-I-programmatically-upload-an-artifact-into-Nexus-2-