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

时间:2012-04-30 07:10:58

标签: java bouncycastle

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

编辑:

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

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

3 个答案:

答案 0 :(得分:23)

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

以下是该方案:

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

由于undeploy事件没有标准侦听器,因此无法在时间触发JSSE提供程序。

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

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

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

答案 1 :(得分:10)

我使用这个方法在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以在重新部署后再次使用它。

答案 2 :(得分:0)

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

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

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

Providers.endThreadProviderList(this.oldList);