Using spring-boot 2.2.4, java 8, Windows 10
I have the following code :
@EnableWs
@Configuration
@SpringBootApplication
public class DemoApplication {
public static void main(final String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public CryptoFactoryBean cryptoFactoryBean() throws IOException {
final CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
cryptoFactoryBean.setKeyStoreLocation(new FileSystemResource("C:\\test\\keystore.p12"));
cryptoFactoryBean.setKeyStorePassword("private");
cryptoFactoryBean.setKeyStoreType("PKCS12");
return cryptoFactoryBean;
}
}
Works fine when run with mvn spring-boot:run:
2020-02-07 11:14:51.334 DEBUG 3708 --- [ main] org.apache.wss4j.common.util.Loader : Trying to find [C:\test\keystore.p12] using sun.misc.Launcher$AppClassLoader@73d16e93 class loader.
2020-02-07 11:14:51.335 DEBUG 3708 --- [ main] org.apache.wss4j.common.util.Loader : Trying to find [C:\test\keystore.p12] using sun.misc.Launcher$AppClassLoader@73d16e93 class loader.
2020-02-07 11:14:51.337 DEBUG 3708 --- [ main] org.apache.wss4j.common.util.Loader : Trying to find [C:\test\keystore.p12] using ClassLoader.getSystemResource().
2020-02-07 11:14:51.655 DEBUG 3708 --- [ main] org.apache.wss4j.common.crypto.Merlin : The KeyStore C:\test\keystore.p12 of type PKCS12 has been loaded
2020-02-07 11:14:51.779 INFO 3708 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-02-07 11:14:51.943 INFO 3708 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-02-07 11:14:51.947 INFO 3708 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 2.627 seconds (JVM running for 3.298)
However when I package the jar and try to run it (java -jar \<myjar>.jar), the file (C:\test\keystore.p12) is not found :
2020-02-07 11:21:06.738 DEBUG 12128 --- [ main] org.apache.wss4j.common.util.Loader : Trying to find [C:\test\keystore.p12] using org.springframework.boot.loader.LaunchedURLClassLoader@31221be2 class loader.
2020-02-07 11:21:06.745 WARN 12128 --- [ main] org.apache.wss4j.common.util.Loader : Caught Exception while in Loader.getResource. This may be innocuous.
java.lang.IllegalArgumentException: name
at sun.misc.URLClassPath$Loader.findResource(URLClassPath.java:693) ~[na:1.8.0_131]
at sun.misc.URLClassPath.findResource(URLClassPath.java:215) ~[na:1.8.0_131]
at java.net.URLClassLoader$2.run(URLClassLoader.java:569) ~[na:1.8.0_131]
at java.net.URLClassLoader$2.run(URLClassLoader.java:567) ~[na:1.8.0_131]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_131]
at java.net.URLClassLoader.findResource(URLClassLoader.java:566) ~[na:1.8.0_131]
at org.springframework.boot.loader.LaunchedURLClassLoader.findResource(LaunchedURLClassLoader.java:58) ~[demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at java.lang.ClassLoader.getResource(ClassLoader.java:1096) ~[na:1.8.0_131]
at org.apache.wss4j.common.util.Loader.getResource(Loader.java:165) [wss4j-ws-security-common-2.2.3.jar!/:2.2.3]
at org.apache.wss4j.common.util.Loader.loadInputStream(Loader.java:59) [wss4j-ws-security-common-2.2.3.jar!/:2.2.3]
at org.apache.wss4j.common.crypto.Merlin.loadInputStream(Merlin.java:348) [wss4j-ws-security-common-2.2.3.jar!/:2.2.3]
at org.apache.wss4j.common.crypto.Merlin.loadProperties(Merlin.java:218) [wss4j-ws-security-common-2.2.3.jar!/:2.2.3]
at org.apache.wss4j.common.crypto.Merlin.<init>(Merlin.java:156) [wss4j-ws-security-common-2.2.3.jar!/:2.2.3]
at org.apache.wss4j.common.crypto.CryptoFactory.getInstance(CryptoFactory.java:119) [wss4j-ws-security-common-2.2.3.jar!/:2.2.3]
at org.apache.wss4j.common.crypto.CryptoFactory.getInstance(CryptoFactory.java:78) [wss4j-ws-security-common-2.2.3.jar!/:2.2.3]
...
I'm guessing (?) it has something to do with LaunchedURLClassLoader.
This is my pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Comment From: snicoll
This is similar to #19098. I don't see how it could be related to LaunchedURLClassLoader
given that it delegates to the standard URLClassLoader
.
Going forward, please share a link to a zip or a github repo as code in text is not very useful. To reproduce, we'll have to copy/paste all that in a project anyway.
Comment From: snicoll
I've copy/pasted the above on MacOS and can't reproduce the issue. I can give that a try on Windows later.
Comment From: Rommz
my bad, forgot to attach the test project. I've added it to my first post
Comment From: snicoll
Thanks. I can reproduce the issue on Windows.
Comment From: makaxel
Hello. I can confirm the issue. jar-file on windows - spring-boot 2.3.0 (2.2.7), java 8 and 11, Windows 10 - exception the same jar-file on linux - spring-boot 2.3.0 (2.2.7), java 11, oracle linux 7.7 - working OK slightly modified jar-file (pom parent and dependencies) - spring boot 1.3.3, java 8, Windows 10 - working OK
Maybe it will help. Sources are at https://github.com/makaxel/test-cryptoFileResourse and https://github.com/makaxel/test-cryptoFileResourseOld
Comment From: elvus
Hi i have the same error, the project is https://github.com/elvus/apiprinter I try this https://stackoverflow.com/questions/51203893/java-lang-illegalargumentexception-name but doesn't works. Sometimes it works and sometimes it doesn't.
The error occurs only after compiling
Comment From: mightybeaker
I have had the same problem on: :: Spring Boot :: (v2.2.1.RELEASE) Windows 10 openjdk version "11.0.2" 2019-01-15
I have an @Configuration
bean defining my Wss4jSecurityInterceptor
.
The WSS securement keystore location Resource
is injected via properties:
@Value("${wss.securement.ks.url}")
private Resource securementKeyStoreLocation;
If I set the property to a classpath resource it works fine:
wss.securement.ks.url=classpath:ws-client.jks
If I override this in an exernal properties file pointing to an external keystore location I hit the problem:
wss.securement.ks.url=file:///TEST/certs/ws-client.jks
I tried the following override to workaround the issue and it seems to work quite well until the underlying bug is fixed:
@Bean
public CryptoFactoryBean securementSignatureCrypto() throws IOException
{
CryptoFactoryBean securementSigCrypto = new CryptoFactoryBean()
{
@Override
public void setKeyStoreLocation(Resource location) throws IOException
{
String path = null;
try
{
path = location.getFile().getPath().replace("\\", "/");
}
catch (IOException ex)
{
if (location instanceof ClassPathResource) {
ClassPathResource classPathResource = (ClassPathResource) location;
path = classPathResource.getPath();
}
else {
throw ex;
}
}
Properties keyStoreLocations = new Properties();
keyStoreLocations.setProperty("org.apache.ws.security.crypto.merlin.file", path);
setConfiguration(keyStoreLocations);
}};
securementSigCrypto.setKeyStoreType(KEYSTORE_TYPE);
securementSigCrypto.setKeyStoreLocation(securementKeyStoreLocation);
securementSigCrypto.setKeyStorePassword(securementKeyStorePassword);
return securementSigCrypto;
}
So I had to replace the windows style back slashes with linux style forward slashes and it started working!
As per the line above: path = location.getFile().getPath().replace("\\", "/");
Comment From: wilkinsona
Thanks for the sample and for your patience, @Rommz. Unfortunately, this is a bug in WSS4J's Loader
so fixing it is out of our control. It is standard behaviour for the JVM's URLClassLoader
to throw an IllegalArgumentException
when getResource(String)
is called with a name
that cannot be turned into a URL
and that's what is happening when you run your application is a jar file.
The early parts of Loader
's getResource
method handle exceptions from getResource(String)
but the latter parts do not. I believe it needs to be updated to consistently handle exceptions from getResource(String)
and then move on to the next candidate.
Comment From: wilkinsona
@makaxel This worked with Spring Boot 1.3.x as there was a workaround in our class loader. It was removed as we want its behaviour to align as closely as possible with a standard URLClassLoader
. Please see https://github.com/spring-projects/spring-boot/issues/5650#issuecomment-208253864 and subsequent comments for further details.