package com.github.igorsuhorukov.url;

import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.Attributes;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;

public class UrlBootstrapLoader {

    private static final String MAIN_CLASS = "Main-Class";
    private static final String MANIFEST_MF = "META-INF/MANIFEST.MF";

    public static void main(String[] args) throws Exception{
        String artifactUrl = System.getProperty("artifactUrl");
        if(artifactUrl==null || artifactUrl.isEmpty()){
            throw new IllegalArgumentException("System property artifactUrl is empty");
        }
        URL artifactJavaUrl = new URL(artifactUrl);
        try (URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{artifactJavaUrl})){
            String mainClass = getMainClassFromManifest(artifactUrl, artifactJavaUrl);
            ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader(urlClassLoader);
            try {
                invokeMainMethod(urlClassLoader, mainClass, args);
            } finally {
                Thread.currentThread().setContextClassLoader(contextClassLoader);
            }
        }
    }

    private static String getMainClassFromManifest(String artifactUrl, URL artifactJavaUrl) throws IOException {
        try (JarInputStream manifestStream = new JarInputStream(artifactJavaUrl.openStream())){
            Manifest manifest = manifestStream.getManifest();
            if(manifest==null){
                throw new IllegalArgumentException(MANIFEST_MF +" not found in " + artifactUrl);
            }
            Attributes mainAttributes = manifest.getMainAttributes();
            if(mainAttributes==null){
                throw new IllegalArgumentException(MANIFEST_MF+" is empty");
            }
            String mainClass = mainAttributes.getValue(MAIN_CLASS);
            if(mainClass==null || mainClass.isEmpty()){
                throw new IllegalArgumentException(MAIN_CLASS+" attribute not found in "+MANIFEST_MF);
            }
            return mainClass;
        }
    }

    private static void invokeMainMethod(URLClassLoader urlClassLoader, String mainClassName, String[] args){
        try {
            Class<?> mainClass = urlClassLoader.loadClass(mainClassName);
            Method mainMethod = mainClass.getDeclaredMethod("main", new Class[]{String[].class});
            mainMethod.invoke((Object)null, new Object[]{args});
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }
}

@@ -43,27 +43,96 @@
 ort 
-java.io.IOException
+org.codehaus.plexus.util.IOUtil;%0A%0Aimport java.io.IOException;%0Aimport java.io.InputStream
 ;%0Aim
@@ -543,16 +543,16 @@
 eption%7B%0A
-
         
@@ -603,24 +603,446 @@
 ifactUrl%22);%0A
+        String artifactUrlReference = System.getProperty(%22artifactUrlReference%22);%0A        if(artifactUrlReference!=null && !artifactUrlReference.isEmpty())%7B%0A            if(artifactUrl!=null && !artifactUrl.isEmpty())%7B%0A                throw new IllegalArgumentException(%22use either artifactUrl or artifactUrlReference system property%22);%0A            %7D%0A            artifactUrl = getReference(artifactUrlReference);%0A        %7D%0A
         if(a
@@ -3165,11 +3165,514 @@
  %7D%0A    %7D
+%0A%0A    private static String getReference(String artifactUrlReference) throws IOException %7B%0A        URL referenceUrl = new URL(artifactUrlReference);%0A        InputStream referenceUrlStream = referenceUrl.openStream();%0A        String reference = IOUtil.toString(referenceUrlStream);%0A        if(reference==null %7C%7C reference.isEmpty() %7C%7C reference.contains(%22%5Cn%22))%7B%0A            throw new IllegalArgumentException(%22artifactUrlReference resource should be non empty%22);%0A        %7D%0A        return reference;%0A    %7D
 %0A%7D%0A

use two mode artifact resolve mode artifactUrl, artifactUrlReference