使用CXF的3.0.0-milestone1做签名、加密时发现异常。具体异常堆栈如下:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Can't find bundle for base name org/apache/xml/security/resource/xmlsecurity, locale zh_CN at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:159) at sun.proxy.$Proxy44.sayHi(Unknown Source) at Main.main(Main.java:11) Caused by: java.util.MissingResourceException: Can't find bundle for base name org/apache/xml/security/resource/xmlsecurity, locale zh_CN at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499) at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322) at java.util.ResourceBundle.getBundle(ResourceBundle.java:724) at org.apache.wss4j.common.crypto.WSProviderConfig$4.<init>(WSProviderConfig.java:138) at org.apache.wss4j.common.crypto.WSProviderConfig.initializeResourceBundles(WSProviderConfig.java:135) at org.apache.wss4j.common.crypto.WSProviderConfig.init(WSProviderConfig.java:69) at org.apache.wss4j.dom.WSSConfig.init(WSSConfig.java:387) at org.apache.wss4j.dom.WSSConfig.getNewInstance(WSSConfig.java:394) at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:180) at org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor$WSS4JOutInterceptorInternal.handleMessage(WSS4JOutInterceptor.java:140) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:502) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:411) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:314) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:267) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:137) ... 2 more
在使用Maven搭建的工程将cxf版本替换为3.0.0解决!!!。
出现问题的根本原因是由于wss4j-ws-security-common-2.0-beta.jar中的WSProviderConfig类initializeResourceBundles方法出现问题:
private static void initializeResourceBundles() { ResourceBundle resourceBundle = new ResourceBundle() { private final ResourceBundle wss4jSecResourceBundle = ResourceBundle.getBundle("messages.wss4j_errors"); private final ResourceBundle xmlSecResourceBundle = ResourceBundle.getBundle(Constants.exceptionMessagesResourceBundleBase); @Override protected Object handleGetObject(String key) { Object value = null; try { value = wss4jSecResourceBundle.getObject(key); } catch (MissingResourceException e) { try { value = xmlSecResourceBundle.getObject(key); } catch (MissingResourceException ex) { //NOPMD //ignore } } return value; } @Override public Enumeration<String> getKeys() { throw new UnsupportedOperationException("getKeys not supported"); } }; I18n.init(resourceBundle); }
在2.0.0版本中为:
public WSS4JResourceBundle() { wss4jSecResourceBundle = ResourceBundle.getBundle("messages.wss4j_errors"); ResourceBundle tmpResourceBundle; try { tmpResourceBundle = ResourceBundle.getBundle(Constants.exceptionMessagesResourceBundleBase, Locale.getDefault(), I18n.class.getClassLoader()); } catch (MissingResourceException ex) { // Using a Locale of which there is no properties file. LOG.debug(ex.getMessage()); // Default to en/US tmpResourceBundle = ResourceBundle.getBundle(Constants.exceptionMessagesResourceBundleBase, new Locale("en", "US"), I18n.class.getClassLoader()); } xmlSecResourceBundle = tmpResourceBundle; }
private final ResourceBundle xmlSecResourceBundle = ResourceBundle.getBundle(Constants.exceptionMessagesResourceBundleBase);会导致找不到资源的异常。