Java e“复制到输出目录并通过清单链接”->OK->Apply->Build->Build Artifacts…->构建

Java e“复制到输出目录并通过清单链接”->OK->Apply->Build->Build Artifacts…->构建,java,jar,executable-jar,Java,Jar,Executable Jar,安全性已经是一个棘手的话题,但我很失望地看到最流行的解决方案是删除安全签名。Maven shade分解BouncyCastle jar文件,该文件将签名放入META-INF,但BouncyCastle签名对于新的uber jar(仅适用于BC jar)无效,这就是导致此线程中出现无效签名错误的原因 是的,按照@ruhsuzbaykus的建议排除或删除签名确实会消除原始错误,但也会导致新的、神秘的错误: java.security.NoSuchAlgorithmException: PBEWith

安全性已经是一个棘手的话题,但我很失望地看到最流行的解决方案是删除安全签名。Maven shade分解BouncyCastle jar文件,该文件将签名放入META-INF,但BouncyCastle签名对于新的uber jar(仅适用于BC jar)无效,这就是导致此线程中出现无效签名错误的原因

是的,按照@ruhsuzbaykus的建议排除或删除签名确实会消除原始错误,但也会导致新的、神秘的错误:

java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not available
通过明确指定在何处查找算法,如下所示:

SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC","BC");
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <filters>
                    <filter>
                        <artifact>org.bouncycastle:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>your.class.here</mainClass>
                    </transformer>
                </transformers>
                <shadedArtifactAttached>true</shadedArtifactAttached>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jarsigner-plugin</artifactId>
    <version>1.4</version>
    <executions>
        <execution>
            <id>sign</id>
            <goals>
                <goal>sign</goal>
            </goals>
        </execution>
        <execution>
            <id>verify</id>
            <goals>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <keystore>/path/to/myKeystore</keystore>
        <alias>myfirstkey</alias>
        <storepass>111111</storepass>
        <keypass>111111</keypass>
    </configuration>
</plugin>
我得到了一个不同的错误:

java.security.NoSuchProviderException: JCE cannot authenticate the provider BC
JCE无法验证提供程序,因为我们已删除加密签名

我找到的解决方案是使用jar-in-jar方法将BouncyCastle签名保存在单个可执行jar中的插件

更新: 另一种方法(正确的方法?)是使用。这允许您继续使用Maven shade,而不会出现安全错误。但是,您必须拥有代码签名证书(Oracle建议搜索“Java代码签名证书”)。POM配置如下所示:

SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC","BC");
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <filters>
                    <filter>
                        <artifact>org.bouncycastle:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>your.class.here</mainClass>
                    </transformer>
                </transformers>
                <shadedArtifactAttached>true</shadedArtifactAttached>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jarsigner-plugin</artifactId>
    <version>1.4</version>
    <executions>
        <execution>
            <id>sign</id>
            <goals>
                <goal>sign</goal>
            </goals>
        </execution>
        <execution>
            <id>verify</id>
            <goals>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <keystore>/path/to/myKeystore</keystore>
        <alias>myfirstkey</alias>
        <storepass>111111</storepass>
        <keypass>111111</keypass>
    </configuration>
</plugin>

org.apache.maven.plugins
maven阴影插件
3.1.0
包裹
阴凉处
org.bouncycastle:*
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
你的班级在这里
真的
org.apache.maven.plugins
maven jarsigner插件
1.4
签名
签名
验证
验证
/路径/to/myKeystore
我的第一把钥匙
111111
111111

不,没有办法让JCE识别自签名证书,因此如果您需要保留BouncyCastle证书,您必须使用jar-in-jar插件或获得JCE证书。

如果您使用gradle,下面是完整的farJar任务:

version = '1.0'
//create a single Jar with all dependencies
task fatJar(type: Jar) {
    manifest {
        attributes 'Implementation-Title': 'Gradle Jar File Example',  
            'Implementation-Version': version,
            'Main-Class': 'com.example.main'
    }
    baseName = project.name + '-all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA' 
    with jar
}

我最近开始在我的项目中使用IntelliJ。然而,我的一些同事仍然在相同的项目上使用Eclipse。今天,在执行IntelliJ创建的jar文件后,我遇到了同样的错误。虽然这里所有的解决方案都在谈论几乎相同的事情,但没有一个对我有效(可能是因为我不使用ANT,maven build给了我其他的错误,这些错误都指向了我,而且我自己也不知道签名的JAR是什么!)

最后,我帮助了我

zip -d demoSampler.jar 'META-INF/*.SF' 'META-INF/*.RSA' 'META-INF/*SF'
猜猜我的jar文件中删除了什么

deleting: META-INF/ECLIPSE_.SF 
deleting: META-INF/ECLIPSE_.RSA

这个问题似乎与一些与eclipse相关的文件有关。

如果您正在寻找一个Fat JAR解决方案,而不需要解包或篡改原始库,而是使用一个特殊的JAR类加载器,请查看

免责声明:我没有编写代码,只是打包并发布在Maven Central上,并在我的read me中描述如何使用它


我个人使用它来创建包含BouncyCastle依赖项的可运行uber jar。也许它对您也有用。

我在创建胖Jar时在
gradle
中遇到了同样的问题,用排除行更新
build.gradle
文件纠正了这个问题

jar {
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
    manifest {
        attributes 'Main-Class': 'com.test.Main'
    }
}

我也面临同样的问题,在某个地方参考后,它的作用如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.1</version>
    <configuration>
        <createDependencyReducedPom>false</createDependencyReducedPom>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
            </configuration>
        </execution>
    </executions>
</plugin>

org.apache.maven.plugins
maven阴影插件
3.2.1
假的
包裹
阴凉处
*:*
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA

对于那些对接受的解决方案有问题的人,有另一种方法可以使用DontIncludeResourceTransformer从着色jar中排除资源:


BC1024KE.DSA

在Shade 3.0中,此转换器接受一个资源列表。在此之前,您只需要使用多个transformer,每个transformer具有一个资源。

在Intellij中,当我在最后一行单击“作为Maven项目添加”时,Intellij说“找到了非托管pom文件”,我就遇到了这种情况。同时,已生成out文件夹。因此,它没有得到最近的变化

删除文件夹并运行程序为我解决了这个问题。然后重新创建out文件夹

看看小狐狸的回答。我收到的错误与他的非常相似。

您可以使用它生成一个jar

Shadow是一个Gradle插件,用于将项目的依赖类和资源组合到单个输出Jar中。组合罐通常指胖罐或优步罐

  • 修改
    build.gradle

    plugins {
        ...
        // ① Add the shadow plugin
        id "com.github.johnrengelman.shadow" version "5.2.0"
    }
    
    ...
    // ② Config the shadow jar, its name is baseName-1.0-classifier.jar
    shadowJar {
        archiveBaseName.set('baseName')
        archiveClassifier.set('classifier')
        archiveVersion.set('1.0')
        manifest {
            attributes 'Main-Class': 'Main'
        }
    }
    
    // ③ Disable the default jar task
    jar.enabled = false
    // ④ Execute the shadowJar task when compiling
    build.dependsOn(shadowJar)
    
  • 执行命令
    gradlebuild
    ,将生成jar文件:

    • /build/libs/baseName-1.0-classifier.jar

  • 你想在自己的罐子上签名吗?如果是的话,你打算怎么签字?不,至少我不这么认为。Xcode可能正试图自己对其进行签名,但似乎没有任何设置来关闭它。别忘了检查是否也对包含已实现接口的JAR进行了签名!我如何在清单文件中反映这一点?我从未见过
    deleting: META-INF/ECLIPSE_.SF 
    deleting: META-INF/ECLIPSE_.RSA
    
    jar {
        from {
            configurations.compile.collect {
                it.isDirectory() ? it : zipTree(it)
            }
        }
        exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
        manifest {
            attributes 'Main-Class': 'com.test.Main'
        }
    }
    
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.2.1</version>
        <configuration>
            <createDependencyReducedPom>false</createDependencyReducedPom>
        </configuration>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
                <configuration>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
            </execution>
        </executions>
    </plugin>
    
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
                    <resource>BC1024KE.DSA</resource>
                </transformer>
              </transformers>
    
    plugins {
        ...
        // ① Add the shadow plugin
        id "com.github.johnrengelman.shadow" version "5.2.0"
    }
    
    ...
    // ② Config the shadow jar, its name is baseName-1.0-classifier.jar
    shadowJar {
        archiveBaseName.set('baseName')
        archiveClassifier.set('classifier')
        archiveVersion.set('1.0')
        manifest {
            attributes 'Main-Class': 'Main'
        }
    }
    
    // ③ Disable the default jar task
    jar.enabled = false
    // ④ Execute the shadowJar task when compiling
    build.dependsOn(shadowJar)