Gary D. Gregory created VFS-424:
-----------------------------------
Summary: VFS 2.0 class loading breaks OSGi, regression from 1.0
Key: VFS-424
URL: https://issues.apache.org/jira/browse/VFS-424
Project: Commons VFS
Issue Type: Bug
Affects Versions: 2.0
Environment: Apache Maven 3.0.4 (r1232337; 2012-01-17 03:44:56-0500)
Maven home: C:\Java\apache-maven-3.0.4\bin\..
Java version: 1.6.0_31, vendor: Sun Microsystems Inc.
Java home: C:\Program Files\Java\jdk1.6.0_31\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"
Reporter: Gary D. Gregory
Class loading changed between version 1.0 and 2.0 in
org.apache.commons.vfs2.impl.StandardFileSystemManager.init()
This breaks our app server running under OSGi (Equinox) like this:
{noformat}
org.apache.commons.vfs2.FileSystemException: Could not create a file system
manager of class "org.apache.commons.vfs2.impl.StandardFileSystemManager".
at org.apache.commons.vfs2.VFS.createManager(VFS.java:99)
at org.apache.commons.vfs2.VFS.getManager(VFS.java:50)
at
com.seagullsw.toolbox.config.ConfigurationDirectory.resolveFileObject(ConfigurationDirectory.java:315)
at
com.seagullsw.toolbox.config.Configuration.resolveFileObject(Configuration.java:135)
<Snip: ...my app frames...>
at
com.seagullsw.appinterface.server.osgi.JCicsOsgiTestCase.testJcicsOsgiRoundtrip(JCicsOsgiTestCase.java:226)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:307)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:112)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:73)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at
org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
at
org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:102)
at
org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.apache.commons.vfs2.FileSystemException: Could not load VFS
configuration from
"bundleresource://7.fwk545215872:34/org/apache/commons/vfs2/impl/providers.xml".
at
org.apache.commons.vfs2.impl.StandardFileSystemManager.configure(StandardFileSystemManager.java:199)
at
org.apache.commons.vfs2.impl.StandardFileSystemManager.init(StandardFileSystemManager.java:123)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.commons.vfs2.VFS.createManager(VFS.java:88)
... 49 more
Caused by: java.lang.ClassCastException:
org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider cannot be cast
to org.apache.commons.vfs2.provider.FileProvider
at
org.apache.commons.vfs2.impl.StandardFileSystemManager.addProvider(StandardFileSystemManager.java:371)
at
org.apache.commons.vfs2.impl.StandardFileSystemManager.configure(StandardFileSystemManager.java:270)
at
org.apache.commons.vfs2.impl.StandardFileSystemManager.configure(StandardFileSystemManager.java:195)
... 55 more
{noformat}
Which I work around with this hack:
{code:java}
private void initVfs() {
StandardFileSystemManager fsm = new StandardFileSystemManager();
fsm.setClassLoader(fsm.getClass().getClassLoader());
try {
FieldUtils.writeDeclaredStaticField(VFS.class, "instance", fsm,
true);
fsm.init();
} catch (FileSystemException e) {
...
} catch (IllegalAccessException e) {
...
}
}
{code}
Two questions:
(1) Why is org.apache.commons.vfs2.VFS.getManager() coded with a class name ref
instead of the a real Class object or an actual instance:
{code:java}
public static synchronized FileSystemManager getManager()
throws FileSystemException
{
if (instance == null)
{
instance =
createManager("org.apache.commons.vfs2.impl.StandardFileSystemManager");
}
return instance;
}
{code}
Why not:
{code:java}
public static synchronized FileSystemManager getManager()
throws FileSystemException
{
if (instance == null)
{
instance = new StandardFileSystemManager();
// where the StandardFileSystemManager constructor calls init();
}
return instance;
}
{code}
If not, what about adding a setManager(FileSystemManager)?
This did not happen in 1.0, it worked fine in OSGi.
In 1.0, the init() method is:
{code:java}
public void init() throws FileSystemException
{
// Set the replicator and temporary file store (use the same component)
final DefaultFileReplicator replicator = createDefaultFileReplicator();
setReplicator(new PrivilegedFileReplicator(replicator));
setTemporaryFileStore(replicator);
if (classLoader == null)
{
// Use default classloader
classLoader = getClass().getClassLoader();
}
if (configUri == null)
{
// Use default config
final URL url = getClass().getResource(CONFIG_RESOURCE);
if (url == null)
{
throw new
FileSystemException("vfs.impl/find-config-file.error", CONFIG_RESOURCE);
}
configUri = url;
}
// Configure
configure(configUri);
// Configure Plugins
configurePlugins();
// Initialise super-class
super.init();
}
{code}
In 2.0, the init() method is:
{code:java}
public void init() throws FileSystemException
{
// Set the replicator and temporary file store (use the same component)
final DefaultFileReplicator replicator = createDefaultFileReplicator();
setReplicator(new PrivilegedFileReplicator(replicator));
setTemporaryFileStore(replicator);
/* replaced by findClassLoader
if (classLoader == null)
{
// Use default classloader
classLoader = getClass().getClassLoader();
}
*/
if (configUri == null)
{
// Use default config
final URL url = getClass().getResource(CONFIG_RESOURCE);
if (url == null)
{
throw new
FileSystemException("vfs.impl/find-config-file.error", CONFIG_RESOURCE);
}
configUri = url;
}
// Configure
configure(configUri);
// Configure Plugins
configurePlugins();
// Initialise super-class
super.init();
}
{code}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira