如何将JCenter工件迁移到Sonatype Maven存储库?

如何将JCenter工件迁移到Sonatype Maven存储库?,maven,migration,sonatype,jcenter,Maven,Migration,Sonatype,Jcenter,JCenter Maven存储库将在几个月后关闭 如何在删除所有工件之前将其迁移到Sonatype。我已经通过多个步骤解决了这个问题: 首先,我编写了一个Java程序,从我的JCenter帐户下载所有工件 然后我用Maven插件编写了一个Gradle脚本。此脚本使用archiveBaseName、版本和工件目录作为参数。脚本和maven插件添加了所有缺少的东西,比如PGP签名 然后我编写一个Java程序,迭代下载的工件(或其中的一部分),并使用参数archiveBaseName、versio

JCenter Maven存储库将在几个月后关闭


如何在删除所有工件之前将其迁移到Sonatype。

我已经通过多个步骤解决了这个问题:

  • 首先,我编写了一个Java程序,从我的JCenter帐户下载所有工件
  • 然后我用Maven插件编写了一个Gradle脚本。此脚本使用archiveBaseName、版本和工件目录作为参数。脚本和maven插件添加了所有缺少的东西,比如PGP签名
  • 然后我编写一个Java程序,迭代下载的工件(或其中的一部分),并使用参数archiveBaseName、version调用Gradle脚本,并使用循环中的工件调用目录
  • 在sonatypegui上,我部署上传的文件。一次多个版本

我使用的下面的代码片段将无法开箱即用,因为它使用了内部私有API。但它可以作为一个起点。当然,您需要一个sonatype帐户和一个gpg环文件。机密属性保存在gradle.properties中。您还需要自定义公司在所有3个文件中使用的组名

下载器
如果你把它捆绑起来,作为一个项目放在github上,或者放在一个供人们使用的地方,你可能会得到大量的下载。很多人都会同舟共济,希望迁移发布到JCenter的工件并同步到Maven Central。@MadsHansen我已经添加了我使用的代码。我希望这对你有帮助。如果你喜欢,你可以用它做一个Github项目。
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;
    }
}
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 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"])
                }
            }
         }
    }
}