diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/BizModel.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/BizModel.java index d157a7b45..b883440bd 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/BizModel.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/BizModel.java @@ -323,6 +323,16 @@ public void start(String[] args, Map envs) throws Throwable { private void doStart(String[] args, Map envs) throws Throwable { AssertUtils.isTrue(bizState == BizState.RESOLVED, "BizState must be RESOLVED"); + + // 支持运行时根据环境变量动态设置模块的启动类 + if (envs != null){ + String mainClassFromEnv = envs.get(Constants.BIZ_MAIN_CLASS); + if (mainClassFromEnv != null){ + mainClass = mainClassFromEnv; + ArkLoggerFactory.getDefaultLogger().info("Ark biz {} will start with main class {} from envs", getIdentity(), mainClassFromEnv); + } + } + if (mainClass == null) { throw new ArkRuntimeException(String.format("biz: %s has no main method", getBizName())); } diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/api/ArkClientTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/api/ArkClientTest.java index cbfb255f6..6f71c5a97 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/api/ArkClientTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/api/ArkClientTest.java @@ -16,10 +16,17 @@ */ package com.alipay.sofa.ark.container.service.api; +import com.alipay.sofa.ark.api.ArkClient; import com.alipay.sofa.ark.api.ArkConfigs; import com.alipay.sofa.ark.api.ClientResponse; +import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.container.BaseTest; import com.alipay.sofa.ark.container.service.biz.BizManagerServiceImpl; +import com.alipay.sofa.ark.loader.JarBizArchive; +import com.alipay.sofa.ark.loader.archive.JarFileArchive; +import com.alipay.sofa.ark.loader.jar.JarFile; +import com.alipay.sofa.ark.spi.archive.BizArchive; +import com.alipay.sofa.ark.spi.constant.Constants; import com.alipay.sofa.ark.spi.event.ArkEvent; import com.alipay.sofa.ark.spi.model.Biz; import com.alipay.sofa.ark.spi.model.BizInfo; @@ -33,9 +40,12 @@ import org.junit.Test; import java.io.File; +import java.io.InputStream; import java.net.URL; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; import static com.alipay.sofa.ark.api.ArkClient.checkBiz; import static com.alipay.sofa.ark.api.ArkClient.checkOperation; @@ -93,6 +103,8 @@ public class ArkClientTest extends BaseTest { private URL bizUrl3; // bizName=biz-demo, bizVersion=4.0.0 private URL bizUrl4; + // bizName=biz-demo, bizVersion=5.0.0 + private URL bizUrl5; @Before public void before() { @@ -105,6 +117,8 @@ public void before() { bizUrl3 = this.getClass().getClassLoader().getResource("sample-ark-3.0.0-ark-biz.jar"); // bizName=biz-demo, bizVersion=4.0.0 bizUrl4 = this.getClass().getClassLoader().getResource("sample-ark-4.0.0-ark-biz.jar"); + // bizName=biz-demo, bizVersion=5.0.0 + bizUrl5 = this.getClass().getClassLoader().getResource("sample-ark-5.0.0-ark-biz.jar"); } @Test @@ -305,6 +319,35 @@ public void testInstallOperation() throws Throwable { assertEquals(SUCCESS, response.getCode()); } + @Test + public void testInstallOperationWithDynamicMainClass() throws Throwable { + + // 传 env 参数,使用动态的模块启动类 org.example.Main2 + BizOperation bizOperation = new BizOperation(); + bizOperation.setOperationType(INSTALL); + bizOperation.getParameters().put(CONFIG_BIZ_URL, bizUrl5.toString()); + bizOperation.setBizName("biz-demo"); + bizOperation.setBizVersion("5.0.0"); + + Map envs = Collections.singletonMap(Constants.BIZ_MAIN_CLASS, "org.example.Main2"); + + ClientResponse response2 = installOperation(bizOperation, new String[] {}, envs); + assertEquals(SUCCESS, response2.getCode()); + assertEquals("org.example.Main2", (new ArrayList<>(response2.getBizInfos())).get(0).getMainClass()); + + // 实际模块jar包里配置启动类是 org.example.Main1 + URL url = new URL(bizOperation.getParameters().get(Constants.CONFIG_BIZ_URL)); + File file = ArkClient.createBizSaveFile(bizOperation.getBizName(), bizOperation.getBizVersion()); + try (InputStream inputStream = url.openStream()) { + FileUtils.copyInputStreamToFile(inputStream, file); + } + JarFile bizFile = new JarFile(file); + JarFileArchive jarFileArchive = new JarFileArchive(bizFile); + BizArchive bizArchive = new JarBizArchive(jarFileArchive); + assertEquals("org.example.Main1", bizArchive.getManifest().getMainAttributes().getValue(Constants.MAIN_CLASS_ATTRIBUTE)); + assertEquals("org.example.Main1", bizArchive.getManifest().getMainAttributes().getValue(Constants.START_CLASS_ATTRIBUTE)); + } + @Test public void testInstallBizFailed() throws Throwable { File bizFile = createBizSaveFile("biz-install-failed-demo", "1.0.0"); diff --git a/sofa-ark-parent/core-impl/container/src/test/resources/sample-ark-5.0.0-ark-biz.jar b/sofa-ark-parent/core-impl/container/src/test/resources/sample-ark-5.0.0-ark-biz.jar new file mode 100644 index 000000000..2b6653a32 Binary files /dev/null and b/sofa-ark-parent/core-impl/container/src/test/resources/sample-ark-5.0.0-ark-biz.jar differ diff --git a/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/constant/Constants.java b/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/constant/Constants.java index bbacca512..f194faa5b 100644 --- a/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/constant/Constants.java +++ b/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/constant/Constants.java @@ -203,6 +203,7 @@ public class Constants { public final static String EMBED_STATIC_BIZ_IN_RESOURCE_ENABLE = "sofa.ark.embed.static.biz.in.resource.enable"; public final static String ACTIVATE_NEW_MODULE = "activate.new.module"; + public final static String BIZ_MAIN_CLASS = "sofa.ark.biz.main.class"; /** * uninstall the biz if it starts up failed