1
1
/*
2
- * Copyright 2012-2014 the original author or authors.
2
+ * Copyright 2012-2016 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
18
18
19
19
import java .io .File ;
20
20
import java .io .IOException ;
21
+ import java .io .InputStream ;
21
22
import java .net .JarURLConnection ;
22
23
import java .net .URL ;
23
24
import java .net .URLConnection ;
24
25
import java .security .CodeSource ;
25
26
import java .security .ProtectionDomain ;
27
+ import java .util .Enumeration ;
28
+ import java .util .jar .JarFile ;
29
+ import java .util .jar .Manifest ;
26
30
31
+ import org .springframework .util .ClassUtils ;
27
32
import org .springframework .util .StringUtils ;
28
33
29
34
/**
@@ -51,17 +56,51 @@ public ApplicationHome() {
51
56
* @param sourceClass the source class or {@code null}
52
57
*/
53
58
public ApplicationHome (Class <?> sourceClass ) {
54
- this .source = findSource (sourceClass == null ? getClass () : sourceClass );
59
+ this .source = findSource (sourceClass == null ? getStartClass () : sourceClass );
55
60
this .dir = findHomeDir (this .source );
56
61
}
57
62
63
+ private Class <?> getStartClass () {
64
+ try {
65
+ ClassLoader classLoader = getClass ().getClassLoader ();
66
+ return getStartClass (classLoader .getResources ("META-INF/MANIFEST.MF" ));
67
+ }
68
+ catch (Exception ex ) {
69
+ return null ;
70
+ }
71
+ }
72
+
73
+ private Class <?> getStartClass (Enumeration <URL > manifestResources ) {
74
+ while (manifestResources .hasMoreElements ()) {
75
+ try {
76
+ InputStream inputStream = manifestResources .nextElement ().openStream ();
77
+ try {
78
+ Manifest manifest = new Manifest (inputStream );
79
+ String startClass = manifest .getMainAttributes ()
80
+ .getValue ("Start-Class" );
81
+ if (startClass != null ) {
82
+ return ClassUtils .forName (startClass ,
83
+ getClass ().getClassLoader ());
84
+ }
85
+ }
86
+ finally {
87
+ inputStream .close ();
88
+ }
89
+ }
90
+ catch (Exception ex ) {
91
+ }
92
+ }
93
+ return null ;
94
+ }
95
+
58
96
private File findSource (Class <?> sourceClass ) {
59
97
try {
60
- ProtectionDomain protectionDomain = sourceClass .getProtectionDomain ();
61
- CodeSource codeSource = protectionDomain .getCodeSource ();
98
+ ProtectionDomain domain = (sourceClass == null ? null
99
+ : sourceClass .getProtectionDomain ());
100
+ CodeSource codeSource = (domain == null ? null : domain .getCodeSource ());
62
101
URL location = (codeSource == null ? null : codeSource .getLocation ());
63
102
File source = (location == null ? null : findSource (location ));
64
- if (source != null && source .exists ()) {
103
+ if (source != null && source .exists () && ! isUnitTest () ) {
65
104
return source .getAbsoluteFile ();
66
105
}
67
106
return null ;
@@ -71,14 +110,36 @@ private File findSource(Class<?> sourceClass) {
71
110
}
72
111
}
73
112
113
+ private boolean isUnitTest () {
114
+ try {
115
+ for (StackTraceElement element : Thread .currentThread ().getStackTrace ()) {
116
+ if (element .getClassName ().startsWith ("org.junit." )) {
117
+ return true ;
118
+ }
119
+ }
120
+ }
121
+ catch (Exception ex ) {
122
+ }
123
+ return false ;
124
+ }
125
+
74
126
private File findSource (URL location ) throws IOException {
75
127
URLConnection connection = location .openConnection ();
76
128
if (connection instanceof JarURLConnection ) {
77
- return new File (((JarURLConnection ) connection ).getJarFile (). getName ());
129
+ return getRootJarFile (((JarURLConnection ) connection ).getJarFile ());
78
130
}
79
131
return new File (location .getPath ());
80
132
}
81
133
134
+ private File getRootJarFile (JarFile jarFile ) {
135
+ String name = jarFile .getName ();
136
+ int separator = name .indexOf ("!/" );
137
+ if (separator > 0 ) {
138
+ name = name .substring (0 , separator );
139
+ }
140
+ return new File (name );
141
+ }
142
+
82
143
private File findHomeDir (File source ) {
83
144
File homeDir = source ;
84
145
homeDir = (homeDir == null ? findDefaultHomeDir () : homeDir );
0 commit comments