How to enforce fetching of a p2 repository to use a specific java version? [message #1808542] |
Wed, 26 June 2019 14:17 |
Alexandra Tritean Messages: 20 Registered: February 2019 |
Junior Member |
|
|
Hello!
I'm trying to fetch the content of a p2 repository, using the equinox p2 API.
IMetadataRepositoryManager manager = (IMetadataRepositoryManager) agent
.getService(IMetadataRepositoryManager.SERVICE_NAME);
IArtifactRepositoryManager artifactManager = (IArtifactRepositoryManager) agent
.getService(IArtifactRepositoryManager.SERVICE_NAME);
manager.addRepository(new URI(repoURL));
artifactManager.addRepository(new URI(repoURL));
SubMonitor progressSubMonitor = SubMonitor.convert(progressMonitor, 100);
IMetadataRepository metadataRepo = manager.loadRepository(new URI(repoURL), progressSubMonitor.split(50));
When the loadRepository operation is executed, it always uses the java version which is configured in JAVA_HOME and therefore it searches for the certificate at that specific location. But if in the JAVA_HOME is configured a version for which the certificate was not installed, it gives the following error.
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:642)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:461)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:361)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:178)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1152)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1063)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:553)
at org.eclipse.ecf.provider.filetransfer.httpclient4.SNIAwareHttpClient$1.connectSocket(SNIAwareHttpClient.java:64)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:412)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:179)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:328)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:612)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:447)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:884)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.eclipse.ecf.provider.filetransfer.httpclient4.HttpClientFileSystemBrowser.runRequest(HttpClientFileSystemBrowser.java:263)
at org.eclipse.ecf.provider.filetransfer.browse.AbstractFileSystemBrowser$DirectoryJob.run(AbstractFileSystemBrowser.java:69)
... 1 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:290)
at java.base/sun.security.validator.Validator.validate(Validator.java:264)
at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:321)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:221)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:626)
... 22 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
... 28 more
What I'm trying to achieve, since I'm building an eclipse RCP product, it's to use the java version which is configured in Windows->Preferences->Installed Jres instead. I know how to obtain the java version from the preferences, but I couldn't find a way to enforce the fetching of a p2 repository to use that specific version of java or at least the certificate that it's found there.
What I tried so far, but without success:
- to modify programmatically the java_home and path environment variables, using a ProcessBuilder https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
- the dirty hack found at https://blog.sebastian-daschner.com/entries/changing_env_java
-the following piece of code
KeyStore ks = KeyStore.getInstance("JKS");
File file = new File(path_to_cacerts_file);
ks.load(new FileInputStream(file), "changeit".toCharArray()); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
trustManagerFactory.init(ks);
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, trustManagerFactory.getTrustManagers(), null);
Any other suggestions are more than welcomed. Thank you!
|
|
|
Re: How to enforce fetching of a p2 repository to use a specific java version? [message #1808991 is a reply to message #1808542] |
Fri, 05 July 2019 14:00 |
Eclipse User |
|
|
|
It sounds like this is all happening in your target instances (your applications launched for debugging from your Eclipse IDE).
If it's true that the JRE is using the JAVA_HOME to resolve its trusted certs (`lib/security/cacerts`), then you can override the JAVA_HOME setting in your Launch Configurations (Run > Run Configurations... or Run > Debug Configurations... and look at the Environment tab) and reference the associated JRE's directory by using the ee_home variable.
It's a bit more complicated if you're attempting to use a site protected by a self-signed certificate. You can configure the JRE from the command-line to use a different trust keystore using the javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword properties. Or you can modify the JRE's cacerts file -- this is not for the faint of heart, and is not a great solution for RCP apps as it needs to be done on every installation. It's likely easier to pay the money and use a properly certified cert on your server.
Just a note: your code loading the KeyStore instance won't work as you're populating a new instance of SSLContext, not a global instance. p2 will end up using its own SSLContext.
Brian.
|
|
|
Powered by
FUDForum. Page generated in 0.03621 seconds