[
https://issues.apache.org/jira/browse/SCB-725?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16539680#comment-16539680
]
ASF GitHub Bot commented on SCB-725:
------------------------------------
wujimin closed pull request #799: [SCB-725] support get main class package when
run with "java -jar xxx.jar
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/799
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JvmUtils.java
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JvmUtils.java
index 48a9baab4..bb02d725e 100644
---
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JvmUtils.java
+++
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JvmUtils.java
@@ -16,6 +16,12 @@
*/
package org.apache.servicecomb.foundation.common.utils;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,21 +42,50 @@ private JvmUtils() {
* @return main class or null, never throw exception
*/
public static Class<?> findMainClass() {
+ // 1.run with java -cp ......
+ // command is main class and args
+ // 2.run with java -jar ......
+ // command is jar file name and args
String command = System.getProperty(SUN_JAVA_COMMAND);
if (command == null || command.isEmpty()) {
return null;
}
- // command is main class and args
- String mainClass = command.trim().split(" ")[0];
+ String mainClassOrJar = command.trim().split(" ")[0];
+ String mainClass = readFromJar(mainClassOrJar);
+ if (mainClass == null || mainClass.isEmpty()) {
+ return null;
+ }
+
try {
- return Class.forName(mainClass);
+ Class<?> cls = Class.forName(mainClass);
+ LOGGER.info("Found main class \"{}\".", mainClass);
+ return cls;
} catch (Throwable e) {
LOGGER.warn("\"{}\" is not a valid class.", mainClass, e);
return null;
}
}
+ private static String readFromJar(String mainClassOrJar) {
+ if (!mainClassOrJar.endsWith(".jar")) {
+ return mainClassOrJar;
+ }
+
+ String manifestUri = "jar:file:/" + new
File(mainClassOrJar).getAbsolutePath() + "!/" + JarFile.MANIFEST_NAME;
+
+ try {
+ URL url = new URL(manifestUri);
+ try (InputStream inputStream = url.openStream()) {
+ Manifest manifest = new Manifest(inputStream);
+ return manifest.getMainAttributes().getValue("Main-Class");
+ }
+ } catch (Throwable e) {
+ LOGGER.warn("Failed to read Main-Class from \"{}\".", manifestUri, e);
+ return null;
+ }
+ }
+
/**
* find a property class loader to avoid null
*/
diff --git
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestJvmUtils.java
b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestJvmUtils.java
index d16792f3e..257c8f407 100644
---
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestJvmUtils.java
+++
b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestJvmUtils.java
@@ -16,12 +16,24 @@
*/
package org.apache.servicecomb.foundation.common.utils;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.jar.JarFile;
+
import org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({JvmUtils.class})
public class TestJvmUtils {
static String orgCmd = System.getProperty(JvmUtils.SUN_JAVA_COMMAND);
@@ -63,9 +75,63 @@ public void findMainClass_invalid() {
}
@Test
- public void findMainClass_normal() {
+ public void findMainClass_class_normal() {
System.setProperty(JvmUtils.SUN_JAVA_COMMAND, TestJvmUtils.class.getName()
+ " arg");
Assert.assertEquals(TestJvmUtils.class, JvmUtils.findMainClass());
}
+
+ @Test
+ public void findMainClass_jar_normal() throws Exception {
+ String content = String.format("Manifest-Version: 1.0\nMain-Class: %s\n",
TestJvmUtils.class.getName());
+ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+
+ URL url = PowerMockito.mock(URL.class);
+
+ String command = "a.jar";
+ String manifestUri = "jar:file:/" + new File(command).getAbsolutePath() +
"!/" + JarFile.MANIFEST_NAME;
+
+ PowerMockito.whenNew(URL.class).withParameterTypes(String.class)
+ .withArguments(manifestUri).thenReturn(url);
+ PowerMockito.when(url.openStream()).thenReturn(inputStream);
+
+ System.setProperty(JvmUtils.SUN_JAVA_COMMAND, command + " arg");
+
+ Assert.assertEquals(TestJvmUtils.class, JvmUtils.findMainClass());
+ }
+
+ @Test
+ public void findMainClass_jar_null() throws Exception {
+ String content = "Manifest-Version: 1.0\n";
+ InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+
+ URL url = PowerMockito.mock(URL.class);
+
+ String command = "a.jar";
+ String manifestUri = "jar:file:/" + new File(command).getAbsolutePath() +
"!/" + JarFile.MANIFEST_NAME;
+
+ PowerMockito.whenNew(URL.class).withParameterTypes(String.class)
+ .withArguments(manifestUri).thenReturn(url);
+ PowerMockito.when(url.openStream()).thenReturn(inputStream);
+
+ System.setProperty(JvmUtils.SUN_JAVA_COMMAND, command + " arg");
+
+ Assert.assertNull(JvmUtils.findMainClass());
+ }
+
+ @Test
+ public void findMainClass_jar_readFailed() throws Exception {
+ URL url = PowerMockito.mock(URL.class);
+
+ String command = "a.jar";
+ String manifestUri = "jar:file:/" + new File(command).getAbsolutePath() +
"!/" + JarFile.MANIFEST_NAME;
+
+ PowerMockito.whenNew(URL.class).withParameterTypes(String.class)
+ .withArguments(manifestUri).thenReturn(url);
+ PowerMockito.when(url.openStream()).thenThrow(new Error());
+
+ System.setProperty(JvmUtils.SUN_JAVA_COMMAND, command + " arg");
+
+ Assert.assertNull(JvmUtils.findMainClass());
+ }
}
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
> support get main class package when run with "java -jar xxx.jar"
> ----------------------------------------------------------------
>
> Key: SCB-725
> URL: https://issues.apache.org/jira/browse/SCB-725
> Project: Apache ServiceComb
> Issue Type: Task
> Components: Java-Chassis
> Reporter: wujimin
> Assignee: wujimin
> Priority: Major
>
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)