Skip to content

Commit 9386100

Browse files
committed
Enhancing runtime tools
1 parent 33b9fa3 commit 9386100

File tree

3 files changed

+230
-129
lines changed

3 files changed

+230
-129
lines changed

net.tascalate.javaflow.tools.runtime/src/main/java/org/apache/commons/javaflow/tools/runtime/ApplicationLoader.java

Lines changed: 0 additions & 90 deletions
This file was deleted.
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
/**
2+
* Original work: copyright 1999-2004 The Apache Software Foundation
3+
* (http://www.apache.org/)
4+
*
5+
* This project is based on the work licensed to the Apache Software
6+
* Foundation (ASF) under one or more contributor license agreements.
7+
* See the NOTICE file distributed with this work for additional
8+
* information regarding copyright ownership.
9+
*
10+
* Modified work: copyright 2013-2019 Valery Silaev (http://vsilaev.com)
11+
*
12+
* Licensed under the Apache License, Version 2.0 (the "License");
13+
* you may not use this file except in compliance with the License.
14+
* You may obtain a copy of the License at
15+
*
16+
* http://www.apache.org/licenses/LICENSE-2.0
17+
*
18+
* Unless required by applicable law or agreed to in writing, software
19+
* distributed under the License is distributed on an "AS IS" BASIS,
20+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21+
* See the License for the specific language governing permissions and
22+
* limitations under the License.
23+
*/
24+
package org.apache.commons.javaflow.tools.runtime;
25+
26+
import java.lang.annotation.Annotation;
27+
import java.lang.reflect.Method;
28+
import java.util.Arrays;
29+
import java.util.Collection;
30+
import java.util.Collections;
31+
32+
import org.apache.commons.javaflow.spi.ResourceTransformationFactory;
33+
34+
public final class ApplicationWeaver {
35+
private ApplicationWeaver() {}
36+
37+
public static boolean bootstrap(ResourceTransformationFactory factory, String...args) {
38+
return _trampoline(factory, null, null, null, args);
39+
}
40+
41+
public static boolean bootstrap(ResourceTransformationFactory factory,
42+
boolean isContinuablePackageRoot,
43+
String...args) {
44+
return _trampoline(factory, null, null, asPackageRoots(isContinuablePackageRoot), args);
45+
}
46+
47+
public static boolean bootstrap(ResourceTransformationFactory factory,
48+
String[] continuablePackageRoots,
49+
String...args) {
50+
return _trampoline(factory, null, null, Arrays.asList(continuablePackageRoots), args);
51+
}
52+
53+
public static boolean bootstrap(ResourceTransformationFactory factory,
54+
Collection<String> continuablePackageRoots,
55+
String...args) {
56+
return _trampoline(factory, null, null, continuablePackageRoots, args);
57+
}
58+
59+
public static boolean bootstrap(ResourceTransformationFactory factory, ClassLoader loader, String...args) {
60+
return _trampoline(factory, null, loader, null, args);
61+
}
62+
63+
public static boolean bootstrap(ResourceTransformationFactory factory,
64+
ClassLoader loader,
65+
boolean isContinuablePackageRoot,
66+
String...args) {
67+
return _trampoline(factory, null, loader, asPackageRoots(isContinuablePackageRoot), args);
68+
}
69+
70+
public static boolean bootstrap(ResourceTransformationFactory factory,
71+
ClassLoader loader,
72+
String[] continuablePackageRoots,
73+
String...args) {
74+
return _trampoline(factory, null, loader, Arrays.asList(continuablePackageRoots), args);
75+
}
76+
77+
public static boolean bootstrap(ResourceTransformationFactory factory,
78+
ClassLoader loader,
79+
Collection<String> continuablePackageRoots,
80+
String...args) {
81+
return _trampoline(factory, null, null, continuablePackageRoots, args);
82+
}
83+
84+
public static boolean bootstrap(ResourceTransformationFactory factory, Class<?> source, String...args) {
85+
return _trampoline(factory, source, source.getClassLoader(), null, args);
86+
}
87+
88+
public static boolean bootstrap(ResourceTransformationFactory factory,
89+
Class<?> source,
90+
boolean isContinuablePackageRoot,
91+
String...args) {
92+
return _trampoline(factory, source, source.getClassLoader(), asPackageRoots(isContinuablePackageRoot), args);
93+
}
94+
95+
96+
public static boolean bootstrap(ResourceTransformationFactory factory,
97+
Class<?> source,
98+
String[] continuablePackageRoots,
99+
String...args) {
100+
return _trampoline(factory, source, source.getClassLoader(), Arrays.asList(continuablePackageRoots), args);
101+
}
102+
103+
104+
public static boolean bootstrap(ResourceTransformationFactory factory,
105+
Class<?> source,
106+
Collection<String> continuablePackageRoots,
107+
String...args) {
108+
return _trampoline(factory, source, source.getClassLoader(), continuablePackageRoots, args);
109+
}
110+
111+
private static boolean _trampoline(ResourceTransformationFactory factory,
112+
Class<?> originalClass,
113+
ClassLoader originalLoader,
114+
Collection<String> continuablePackageRoots,
115+
String...args) {
116+
if (null == originalLoader) {
117+
if (null != originalClass) {
118+
originalLoader = originalClass.getClassLoader();
119+
} else {
120+
originalLoader = CURRENT_INITIATOR.get();
121+
if (null == originalLoader) {
122+
originalLoader = Thread.currentThread().getContextClassLoader();
123+
}
124+
if (null == originalLoader) {
125+
originalLoader = ClassLoader.getSystemClassLoader();
126+
}
127+
}
128+
}
129+
130+
if (null == originalClass) {
131+
StackTraceElement ste = new Exception().getStackTrace()[2];
132+
try {
133+
originalClass = originalLoader.loadClass(ste.getClassName());
134+
} catch (ClassNotFoundException ex) {
135+
throw new RuntimeException(
136+
"Unable to load requesting class " + ste.getClassName() + " using class loader " + originalLoader,
137+
ex
138+
);
139+
}
140+
}
141+
142+
if ((originalLoader instanceof ContinuableClassLoader) &&
143+
isProcessed(originalClass)) {
144+
// Correct loader and annotations applied
145+
return false;
146+
}
147+
148+
try {
149+
ContinuableClassLoader.Builder builder = new ContinuableClassLoader.Builder(factory);
150+
if (null == continuablePackageRoots || continuablePackageRoots.isEmpty()) {
151+
builder.parentFirst(false);
152+
} else {
153+
for (String s : continuablePackageRoots) {
154+
if ("*".equals(s)) {
155+
s = originalClass.getPackage().getName();
156+
}
157+
builder.addLoaderPackageRoot(s);
158+
}
159+
}
160+
ContinuableClassLoader loader = builder.parent(originalLoader).create();
161+
162+
ClassLoader prev = CURRENT_INITIATOR.get();
163+
CURRENT_INITIATOR.set(loader);
164+
try {
165+
run(loader, originalClass.getName(), "main", args);
166+
} finally {
167+
if (null == prev) {
168+
CURRENT_INITIATOR.remove();
169+
} else {
170+
CURRENT_INITIATOR.set(prev);
171+
}
172+
}
173+
}
174+
catch (RuntimeException ex) {
175+
throw ex;
176+
}
177+
catch (Exception ex) {
178+
throw new RuntimeException(ex);
179+
}
180+
return true;
181+
}
182+
183+
private static void run(ContinuableClassLoader classLoader, String className, String method, String... args) throws Exception {
184+
Class<?> mainClass = classLoader.forceLoadClass(className);
185+
if (!isProcessed(mainClass)) {
186+
throw new IllegalStateException("Class " + className + " has no continuable methods");
187+
}
188+
Method mainMethod = mainClass.getMethod(method, String[].class);
189+
mainMethod.invoke(null, new Object[] {args});
190+
}
191+
192+
private static boolean isProcessed(Class<?> clazz) {
193+
for (Annotation a : clazz.getAnnotations()) {
194+
if ("org.apache.commons.javaflow.core.Skip".equals(a.annotationType().getName())) {
195+
return true;
196+
}
197+
}
198+
return false;
199+
}
200+
201+
private static Collection<String> asPackageRoots(boolean isContinuablePackageRoot) {
202+
return isContinuablePackageRoot ? Collections.singleton("*") : null;
203+
}
204+
205+
private static final ThreadLocal<ClassLoader> CURRENT_INITIATOR = new ThreadLocal<ClassLoader>();
206+
}

net.tascalate.javaflow.tools.runtime/src/main/java/org/apache/commons/javaflow/tools/runtime/ContinuableClassLoader.java

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import java.io.InputStream;
2828
import java.lang.reflect.InvocationTargetException;
2929
import java.lang.reflect.Method;
30-
import java.net.URL;
3130
import java.net.URLClassLoader;
3231
import java.security.AccessControlContext;
3332
import java.security.AccessController;
@@ -349,16 +348,6 @@ private boolean isParentFirst(String resourceName) {
349348
// if this class belongs to a package which has been
350349
// designated to use a specific loader first
351350
// (this one or the parent one)
352-
353-
if (resourceName.startsWith("org.apache.commons.javaflow.tools.runtime.") ||
354-
resourceName.startsWith("org.apache.commons.javaflow.spi.")) {
355-
return true;
356-
}
357-
358-
// if (resourceName.startsWith("org.apache.commons.javaflow.") && !resourceName.startsWith("org.apache.commons.javaflow.examples.")) {
359-
// return true;
360-
// }
361-
362351
boolean useParentFirst = parentFirst;
363352

364353
for (String packageName : systemPackages) {
@@ -374,6 +363,15 @@ private boolean isParentFirst(String resourceName) {
374363
break;
375364
}
376365
}
366+
367+
if (!useParentFirst) {
368+
for (String packageName : OWN_PACKAGES) {
369+
if (resourceName.startsWith(packageName)) {
370+
useParentFirst = true;
371+
break;
372+
}
373+
}
374+
}
377375

378376
return useParentFirst;
379377
}
@@ -592,34 +590,6 @@ public Class<?> findClass(String name) throws ClassNotFoundException {
592590
}
593591
}
594592
}
595-
596-
/**
597-
* Finds the resource with the given name. A resource is some data (images,
598-
* audio, text, etc) that can be accessed by class code in a way that is
599-
* independent of the location of the code.
600-
*
601-
* @param name
602-
* The name of the resource for which a stream is required. Must
603-
* not be <code>null</code>.
604-
* @return a URL for reading the resource, or <code>null</code> if the
605-
* resource could not be found or the caller doesn't have adequate
606-
* privileges to get the resource.
607-
*/
608-
@Override
609-
public URL getResource(String name) {
610-
// we need to search the components of the path to see if
611-
// we can find the class we want.
612-
if (isParentFirst(name)) {
613-
return super.getResource(name);
614-
}
615-
616-
// try this class loader first, then parent
617-
URL url = findResource(name);
618-
if (url == null) {
619-
url = getParent().getResource(name);
620-
}
621-
return url;
622-
}
623593

624594
private Object safeGetClassLoadingLock(String name) {
625595
if (null == GET_CLASS_LOADING_LOCK) {
@@ -701,4 +671,19 @@ private static List<String> dotEndingPackageNames(List<String> source) {
701671
}
702672
return result;
703673
}
674+
675+
private static String[] OWN_PACKAGES;
676+
static {
677+
Class<?>[] ownClasses = {
678+
ContinuableClassLoader.class,
679+
ResourceTransformer.class,
680+
Logger.class
681+
};
682+
683+
OWN_PACKAGES = new String[ownClasses.length];
684+
int i = 0;
685+
for (Class<?> cls : ownClasses) {
686+
OWN_PACKAGES[i++] = cls.getPackage().getName() + '.';
687+
}
688+
}
704689
}

0 commit comments

Comments
 (0)