Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重新部署应用程序时无法加载Bouncycastle_Java_Bouncycastle - Fatal编程技术网

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

Java 重新部署应用程序时无法加载Bouncycastle,java,bouncycastle,Java,Bouncycastle,我按照以下说明添加bouncycastle: 但我还有一个问题。有时,当我重新部署应用程序时,找不到此提供程序,因此我的应用程序会引发异常。此问题仅在每100次重新部署中发生一次(可能更少)。当我重新启动我的服务器weblogic时,它又开始工作了。我将非常感谢任何关于为什么会出现这个问题的建议 编辑: 我在上面的链接中使用了这两种方法,因为当我只使用其中一种方法时,它就不起作用了 我将此provder添加到java.security,然后在类中注册了此provder: static {

我按照以下说明添加bouncycastle: 但我还有一个问题。有时,当我重新部署应用程序时,找不到此提供程序,因此我的应用程序会引发异常。此问题仅在每100次重新部署中发生一次(可能更少)。当我重新启动我的服务器weblogic时,它又开始工作了。我将非常感谢任何关于为什么会出现这个问题的建议

编辑:

我在上面的链接中使用了这两种方法,因为当我只使用其中一种方法时,它就不起作用了 我将此provder添加到java.security,然后在类中注册了此provder:

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

您可能遇到了一个
NoClassDefFoundError
。这是JSSE实现中的一个已知问题

以下是场景:

  • 您的容器在特定于应用程序的类加载器中加载bouncy castle类
  • 您创建的提供程序实例依赖于该类以及该类加载器
  • 然后,由于顶级JVM类加载器中的静态字段,提供者被注册到JREAPI中
  • 重新部署时,容器丢弃应用程序类加载器以创建新的类加载器
  • 由于已经知道该算法,第二个提供程序插入会以静默方式失败
  • 使用该算法时,提供程序实例根本不可用,因为类加载器已被丢弃
  • 然后,唯一的选择是重新启动容器以修复这种情况
由于没有用于取消部署事件的标准侦听器,因此不可能同时触发JSSE提供程序的删除

避免这种麻烦的推荐方法是在JVM类路径或容器类路径中使用bouncy castle类。您必须将其从应用程序中删除。现在,您需要使用静态初始值设定项的替代选项注册BC provider。WebLogic提供(我使用了服务器启动类),该代码将负责在整个服务器/JVM生命周期内注册JSSE提供程序

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


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

我使用此解决方案在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);
列表将被扩展以使用bouncy castle提供程序,新列表将作为本地线程注入。这可以在servletfilter或其他东西中使用。请求完成后,可能需要将列表重置为旧值

Providers.endThreadProviderList(this.oldList);

您提供的链接提供了两种方法,您正在使用它们?我将这两种方法都添加到java.security这个提供程序中,然后在我的类中注册了这个提供程序:static{security.addProvider(new BouncyCastleProvider();}您可以只使用static方法吗?是的,我先尝试一下,它只适用于JUnit测试。但当我将此应用程序部署到weblogic时,它停止工作,然后我找到上面的链接并按照它的说明进行操作:检查addProvider()的返回值,调用getProviders()查看它是否存在,如果可以,请在removeProvider()处设置断点.我遇到了完全相同的问题,伊夫的回答正是解决这个问题的方法。嗯,回答得很好。我会尝试一下,但这确实很难测试,因为这种问题在数百次重新部署中很少出现。你知道为什么有时候会出现这种问题吗?但我相信A.R.Younce,并认为这个答案是正确的。thx很多年前我第一次遇到麻烦时,每次重新部署都失败了。也许WebLogic已经得到了改进,能够解决这个问题。这主要取决于BC是否得到了有效使用,或者所有必需的类是否至少被加载/实例化了一次,或者在重新部署后缺少了一些类,比如这里,谢谢,在jre/lib/ext中复制了lib,并在jre/lib/security/java.security中添加了security.provider.N=org.bouncycastle.jce.provider.BouncyCastleProvider.bounchycastleprovider。这似乎不起作用(我得到一个
没有安装的提供商支持此密钥:
),据我从JavaDoc中了解,它只能由JAR验证器在内部使用,不能用于JCE提供程序的一般用法。在web应用程序的关闭过程中删除BC提供程序非常有效!在关闭过程中删除提供程序时,可以从
BouncyCastleProvider.provider\u name.