mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
Merge pull request #89 from dscho/get-resources
Support ClassLoader#getResources with multiple class path elements
This commit is contained in:
commit
790fcff73e
@ -17,6 +17,7 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
public class SystemClassLoader extends ClassLoader {
|
public class SystemClassLoader extends ClassLoader {
|
||||||
private native VMClass findVMClass(String name)
|
private native VMClass findVMClass(String name)
|
||||||
@ -106,20 +107,51 @@ public class SystemClassLoader extends ClassLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
URL url = findResource(name);
|
Enumeration<URL> urls2 = findResources(name);
|
||||||
if (url != null) {
|
while (urls2.hasMoreElements()) {
|
||||||
urls.add(url);
|
urls.add(urls2.nextElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Collections.enumeration(urls);
|
return Collections.enumeration(urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ResourceEnumeration implements Enumeration<URL> {
|
||||||
|
private long[] finderElementPtrPtr;
|
||||||
|
private String name, urlPrefix;
|
||||||
|
|
||||||
|
public ResourceEnumeration(String name) {
|
||||||
|
this.name = name;
|
||||||
|
finderElementPtrPtr = new long[1];
|
||||||
|
urlPrefix = nextResourceURLPrefix();
|
||||||
|
}
|
||||||
|
|
||||||
|
private native String nextResourceURLPrefix(SystemClassLoader loader,
|
||||||
|
String name, long[] finderElementPtrPtr);
|
||||||
|
|
||||||
|
private String nextResourceURLPrefix() {
|
||||||
|
return nextResourceURLPrefix(SystemClassLoader.this, name,
|
||||||
|
finderElementPtrPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMoreElements() {
|
||||||
|
return urlPrefix != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL nextElement() {
|
||||||
|
if (urlPrefix == null) throw new NoSuchElementException();
|
||||||
|
URL result;
|
||||||
|
try {
|
||||||
|
result = new URL(urlPrefix + name);
|
||||||
|
} catch (MalformedURLException ignored) {
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
if (finderElementPtrPtr[0] == 0l) urlPrefix = null;
|
||||||
|
else urlPrefix = nextResourceURLPrefix();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected Enumeration<URL> findResources(String name) {
|
protected Enumeration<URL> findResources(String name) {
|
||||||
Collection<URL> urls = new ArrayList(1);
|
return new ResourceEnumeration(name);
|
||||||
URL url = findResource(name);
|
|
||||||
if (url != null) {
|
|
||||||
urls.add(url);
|
|
||||||
}
|
|
||||||
return Collections.enumeration(urls);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class Handler extends URLStreamHandler {
|
|||||||
("protocol " + file.getProtocol() + " not yet supported");
|
("protocol " + file.getProtocol() + " not yet supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
url.set("jar", "", -1, s, null);
|
url.set("jar", null, -1, s, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyJarURLConnection extends JarURLConnection {
|
private static class MyJarURLConnection extends JarURLConnection {
|
||||||
|
11
makefile
11
makefile
@ -1487,13 +1487,20 @@ ifeq ($(continuations),true)
|
|||||||
$(build)/compile-x86-asm.o: $(src)/continuations-x86.$(asm-format)
|
$(build)/compile-x86-asm.o: $(src)/continuations-x86.$(asm-format)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(build)/run-tests.sh: $(test-classes) makefile
|
$(build)/run-tests.sh: $(test-classes) makefile $(build)/extra-dir/multi-classpath-test.txt $(build)/test/multi-classpath-test.txt
|
||||||
echo 'cd $$(dirname $$0)' > $(@)
|
echo 'cd $$(dirname $$0)' > $(@)
|
||||||
echo "sh ./test.sh 2>/dev/null \\" >> $(@)
|
echo "sh ./test.sh 2>/dev/null \\" >> $(@)
|
||||||
echo "$(shell echo $(library-path) | sed 's|$(build)|\.|g') ./$(name)-unittest${exe-suffix} ./$(notdir $(test-executable)) $(mode) \"-Djava.library.path=. -cp test\" \\" >> $(@)
|
echo "$(shell echo $(library-path) | sed 's|$(build)|\.|g') ./$(name)-unittest${exe-suffix} ./$(notdir $(test-executable)) $(mode) \"-Djava.library.path=. -cp test:extra-dir\" \\" >> $(@)
|
||||||
echo "$(call class-names,$(test-build),$(filter-out $(test-support-classes), $(test-classes))) \\" >> $(@)
|
echo "$(call class-names,$(test-build),$(filter-out $(test-support-classes), $(test-classes))) \\" >> $(@)
|
||||||
echo "$(continuation-tests) $(tail-tests)" >> $(@)
|
echo "$(continuation-tests) $(tail-tests)" >> $(@)
|
||||||
|
|
||||||
|
$(build)/extra-dir/multi-classpath-test.txt:
|
||||||
|
mkdir -p $(build)/extra-dir
|
||||||
|
echo "$@" > $@
|
||||||
|
|
||||||
|
$(build)/test/multi-classpath-test.txt:
|
||||||
|
echo "$@" > $@
|
||||||
|
|
||||||
$(build)/test.sh: $(test)/test.sh
|
$(build)/test.sh: $(test)/test.sh
|
||||||
cp $(<) $(@)
|
cp $(<) $(@)
|
||||||
|
|
||||||
|
@ -168,6 +168,7 @@ class Finder {
|
|||||||
unsigned* length,
|
unsigned* length,
|
||||||
bool tryDirectory = false) = 0;
|
bool tryDirectory = false) = 0;
|
||||||
virtual const char* urlPrefix(const char* name) = 0;
|
virtual const char* urlPrefix(const char* name) = 0;
|
||||||
|
virtual const char* nextUrlPrefix(const char* name, void *&finderElementPtr) = 0;
|
||||||
virtual const char* sourceUrl(const char* name) = 0;
|
virtual const char* sourceUrl(const char* name) = 0;
|
||||||
virtual const char* path() = 0;
|
virtual const char* path() = 0;
|
||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
|
@ -152,6 +152,30 @@ Avian_avian_SystemClassLoader_resourceURLPrefix
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_avian_SystemClassLoader_00024ResourceEnumeration_nextResourceURLPrefix
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object loader = reinterpret_cast<object>(arguments[1]);
|
||||||
|
object name = reinterpret_cast<object>(arguments[2]);
|
||||||
|
object finderElementPtrPtr = reinterpret_cast<object>(arguments[3]);
|
||||||
|
|
||||||
|
if (LIKELY(name) && LIKELY(finderElementPtrPtr)) {
|
||||||
|
THREAD_RUNTIME_ARRAY(t, char, n, stringLength(t, name) + 1);
|
||||||
|
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
|
||||||
|
|
||||||
|
void *&finderElementPtr = reinterpret_cast<void *&>(longArrayBody(t,
|
||||||
|
finderElementPtrPtr, 0));
|
||||||
|
const char* name = static_cast<Finder*>
|
||||||
|
(systemClassLoaderFinder(t, loader))->nextUrlPrefix(RUNTIME_ARRAY_BODY(n),
|
||||||
|
finderElementPtr);
|
||||||
|
|
||||||
|
return name ? reinterpret_cast<uintptr_t>(makeString(t, "%s", name)) : 0;
|
||||||
|
} else {
|
||||||
|
throwNew(t, Machine::NullPointerExceptionType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_avian_SystemClassLoader_getClass
|
Avian_avian_SystemClassLoader_getClass
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
@ -908,7 +908,16 @@ class MyFinder: public Finder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* urlPrefix(const char* name) {
|
virtual const char* urlPrefix(const char* name) {
|
||||||
for (Element* e = path_; e; e = e->next) {
|
void *finderElementPtr = NULL;
|
||||||
|
return nextUrlPrefix(name, finderElementPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char* nextUrlPrefix(const char* name,
|
||||||
|
void *&finderElementPtr)
|
||||||
|
{
|
||||||
|
Element *&e = reinterpret_cast<Element*&>(finderElementPtr);
|
||||||
|
e = e ? e->next : path_;
|
||||||
|
for (; e; e = e->next) {
|
||||||
unsigned length;
|
unsigned length;
|
||||||
System::FileType type = e->stat(name, &length, true);
|
System::FileType type = e->stat(name, &length, true);
|
||||||
if (type != System::TypeDoesNotExist) {
|
if (type != System::TypeDoesNotExist) {
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
public class Misc {
|
public class Misc {
|
||||||
private static class μClass {
|
private static class μClass {
|
||||||
public int μField;
|
public int μField;
|
||||||
@ -262,6 +266,27 @@ public class Misc {
|
|||||||
|
|
||||||
expect((Protected.class.getModifiers() & java.lang.reflect.Modifier.PUBLIC)
|
expect((Protected.class.getModifiers() & java.lang.reflect.Modifier.PUBLIC)
|
||||||
== 0);
|
== 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
int count = 0;
|
||||||
|
boolean test = false, extraDir = false;
|
||||||
|
ClassLoader loader = Misc.class.getClassLoader();
|
||||||
|
Enumeration<URL> resources = loader.getResources("multi-classpath-test.txt");
|
||||||
|
while (resources.hasMoreElements()) {
|
||||||
|
++count;
|
||||||
|
String url = resources.nextElement().toString();
|
||||||
|
if (url.contains("extra-dir")) {
|
||||||
|
extraDir = true;
|
||||||
|
} else if (url.contains("test")) {
|
||||||
|
test = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(count == 2);
|
||||||
|
expect(test);
|
||||||
|
expect(extraDir);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class Protected { }
|
protected class Protected { }
|
||||||
|
Loading…
Reference in New Issue
Block a user