I have an integration task with some service. In this case I got some wsdl url, some .jks file and password. Nothing else. I already tested this wsdl endpoints by SoapUI and got success results (can do only with SSL settings [.jks and password]). After that I export whole wsdl from SoapUI and generated classes with plugin:
<plugin>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>4.0.2</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<wsdlDirectory>${project.basedir}/src/main/resources/</wsdlDirectory>
<wsdlFiles>
<wsdlFile>exported.wsdl</wsdlFile>
</wsdlFiles>
<packageName>az.atb.parking.client</packageName>
<sourceDestDir>
${project.build.directory}/generated-sources/
</sourceDestDir>
</configuration>
</plugin>
I now that I need to do requests with my .jks and password.
So my WebServiceClient after generate looks like:
@Component
@WebServiceClient(name = "PP", targetNamespace = "PP", wsdlLocation = "https://PRIVATE_URL:PORT/?wsdl")
public class PP extends Service
{
private static final URL PP_WSDL_LOCATION;
private static final WebServiceException PP_EXCEPTION;
private static final QName PP_QNAME = new QName("PP", "PP");
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL("https://PRIVATE_URL:PORT/?wsdl");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
PP_WSDL_LOCATION = url;
PP_EXCEPTION = e;
}
public PP() {
super(__getWsdlLocation(), PP_QNAME);
}
public PP(WebServiceFeature... features) {
super(__getWsdlLocation(), PP_QNAME, features);
}
public PP(URL wsdlLocation) {
super(wsdlLocation, PP_QNAME);
}
public PP(URL wsdlLocation, WebServiceFeature... features) {
super(wsdlLocation, PP_QNAME, features);
}
public PP(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public PP(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
super(wsdlLocation, serviceName, features);
}
@WebEndpoint(name = "PPPort")
public PPPort getPPPort() {
return super.getPort(new QName("PP", "PPPort"), PPPort.class);
}
@WebEndpoint(name = "PPPort")
public PPPort getPPPort(WebServiceFeature... features) {
return super.getPort(new QName("PP", "PPPort"), PPPort.class, features);
}
private static URL __getWsdlLocation() {
if (PP_EXCEPTION!= null) {
throw PP_EXCEPTION;
}
return PP_WSDL_LOCATION;
}
}
So in my @Service I tried to use this Client like:
@Service
public class ParkingClientService {
private final PPPort client;
public ParkingClientService(PP ppClient) {
this.client = ppClient.getPPPort();
}
// OTHER METHODS
}
But it gives me errors like (after starting spring application):
1. org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'PP' defined in file [C:\Users\USERNAME\IdeaProjects\parking-api\target\classes\az\atb\parking\client\PP.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [az.atb.parking.client.PP]: Constructor threw exception; nested exception is jakarta.xml.ws.WebServiceException: Failed to access the WSDL at: https://PRIVATE_URL:PORT/?wsdl. It failed with:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.
2. Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [az.atb.parking.client.PP]: Constructor threw exception; nested exception is jakarta.xml.ws.WebServiceException: Failed to access the WSDL at: https://PRIVATE_URL:PORT/?wsdl. It failed with:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.
3. Caused by: jakarta.xml.ws.WebServiceException: Failed to access the WSDL at: https://PRIVATE_URL:PORT/?wsdl. It failed with:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.
4. Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
5. Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
6. Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I tried different versions to put keystore file and password, but they not helps. ChatGPT can't help me with this question).
I tried to add:
- Adding truest manager:
private PPPort configurePort(PPPort port) {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
String keystoreLocation = "C:\\Users\\USERNAME\\IdeaProjects\\parking-api\\src\\main\\resources\\keystore\\parking.jks";
try (FileInputStream keyStoreFile = new FileInputStream(keystoreLocation)) {
keyStore.load(keyStoreFile, "PASSWORD".toCharArray());
}
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "PASSWORD".toCharArray());
// Create a permissive TrustManager that accepts all certificates
TrustManager[] trustManagers = {new PermissiveTrustManager()};
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, null);
((BindingProvider) port).getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sslContext.getSocketFactory());
} catch (Exception e) {
e.printStackTrace(); // Handle exception appropriately in your code
}
return port;
}
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, null);
sslContext.getDefaultSSLParameters().setEndpointIdentificationAlgorithm("HTTPS");
2.
System.setProperty("javax.net.ssl.keyStore", "mypath/parking.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "PASSWORD");
How can I do my requests and where and how I need to put my file.jks and password?