重新部署应用程序时无法加载Bouncycastle

我按照这个指示添加bouncycastle: http : //www.bouncycastle.org/wiki/display/JA1/Provider+Installation但我还有一个问题。 有时,当我重新部署我的应用程序时,找不到此提供程序,因此我的应用程序抛出exception。 每100次重新部署(可能更少)只发生一个问题。 当我重新启动我的服务器 – weblogic然后它再次开始工作。 我将非常感谢有关此问题发生的任何建议

编辑:

我在上面的链接中使用这两种方法,因为当我只使用其中一种然后它不起作用我添加到java.security这个提示,然后在我的课程中我注册了这个提示:

static { Security.addProvider(new BouncyCastleProvider()); } 

你可能得到了一个NoClassDefFoundError 。 这是JSSE实现的已知问题。

这是场景:

  • 您的容器在特定于应用程序的ClassLoader中加载充气城堡类
  • 您创建的提供程序实例依赖于类ClassLoader等类
  • 然后,由于顶级JVM ClassLoader中的静态字段,提供程序已注册到JRE API中
  • 重新部署时,容器会丢弃应用程序ClassLoader以创建新的应用程序
  • 由于算法已知,第二个提供程序插入无提示失败
  • 使用该算法时,提供程序实例根本无法使用,因为ClassLoader已被丢弃
  • 然后唯一的选择是重新启动容器以解决问题。

由于undeploy事件没有标准侦听器,因此无法在每次触发JSSE提供程序时将其删除。

避免这种麻烦的推荐方法是在JVM ClassPath或容器ClassPath中使用弹性城堡类。 您必须从应用程序中删除它。 现在,您需要使用静态初始化程序的备用选项注册BC提供程序。 WebLogic提供了在服务器启动时触发代码的方法 (我使用过服务器启动类),这段代码将负责为整个服务器/ JVM生命周期注册JSSE提供程序。

另一个选择是在JRE java.security文件中添加以下行,在jre/lib/ext使用bouncy castle jar,但我不喜欢这种方式,因为更新时可能会丢失: security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider

那么应用程序只是希望实现在那里,为算法可用性添加测试以向操作员和用户报告任何麻烦可能是个好主意。

我使用这个工作来重新部署Tomcat中的应用程序:

 public class GenSignCastle { BouncyCastleProvider bcProvider = null; public GenSignCastle() { if ( bcProvider == null ) { bcProvider = new BouncyCastleProvider(); Provider[] providers = Security.getProviders(); String name = bcProvider.getName(); Security.removeProvider( name ); // remove old instance Security.addProvider( bcProvider ); } } . . . } 

有趣的是我必须首先删除BouncyCastleProvider以在重新部署后再次使用它。

通过以下代码和sun.security.jce包的用法可以轻松解决此问题:

 ProviderList list = Providers.getFullProviderList(); ProviderList.add(list, new BouncyCastleProvider()); Providers.beginThreadProviderList(list); 

该列表将扩展为使用充气城堡提供程序,新列表将作为本地线程注入。 这可以在servletfilter或其他内容中使用。 也许有必要在请求完成后将列表重置为旧值

 Providers.endThreadProviderList(this.oldList);