PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, April 14, 2022

[FIXED] How can I migrate JCenter artifact to the Sonatype Maven repository?

 April 14, 2022     jcenter, maven, migration, sonatype     No comments   

Issue

The JCenter Maven repository will be down in some month.

href="https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/?utm_source=mkto&utm_medium=email&utm_campaign=bintray-sunset&utm_content=global-02-2021" rel="nofollow noreferrer">https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/?utm_source=mkto&utm_medium=email&utm_campaign=bintray-sunset&utm_content=global-02-2021

How can I migrate all artifact to Sonatype before it will be deleted.


Solution

I have solve this with multiple steps:

  • First I have written a Java program to download all the artifacts from my JCenter account.
  • Then I have write a Gradle script with the Maven plugin. This script use archiveBaseName, version and the directory of the artifacts as parameters. The script and maven plugin add all the missing things like the PGP signature.
  • Then I write a Java program that iterate over the downloaded artifacts (or a part of it) and call the Gradle script with the parameters archiveBaseName, version and the directory with the artifacts in a loop.
  • On the Sonatype GUI I deploy the uploaded files. Multiple version at once.

The follow code snippet which I have used will not work out of the box because it used internal private API. But it can help as start point. Of course you need an sonatype account and a gpg ring file. The secret properties are saved in the gradle.properties. You need also to customize the group name that the company used in all 3 files.

Downloader

package tool;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Nonnull;

import com.inet.lib.util.IOFunctions;

public class DownloadJCenter {

    // this path will be cut on save
    private static String basePath;

    private static File   root;

    public static void main( String[] args ) throws IOException {
        basePath = "/";
        URL startURL = new URL( "https://jcenter.bintray.com/com/company/" );
        root = new File( "jcenter" );
        load( startURL );
    }

    /**
     * Load the URL iterative
     * 
     * @param parent the URL to load
     * @throws IOException if any error occur
     */
    static void load( @Nonnull URL parent ) throws IOException {
        System.err.println( parent );
        InputStream input = IOFunctions.openStreamSupportingRedirect( parent, 5000 );
        String content = IOFunctions.readString( input, StandardCharsets.UTF_8 );
        List<URL> urls = extractUrls( parent, content );
        for( URL url : urls ) {
            String path = url.getPath();
            if( path.endsWith( "/" ) ) {
                load( url );
            } else {
                input = IOFunctions.openStreamSupportingRedirect( url, 5000 );
                byte[] bytes = IOFunctions.readBytes( input );
                File file = new File( root, path.substring( basePath.length() ) );
                file.getParentFile().mkdirs();
                try (FileOutputStream fos = new FileOutputStream( file )) {
                    fos.write( bytes );
                }
            }
        }
    }

    /**
     * Extract the URLs from the content of page
     * 
     * @param parent the parent URL for relative URLs
     * @param content the page content
     * @return list of found URLs
     * @throws IOException if any error occur
     */
    @Nonnull
    static List<URL> extractUrls( URL parent, @Nonnull String content ) throws IOException {
        ArrayList<URL> result = new ArrayList<>();
        int idx = 0;
        while( true ) {
            int idx1 = content.indexOf( "href=\"", idx );
            if( idx1 < 0 ) {
                break;
            }
            idx1 += 6;
            int idx2 = content.indexOf( "\"", idx1 );
            String urlStr = content.substring( idx1, idx2 );
            if( !urlStr.startsWith( ".." ) ) {
                result.add( new URL( parent, urlStr ) );
            }
            idx = idx2;
        }
        return result;
    }
}

Gradle Launcher

package tool;

import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.util.ArrayList;
import java.util.HashMap;

import com.inet.error.ErrorCode;
import com.inet.lib.util.IOFunctions;
import com.inet.shared.utils.Version;

/**
 * Deploy to the Sonatype server.
 */
public class DeploySonatype {

    private static final String gradle = "C:/Users/...../gradle-6.7.1/bin/gradle.bat";

    public static void main( String[] args ) throws IOException {
        File root = new File( "jcenter/com/company" );
        for( File file : root.listFiles() ) {
            if( file.isDirectory() ) {
                String archivesBaseName = file.getName();
                deployLibrary( archivesBaseName, file );
            }
        }
    }

    static void deployLibrary( String archivesBaseName, File libraryDir ) throws IOException {
        HashMap<Version,File> versionDirs = new HashMap<>();
        for( File file : libraryDir.listFiles() ) {
            if( file.isDirectory() ) {
                versionDirs.put( new Version( file.getName()), file );
            }
        }

        ArrayList<Version> versions = new ArrayList( versionDirs.keySet() );
        versions.sort( null );// old versions first

        for( Version version : versions ) {
            File dir = versionDirs.get( version );
            deployVersion( archivesBaseName, version, dir );
        }
    }

    static void deployVersion( String archivesBaseName, Version version, File dir ) throws IOException {
        System.err.println( archivesBaseName + " " + version + " " + dir );

        File script = IOFunctions.getFile( DeploySonatype.class.getResource( "deploy.gradle" ) );
        IOFunctions.deleteDir( new File( script.getParent(), "build" ) ); // clean from previous run

        ArrayList<String> command = new ArrayList<>();
        command.add( gradle );
        command.add( "-b" );
        command.add( "\"" + script.getPath() + "\"" );
        command.add( "--stacktrace" );
        command.add( "-ParchivesBaseName=" + archivesBaseName );
        command.add( "-Pversion=" + version );
        command.add( "-PartifactDir=" + dir.getAbsolutePath() );

        command.add( "uploadArchives" );

        System.err.println( command );

        ProcessBuilder processBuilder = new ProcessBuilder( command );
        processBuilder.redirectOutput( Redirect.INHERIT );
        processBuilder.redirectError( Redirect.INHERIT );
        processBuilder.environment().put( "JAVA_HOME", System.getProperty( "java.home" ) );
        Process start = processBuilder.start();
        try {
            int exitValue = start.waitFor();
            if( exitValue != 0 ) {
                throw new IOException( "Exit Value: " + exitValue );
            }
        } catch( InterruptedException ex ) {
            ErrorCode.throwAny( ex );
        }
    }
}

deploy.gradle

/****************************************
 * Deploy to Maven
 ****************************************/
apply plugin: 'maven'
apply plugin: 'signing'

group = 'com.company'
println archivesBaseName + "/" + version + "  -> " + artifactDir // come from Java as parameter

task copyArtifact(type: Copy) {
    from file( artifactDir )
    into file("$buildDir/artifacts" )
}

task setupArchives {
    dependsOn copyArtifact
    doLast {
        artifacts {
            fileTree( dir: file( "$buildDir/artifacts" ) ).each {
                archives file: it
                println "\t" + it
            }
        }
        signing {
            if (project.hasProperty("signing.keyId") ){
                sign configurations.archives
            }
        }
    }
}

uploadArchives {
    dependsOn setupArchives

    repositories {
        mavenDeployer {
            beforeDeployment { MavenDeployment deployment ->
                signing {
                    fileTree( dir: file( "$buildDir/artifacts" ) ).each {
                        sign it
                        println "sign: " + it
                    }
                }
            }

            if (project.hasProperty("ossrhUsername") ){
                repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
                    authentication(userName: project["ossrhUsername"], password: project["ossrhPassword"])
                }
            }
         }
    }
}


Answered By - Horcrux7
Answer Checked By - Robin (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing