Skip to content

Commit cd0f7d5

Browse files
Use a single classloader for java 11 if environment variable is set
1 parent 7b6c1f3 commit cd0f7d5

File tree

6 files changed

+76
-2
lines changed

6 files changed

+76
-2
lines changed

endtoendtests/Azure.Functions.Java.Tests.E2E/Azure.Functions.Java.Tests.E2E/HttpEndToEndTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,19 @@ public async Task HttpTriggerJavaClassLoader()
5959
Assert.True(await Utilities.InvokeHttpTrigger("HttpTriggerJavaClassLoader", "?&name=Test", HttpStatusCode.InternalServerError, ""));
6060
}
6161
}
62+
63+
[Fact]
64+
public async void HttpTriggerJavaStatic()
65+
{
66+
String value = Environment.GetEnvironmentVariable("FUNCTIONS_WORKER_JAVA_V3_SINGLE_CLASSLOADER");
67+
String java_home = Environment.GetEnvironmentVariable("JAVA_HOME");
68+
if (java_home.Contains("1.8") || (value != null && (value.ToLower().Equals("true") || value.ToLower().Equals("1"))))
69+
{
70+
await HttpTriggerTests("HttpTriggerJavaStatic1", "", HttpStatusCode.OK, "1");
71+
await HttpTriggerTests("HttpTriggerJavaStatic2", "", HttpStatusCode.OK, "2");
72+
await HttpTriggerTests("HttpTriggerJavaStatic1", "", HttpStatusCode.OK, "3");
73+
await HttpTriggerTests("HttpTriggerJavaStatic2", "", HttpStatusCode.OK, "4");
74+
}
75+
}
6276
}
6377
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
{
22
"profiles": {
33
"Azure.Functions.Java.Tests.E2E": {
4-
"commandName": "Project"
4+
"commandName": "Project",
5+
"environmentVariables": {
6+
"FUNCTIONS_WORKER_JAVA_V3_SINGLE_CLASSLOADER": "1"
7+
}
58
}
69
}
710
}

endtoendtests/src/main/java/com/microsoft/azure/functions/endtoend/HttpTriggerTests.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,4 +237,32 @@ public HttpResponseMessage runRetryExponentialBackoffRetryFail(
237237
return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
238238
}
239239
}
240+
241+
private static int flag = 0;
242+
243+
@FunctionName("HttpTriggerJavaStatic1")
244+
public HttpResponseMessage HttpTriggerJavaStatic1(
245+
@HttpTrigger(
246+
name = "req",
247+
methods = {HttpMethod.GET, HttpMethod.POST},
248+
authLevel = AuthorizationLevel.ANONYMOUS)
249+
HttpRequestMessage<Optional<String>> request,
250+
final ExecutionContext context) {
251+
context.getLogger().info("Java HTTP trigger - static processed a request.");
252+
flag++;
253+
return request.createResponseBuilder(HttpStatus.OK).body(String.valueOf(flag)).build();
254+
}
255+
256+
@FunctionName("HttpTriggerJavaStatic2")
257+
public HttpResponseMessage HttpTriggerJavaStatic2(
258+
@HttpTrigger(
259+
name = "req",
260+
methods = {HttpMethod.GET, HttpMethod.POST},
261+
authLevel = AuthorizationLevel.ANONYMOUS)
262+
HttpRequestMessage<Optional<String>> request,
263+
final ExecutionContext context) {
264+
context.getLogger().info("Java HTTP trigger - static processed a request.");
265+
flag++;
266+
return request.createResponseBuilder(HttpStatus.OK).body(String.valueOf(flag)).build();
267+
}
240268
}

src/main/java/com/microsoft/azure/functions/worker/Constants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ private Constants(){}
88
public final static String TRIGGER_METADATA_DOLLAR_REQUEST_KEY = "$request";
99
public final static String FUNCTIONS_WORKER_DIRECTORY = "FUNCTIONS_WORKER_DIRECTORY";
1010
public final static String FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS = "FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS";
11+
public final static String FUNCTIONS_WORKER_JAVA_V3_SINGLE_CLASSLOADER = "FUNCTIONS_WORKER_JAVA_V3_SINGLE_CLASSLOADER";
1112
}

src/main/java/com/microsoft/azure/functions/worker/Helper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ public static boolean isLoadAppLibsFirst() {
66
String javaReverseLibLoading = System.getenv(Constants.FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS);
77
return Util.isTrue(javaReverseLibLoading);
88
}
9+
public static boolean isCustomURLClassLoader() {
10+
String customURLClassLoader = System.getenv(Constants.FUNCTIONS_WORKER_JAVA_V3_SINGLE_CLASSLOADER);
11+
return Util.isTrue(customURLClassLoader);
12+
}
913
}

src/main/java/com/microsoft/azure/functions/worker/reflect/EnhancedClassLoaderProvider.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,31 @@ public EnhancedClassLoaderProvider() {
1919
*/
2020
@Override
2121
public ClassLoader createClassLoader() {
22+
if(Helper.isCustomURLClassLoader()) {
23+
return getURLClassLoaderInstance();
24+
}else {
25+
return createURLClassLoaderInstance();
26+
}
27+
}
28+
29+
/**
30+
* Create and return a singleton URL classloader
31+
* @return instance of URLClassLoader
32+
*/
33+
private URLClassLoader getURLClassLoaderInstance() {
34+
if (classLoaderInstance == null) {
35+
synchronized (lock) {
36+
if (classLoaderInstance == null) {
37+
classLoaderInstance = createURLClassLoaderInstance();
38+
}
39+
}
40+
}
41+
return classLoaderInstance;
42+
}
43+
44+
private URLClassLoader createURLClassLoaderInstance(){
2245
URL[] urlsForClassLoader = new URL[urls.size()];
2346
urls.toArray(urlsForClassLoader);
24-
2547
URLClassLoader classLoader = new URLClassLoader(urlsForClassLoader);
2648
loadDrivers(classLoader);
2749
return classLoader;
@@ -73,4 +95,6 @@ public void addUrl(URL url) throws IOException {
7395
urls.add(url);
7496
}
7597
private final Set<URL> urls;
98+
private final Object lock = new Object();
99+
private static volatile URLClassLoader classLoaderInstance;
76100
}

0 commit comments

Comments
 (0)