commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bernd Eckenfels (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (VFS-424) VFS 2.0 class loading breaks in OSGi, regression from 1.0
Date Thu, 11 Aug 2016 17:24:20 GMT

    [ https://issues.apache.org/jira/browse/VFS-424?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15417628#comment-15417628
] 

Bernd Eckenfels commented on VFS-424:
-------------------------------------

Do you deploy VFS as its own bundle or is it embedded or shadowed in the application bundle
or a different service bundle? In the later case, did you include the xml resources as well?

I am using VFS in OSGi without the VFS.getManager(). I simply instantiate the manager myself.
I think this is much better as it avoids sharing the instance and you have better control
over classloading and configuration.

(That said, yes we should fix it anyway, using the (new) setter does not look like we should
require it for OSGi use)

> VFS 2.0 class loading breaks in 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 Gregory
>            Assignee: Bernd Eckenfels
>             Fix For: 2.1
>
>
> 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 was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message