org.ofbiz.base.start.StartupException: Cannot start() org.ofbiz.commons.vfs.CommonsVfsContainer (Initializing StandardFileSystemManager (Could not load VFS configuration from "file:/home/engineers/workspaces/ws-opentaps-tpg/opentaps/bin/META-INF/vfs-providers.xml ".)) at org.ofbiz.base.container.ContainerLoader.start(ContainerLoader.java:104) at org.ofbiz.base.start.Start.startStartLoaders(Start.java:264) at org.ofbiz.base.start.Start.startServer(Start.java:313) at org.ofbiz.base.start.Start.start(Start.java:317) at org.ofbiz.base.start.Start.main(Start.java:400) org.ofbiz.base.container.ContainerException: Initializing StandardFileSystemManager (Could not load VFS configuration from "file:/home/engineers/workspaces/ws-opentaps-tpg/opentaps/bin/META-INF/vfs-providers.xml ".) at org.ofbiz.commons.vfs.CommonsVfsContainer.start(CommonsVfsContainer.java:51) at org.ofbiz.base.container.ContainerLoader.start(ContainerLoader.java:102) at org.ofbiz.base.start.Start.startStartLoaders(Start.java:264) at org.ofbiz.base.start.Start.startServer(Start.java:313) at org.ofbiz.base.start.Start.start(Start.java:317) at org.ofbiz.base.start.Start.main(Start.java:400) Caused by: org.apache.commons.vfs.FileSystemException: Could not load VFS configuration from "file:/home/engineers/workspaces/ws-opentaps-tpg/opentaps/bin/META-INF /vfs-providers.xml ". at org.apache.commons.vfs.impl.StandardFileSystemManager.configure(StandardFileSystemManager.java:199) at org.apache.commons.vfs.impl.StandardFileSystemManager.configurePlugins(StandardFileSystemManager.java:156) at org.apache.commons.vfs.impl.StandardFileSystemManager.init(StandardFileSystemManager.java:129) at org.webslinger.commons.vfs.VFSUtil.createStandardFileSystemManager(VFSUtil.java:351) at org.webslinger.commons.vfs.VFSUtil.createStandardFileSystemManager(VFSUtil.java:345) at org.ofbiz.commons.vfs.CommonsVfsContainer.start(CommonsVfsContainer.java:45) ... 5 more Caused by: org.apache.commons.vfs.FileSystemException: Multiple providers registered for URL scheme "ofbiz-home". at org.apache.commons.vfs.impl.DefaultFileSystemManager.addProvider(DefaultFileSystemManager.java:174) at org.apache.commons.vfs.impl.StandardFileSystemManager.addProvider(StandardFileSystemManager.java:362) at org.apache.commons.vfs.impl.StandardFileSystemManager.configure(StandardFileSystemManager.java:262) at org.apache.commons.vfs.impl.StandardFileSystemManager.configure(StandardFileSystemManager.java:195) ... 10 more
网络上(包括Opentaps论坛与OFBiz Mailing Lists)所提供的解决方案是在Opentaps中禁用vfs和webslinger,即把\framework\base\config\ofbiz-containers.xml中以下两行注释掉:
<container name="commons-vfs-container" class="org.ofbiz.commons.vfs.CommonsVfsContainer"/> <container name="webslinger-container" class="org.ofbiz.webslinger.WebslingerContainer"/>
这种解决方案能够使Opentaps启动成功,但是实际上在Opentaps真正需要使用到vfs与webslinger就显得非常无能为力.
根据异常信息分析,原因有可能是重复加载了vfs-providers.xml(定义URL scheme为ofbiz-home的Provider).经过调试证实了笔者的猜测,在实例化org.apache.commons.vfs.impl.StandardFileSystemManager后,会调用其init方法来初始化,在init方法中调用了configurePlugins方法,以下为configurePlugins方法的代码:
protected void configurePlugins() throws FileSystemException { ClassLoader cl = findClassLoader(); Enumeration enumResources = null; try { enumResources = cl.getResources(PLUGIN_CONFIG_RESOURCE); } catch (IOException e) { throw new FileSystemException(e); } while (enumResources.hasMoreElements()) { URL url = (URL) enumResources.nextElement(); configure(url); } }
在此段代码设置断点,发现%OPENTAPS_HOME%/bin/META-INF/vfs-providers.xml被加载了两次,同时抛出了异常,这正是问题所在.那么vfs-providers.xml为什么会被加载两次,请看以下代码:
protected void configurePlugins() throws FileSystemException { ... enumResources = cl.getResources(PLUGIN_CONFIG_RESOURCE); ... }
java.lang.ClassLoader :
public Enumeration<URL> getResources(String name) throws IOException { Enumeration[] tmp = new Enumeration[2]; if (parent != null) { tmp[0] = parent.getResources(name); } else { tmp[0] = getBootstrapResources(name); } tmp[1] = findResources(name); return new CompoundEnumeration(tmp); }
推断出vfs-providers.xml在Parent ClassLoader中被加载后,又被Current ClassCloader加载.从ClassLoder方面再深入的分析就太费时间精力了,毕竟只是在Eclipse才有这个问题.有更快速方便的方法,就是修改StandardFileSystemManager.
在Opentaps根目录新建目录debug-in-eclipse-hack/src,在Eclipse中设置为源代码目录,把StandardFileSystemManager根据包路径拷贝进去,修改configurePlugins方法,代码如下.
protected void configurePlugins() throws FileSystemException { ClassLoader cl = findClassLoader(); Enumeration enumResources = null; try { enumResources = cl.getResources(PLUGIN_CONFIG_RESOURCE); } catch (IOException e) { throw new FileSystemException(e); } Set set = new HashSet(); while (enumResources.hasMoreElements()) { URL url = (URL) enumResources.nextElement(); if (!set.contains(url.toString())){ set.add(url.toString()); } } Iterator itr = set.iterator(); while (itr.hasNext()){ String url = (String)itr.next(); try { configure(new URL(url)); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Opentaps启动时新的StandardFileSystemManager类会被加载.
修改的代码会把重复的vfs-providers.xml去掉,从而解决问题.
好了,现在重新在Eclipse中启动Opentaps.如果还出现同样的问题,则把framework/webslinger/build/lib/ofbiz-webslinger.jar删除就可解决问题.