SonarQube 9.9 with Jenkins Scan Successful but Quality Gate Fails

SonarQube 9.9
Jenkins

While we have had a tremendous amount of trouble getting SonarQube integrated into our Jenkins pipeline, we are close, but still having one issue:

The scan is successful:

INFO: ANALYSIS SUCCESSFUL, you can find the results at: https://sonarqube.xxx-inc.com/dashboard?id=SOME_ID&branch=dev
INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
INFO: More about the report processing at https://sonarqube.xxx-inc.com/api/ce/task?id=AYcGFpQIgL2x6i4EXxr9
INFO: Time spent writing ucfgs 29793ms
INFO: Analysis total time: 17:55.647 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 17:57.413s
INFO: Final Memory: 430M/1536M
INFO: ------------------------------------------------------------------------
The SonarScanner CLI has finished

However, the Quality Gate portion throws an exception I do not understand:

[Pipeline] }
[Pipeline] // withSonarQubeEnv
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Quality Gate)
[Pipeline] timeout
Timeout set to expire in 1 hr 10 min
[Pipeline] {
[Pipeline] withSonarQubeEnv
Injecting SonarQube environment variables using the configuration: Arcos-Sonarqube
[Pipeline] {
[Pipeline] waitForQualityGate
Checking status of SonarQube task 'AYcGFpQIgL2x6i4EXxr9' on server 'Arcos-Sonarqube'
[Pipeline] }
[Pipeline] // withSonarQubeEnv
[Pipeline] }
[Pipeline] // timeout
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
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:434)
Caused: sun.security.validator.ValidatorException: PKIX path building failed
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
	at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
	at java.base/sun.security.validator.Validator.validate(Validator.java:264)
	at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:222)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638)
Caused: 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:131)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:353)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:296)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:291)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:654)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:473)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:369)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:183)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1507)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1417)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:456)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:427)
	at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:268)
	at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:238)
	at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:149)
	at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:192)
	at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
	at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
	at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
	at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
	at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
	at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
	at okhttp3.RealCall.execute(RealCall.java:69)
	at org.sonarqube.ws.client.HttpConnector.doCall(HttpConnector.java:188)
	at org.sonarqube.ws.client.HttpConnector.get(HttpConnector.java:124)
	at org.sonarqube.ws.client.HttpConnector.call(HttpConnector.java:111)
	at hudson.plugins.sonar.client.HttpClient.getHttp(HttpClient.java:37)
	at hudson.plugins.sonar.client.WsClient.getCETask(WsClient.java:51)
	at org.sonarsource.scanner.jenkins.pipeline.WaitForQualityGateStep$Execution.checkTaskCompleted(WaitForQualityGateStep.java:238)
	at org.sonarsource.scanner.jenkins.pipeline.WaitForQualityGateStep$Execution.start(WaitForQualityGateStep.java:175)
	at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:322)
	at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:196)
	at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:124)
	at jdk.internal.reflect.GeneratedMethodAccessor6471.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1225)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:41)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:180)
	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:163)
	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:178)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:182)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:152)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:152)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:152)
	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
Caused: java.lang.IllegalStateException: Fail to request https://sonarqube.xxx-inc.com/api/ce/task?id=AYcGFpQIgL2x6i4EXxr9
	at org.sonarqube.ws.client.HttpConnector.doCall(HttpConnector.java:190)
	at org.sonarqube.ws.client.HttpConnector.get(HttpConnector.java:124)
	at org.sonarqube.ws.client.HttpConnector.call(HttpConnector.java:111)
	at hudson.plugins.sonar.client.HttpClient.getHttp(HttpClient.java:37)
	at hudson.plugins.sonar.client.WsClient.getCETask(WsClient.java:51)
	at org.sonarsource.scanner.jenkins.pipeline.WaitForQualityGateStep$Execution.checkTaskCompleted(WaitForQualityGateStep.java:238)
	at org.sonarsource.scanner.jenkins.pipeline.WaitForQualityGateStep$Execution.start(WaitForQualityGateStep.java:175)
	at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:322)
	at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:196)
	at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:124)
	at jdk.internal.reflect.GeneratedMethodAccessor6471.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1225)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:41)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:180)
	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:163)
	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:178)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:182)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:152)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:152)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:152)
	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
	at WorkflowScript.run(WorkflowScript:72)
	at ___cps.transform___(Native Method)
	at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:90)
	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:113)
	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:83)
	at jdk.internal.reflect.GeneratedMethodAccessor145.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
	at com.cloudbees.groovy.cps.impl.CollectionLiteralBlock$ContinuationImpl.dispatch(CollectionLiteralBlock.java:55)
	at com.cloudbees.groovy.cps.impl.CollectionLiteralBlock$ContinuationImpl.item(CollectionLiteralBlock.java:45)
	at jdk.internal.reflect.GeneratedMethodAccessor180.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
	at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
	at com.cloudbees.groovy.cps.Next.step(Next.java:83)
	at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:177)
	at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:166)
	at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:136)
	at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:275)
	at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:166)
	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:51)
	at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:187)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:420)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$400(CpsThreadGroup.java:95)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:330)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:294)
	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:139)
	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
	at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
[Bitbucket] Notifying commit build result
[Bitbucket] Build result notified
Finished: FAILURE

How could the software successfully connect to our SonarQube instance during analysis, but fail to connect to the SAME instance during Quality Gate?

Thanks for your time.

Tony

Hey there.

Is it possible that the SonarScanner is running on a different flavor/version/installation of Java than your Jenkins master/nodes? This would explain a discrepancy between the two, if the two installations trust different certs.

The former (the SonarScanner) a CLI tool, while the waitForQualityGate step is running on the Jenkins master/node.

You can check the Java install information for the SonarScanner at the beginning of the logs.

16:54:58.872 INFO: SonarScanner 4.8.0.2856
16:54:58.872 INFO: Java 17.0.6 Homebrew (64-bit)
16:54:58.872 INFO: Mac OS X 13.2.1 aarch64

You’ll have to consult your Jenkins admins on what version of Java is being used to run Jenkins itself (and any build agents)

1 Like

Jenkins: 11.0.17
SonarQube: 17.0.6

INFO: SonarScanner 4.8.0.2856
INFO: Java 11.0.17 Oracle Corporation (64-bit)
INFO: Windows Server 2016 10.0 amd64

If I am processing this correctly, our Jenkins server and Build server (on which SonarScanner is running) are the same server.

I am really not understanding where waitForQualityGate is checking CERTs?

I am trying to determine what process (and where this process lives) is making the connection attempt. This is the exception:

Caused: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

The connection address is as follows:

Caused: java.lang.IllegalStateException: Fail to request https://sonarqube.xxx-inc.com/api/ce/task?id=AYcKqIWZgL2x6i4EXxsg

What is perplexing is the base URL is the same one used for sending the analysis in the previous step, so how can it not connect or find a CERT?

We are really struggling with this one?

Hi,

the error clearly indicates that a Java with missing certs is involved.
You may post the relevant parts of your Jenkinsfile, the Sonarqube analysis and the part using the waitForQualityGate() step with the sensitive parts (credentialid …) redacted.

Gilbert

Jenkins file:

pipeline {
    agent {
        node {
            label 'windows'
        }
    }
    
    stages {
        stage('Clean Workspace') {
            steps {
                step([$class: 'WsCleanup'])
            }
        }
        stage('Git Clone') {
            steps {
                script {
                    if ((env.BRANCH_NAME == 'prod') || (env.BRANCH_NAME == 'qa') || (env.BRANCH_NAME == 'alpha') || (env.BRANCH_NAME == 'dev') || (env.BRANCH_NAME.startsWith('bugfix/')) || (env.BRANCH_NAME.startsWith('hotfix/')) || (env.BRANCH_NAME.startsWith('feature/'))) {
                        git branch: "${BRANCH_NAME}", credentialsId: "CREDENTIALS", url: "https://git.repo"
                    }
                    else {
                        checkout([
                            $class: 'GitSCM', 
                            branches: [[name: 'refs/tags/${BRANCH_NAME}']], 
                            extensions: [], 
                            userRemoteConfigs: [[
                                credentialsId: 'CREDENTIALS', 
                                url: 'https://git.repo']]
                        ])
                    }
                }
            }
        }
        stage('Nuget Restore') {
            steps {
                powershell "C:\\nuget\\nuget\\nuget.exe restore Product.sln -Verbosity quiet"
            }
        }
        stage('SonarQube Analysis') {
            environment {
              msbuildHome = tool 'MSBuild 16.10'
              scannerHome = tool 'SonarScanner for MSBuild for Product'
            }
        
            steps {
              withSonarQubeEnv('A-Sonarqube') {
                bat "\"${scannerHome}\\SonarScanner.MSBuild.exe\" begin /k:\"VALUE\""
                powershell('''
                        Write-Host "Starting Product.Web Build"
                        $env:PATH = "$env:PATH;C:\\Program Files\\nodejs;C:\\Users\\sa_jenkins\\AppData\\Roaming\\npm"
                        "appSettings.config", "connectionStrings.config", "qciFramework.config" | ForEach-Object {
                            Copy-Item $env:WORKSPACE\\Product.Web\\ConfigTemplates\\$_ $env:WORKSPACE\\Product.Web\\Config -Recurse -Force
                        }
                    ''')
                bat "\"${msbuildHome}\\MSBuild.exe\" Product.Web\\Product.Web.csproj /p:DeployOnBuild=true /p:PublishProfile=Debug.pubxml /p:Configuration=Debug /p:Platform=AnyCPU /p:VisualStudioVersion=16.0 /p:NoWarn=1591 /t:Clean /t:Rebuild /p:CurrentDirectory=%~dp0\\ -v:quiet"
                
                powershell('''
                        Write-Host "Starting Product.Web Angular Build"
                        # Angular Build
                        cd $env:WORKSPACE\\Product.Web
                        ng build Feature1 --output-path="..\\Product.Web.Deploy\\Publish Debug\\Feature1" --configuration production
                        ng build Feature2 --output-path="..\\Product.Web.Deploy\\Publish Debug\\Feature2" --configuration production
                    ''')
                    
                bat "\"${scannerHome}\\SonarScanner.MSBuild.exe\" end"                              
              } 
            }
        }

        stage ("Quality Gate") {
            steps {
                timeout(time: 70, unit: 'MINUTES') {
                    withSonarQubeEnv('A-Sonarqube') { waitForQualityGate abortPipeline: true }
                }
            }
        }
    }
}

Hi,

i believe the problem is , you’ve nested the waitForQualityGate() step inside
withSonarQubeEnv(...) { ... } but this is wrong.
Only the Sonar analysis itself has to run inside withSonarQubeEnv

here is a snippet from one of our .Net builds, they use the scripted syntax and called the analysis
stage = build, the waitforquality stage = sonarqube

stage('build') {
    withEnv(['JAVA_HOME=/etc/alternatives/java_sdk_11_openjdk']) {
    withSonarQubeEnv('xxx') {
        def dotnet = tool name: 'dotnet-core-6.0', type: 'msbuild'
        def sonar_scanner = tool name: 'sonar-scanner-msbuild-5', type: 'hudson.plugins.sonar.MsBuildSQRunnerInstallation'
        
        dir ("${props['startupProjectDir']}") {
            //################ Sonar begin ################
            shell "\"${dotnet}/dotnet\" \"${sonar_scanner}/SonarScanner.MSBuild.dll\" begin /k:${props['sonarProjectKey']} /v:${sonarVersion}"
            
            //################ Build start ################
            shell("\"${dotnet}/dotnet\" publish ${props['startupProject']} -p:Version=${version} --configuration Release --output publish")
            //################ Sonar end ################
            shell "\"${dotnet}/dotnet\" \"${sonar_scanner}/SonarScanner.MSBuild.dll\" end"
        }
    }}
}
stage('sonarqube') {
    //################ Sonar Quality Gate ################
    timeout(time: 5, unit: 'MINUTES') {
        waitForQualityGate abortPipeline: true
    }
}

The waitForQualityGate() step needs no Sonarqube credentials like the Sonar scanner, as
it works the other way around. After CE has finished the background task the Sonarqube server sends a json payload to all configured recipients, see https://yoursonarhost/admin/webhooks
At this page you may also control whether delivery for the configured webhook is/was successful.
Then the Jenkins waitForQualityGate() pipeline step consumes the payload and breaks the build if Quality gate FAILED.

Please try

  • Remove the nesting from waitForQualityGate step, as mentioned above , also time = 70 is too much, we use only 10mins even for very large projects

  • Check the webhook delivery status on Sonarqube server

  • i also recommend to use a custom log recorder for Sonarqube in Jenkins with
    configuration logger hudson.plugins.sonar, hudson.tools, org.sonarsource

You’ll see if errrors occure and if webhooks are received, i.e. with a name like ‘SonarQube’ for the
log recorder => https://yourjenkinshost/manage/log/SonarQube/

Finally i guess the SSLHandshakeException stems from:
somehow the Sonar analysis stage runs with another java as the waitForQualityGate inside withSonarQubeEnv but if you remove the nesting it may work as expected.

Gilbert

2 Likes

Thank you so much GIlbert.

We updated our Jenkins file:

        stage ("Quality Gate") {
            steps {
                timeout(time: 5, unit: 'MINUTES') {
                    waitForQualityGate abortPipeline: true 
                }
            }
        }

Similar result:

INFO: ANALYSIS SUCCESSFUL, you can find the results at: https://sonarqube.xxx-inc.com/dashboard?id=SOME_ID&branch=dev
INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
INFO: More about the report processing at https://sonarqube.xxx-inc.com/api/ce/task?id=AYcUPDk7gL2x6i4EXxs-
INFO: Time spent writing ucfgs 9426ms
INFO: Analysis total time: 10:43.722 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 10:45.445s
INFO: Final Memory: 427M/1548M
INFO: ------------------------------------------------------------------------
The SonarScanner CLI has finished
11:28:43.283  Post-processing succeeded.
[Pipeline] }
[Pipeline] // withSonarQubeEnv
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Quality Gate)
[Pipeline] timeout
Timeout set to expire in 5 min 0 sec
[Pipeline] {
[Pipeline] waitForQualityGate
Checking status of SonarQube task 'AYcUPDk7gL2x6i4EXxs-' on server 'Arcos-Sonarqube'
[Pipeline] }
[Pipeline] // timeout
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
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:434)
Caused: sun.security.validator.ValidatorException: PKIX path building failed
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
	at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
	at java.base/sun.security.validator.Validator.validate(Validator.java:264)
	at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:222)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638)
Caused: 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:131)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:353)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:296)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:291)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:654)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:473)
	at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:369)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:183)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1507)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1417)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:456)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:427)
	at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:268)
	at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:238)
	at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:149)
	at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:192)
	at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
	at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
	at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
	at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
	at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
	at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
	at okhttp3.RealCall.execute(RealCall.java:69)
	at org.sonarqube.ws.client.HttpConnector.doCall(HttpConnector.java:188)
	at org.sonarqube.ws.client.HttpConnector.get(HttpConnector.java:124)
	at org.sonarqube.ws.client.HttpConnector.call(HttpConnector.java:111)
	at hudson.plugins.sonar.client.HttpClient.getHttp(HttpClient.java:37)
	at hudson.plugins.sonar.client.WsClient.getCETask(WsClient.java:51)
	at org.sonarsource.scanner.jenkins.pipeline.WaitForQualityGateStep$Execution.checkTaskCompleted(WaitForQualityGateStep.java:238)
	at org.sonarsource.scanner.jenkins.pipeline.WaitForQualityGateStep$Execution.start(WaitForQualityGateStep.java:175)
	at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:322)
	at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:196)
	at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:124)
	at jdk.internal.reflect.GeneratedMethodAccessor6471.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1225)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:41)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:180)
	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:163)
	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:178)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:182)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:152)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:152)
	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
Caused: java.lang.IllegalStateException: Fail to request https://sonarqube.xxx-inc.com/api/ce/task?id=AYcUPDk7gL2x6i4EXxs-
	at org.sonarqube.ws.client.HttpConnector.doCall(HttpConnector.java:190)
	at org.sonarqube.ws.client.HttpConnector.get(HttpConnector.java:124)
	at org.sonarqube.ws.client.HttpConnector.call(HttpConnector.java:111)
	at hudson.plugins.sonar.client.HttpClient.getHttp(HttpClient.java:37)
	at hudson.plugins.sonar.client.WsClient.getCETask(WsClient.java:51)
	at org.sonarsource.scanner.jenkins.pipeline.WaitForQualityGateStep$Execution.checkTaskCompleted(WaitForQualityGateStep.java:238)
	at org.sonarsource.scanner.jenkins.pipeline.WaitForQualityGateStep$Execution.start(WaitForQualityGateStep.java:175)
	at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:322)
	at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:196)
	at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:124)
	at jdk.internal.reflect.GeneratedMethodAccessor6471.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1225)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:41)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:180)
	at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:163)
	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:178)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:182)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:152)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:152)
	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
	at WorkflowScript.run(WorkflowScript:71)
	at ___cps.transform___(Native Method)
	at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:90)
	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:113)
	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:83)
	at jdk.internal.reflect.GeneratedMethodAccessor145.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
	at com.cloudbees.groovy.cps.impl.CollectionLiteralBlock$ContinuationImpl.dispatch(CollectionLiteralBlock.java:55)
	at com.cloudbees.groovy.cps.impl.CollectionLiteralBlock$ContinuationImpl.item(CollectionLiteralBlock.java:45)
	at jdk.internal.reflect.GeneratedMethodAccessor180.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
	at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
	at com.cloudbees.groovy.cps.Next.step(Next.java:83)
	at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:177)
	at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:166)
	at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:136)
	at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:275)
	at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:166)
	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:51)
	at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:187)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:420)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$400(CpsThreadGroup.java:95)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:330)
	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:294)
	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:139)
	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
	at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
[Bitbucket] Notifying commit build result
[Bitbucket] Build result notified
Finished: FAILURE

Could these processes possibly be using different versions of Java? I currently have the CERT needed for version 11 of Java on the Jenkins/Build server.

You posted the relevant parts of your pipeline already and there was nothing suspicious beside the
nesting.

Yes, it seems there are differrent version of Java involved.
After the scanner has finished, the submission of the analysis report to the Sonarqube server works,
no connection problems - this java version has all certs.

That’s not completely correct, as the waitForQualityGate() step initially opens a connection to Sonarqube server, asking for the status of the analysisid - has the background already finished, what’s the result of the quality gate ?

With a successful connection, there are different scenarios like

The background task is processed almost immediately, doesn’t take much time

Checking status of SonarQube task 'xxxxxxxxxxx' on server 'xxxxxxx'
SonarQube task 'xxxxxxxxxxx' status is 'SUCCESS'
SonarQube task 'xxxxxxxxxxx' completed. Quality gate is 'OK'

The background task is already in work

Checking status of SonarQube task 'xxxxxxxxxxx' on server 'xxxxxxx'
SonarQube task 'xxxxxxxxxxx' status is 'IN_PROGRESS'
SonarQube task 'xxxxxxxxxxx' status is 'SUCCESS'
SonarQube task 'xxxxxxxxxxx' completed. Quality gate is 'OK'

The background task is in the queue, waiting to be processed

Checking status of SonarQube task 'xxxxxxxxxxx' on server 'xxxxxxx'
SonarQube task 'xxxxxxxxxxx' status is 'PENDING'
SonarQube task 'xxxxxxxxxxx' status is 'SUCCESS'
SonarQube task 'xxxxxxxxxxx' completed. Quality gate is 'OK'

When in progress or pending for a specific time, the waitForQualityGate() step creates a listener
waiting for the payload with the matching analysisid of the Sonarqube server webhook.

But the initial connection already fails in your pipeline because of missing certs.

Did you already try to move the waitForQualityGate() step in the
stage('SonarQube Analysis') { ... } scope, then it should use the same java version !?

Thank you Gilbert…Honestly, SonarQube should be ashamed of the nonsense people have to go through to get this working.

Anyway,

Updated Jenkins file:

        stage('SonarQube Analysis') {
            environment {
              msbuildHome = tool 'MSBuild 16.10'
              scannerHome = tool 'SonarScanner for MSBuild for Product'
            }
        
            steps {
              withSonarQubeEnv('Arcos-Sonarqube') {
                bat "\"${scannerHome}\\SonarScanner.MSBuild.exe\" begin /k:\"KEY\""
                powershell('''
                        Write-Host "Starting Product.Web Build"
                        $env:PATH = "$env:PATH;C:\\Program Files\\nodejs;C:\\Users\\sa_jenkins\\AppData\\Roaming\\npm"
                        "appSettings.config", "connectionStrings.config", "qciFramework.config" | ForEach-Object {
                            Copy-Item $env:WORKSPACE\\Product.Web\\ConfigTemplates\\$_ $env:WORKSPACE\\Product.Web\\Config -Recurse -Force
                        }
                    ''')
                bat "\"${msbuildHome}\\MSBuild.exe\" Product.Web\\Product.Web.csproj /p:DeployOnBuild=true /p:PublishProfile=Debug.pubxml /p:Configuration=Debug /p:Platform=AnyCPU /p:VisualStudioVersion=16.0 /p:NoWarn=1591 /t:Clean /t:Rebuild /p:CurrentDirectory=%~dp0\\ -v:quiet"
                
                powershell('''
                        Write-Host "Starting Product.Web Angular Build"
                        # Angular Build
                        cd $env:WORKSPACE\\Product.Web
                        ng build Something1 --output-path="..\\Product.Web.Deploy\\Publish Debug\\Something1" --configuration production
                        ng build Something2 --output-path="..\\Product.Web.Deploy\\Publish Debug\\Something2" --configuration production
                    ''')
                    
                bat "\"${scannerHome}\\SonarScanner.MSBuild.exe\" end"   
                timeout(time: 5, unit: 'MINUTES') {
                    waitForQualityGate abortPipeline: true 
                }               
              } 
            }
        }
    }
}

Result:

INFO: ANALYSIS SUCCESSFUL, you can find the results at: https://sonarqube.arcos-inc.com/dashboard?id=ARA_arcos_rosterapps_new_AYYX6upmHZetriXfK502&branch=dev
INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
INFO: More about the report processing at https://sonarqube.arcos-inc.com/api/ce/task?id=AYcjhMCjgL2x6i4EXxtH
INFO: Time spent writing ucfgs 5596ms
INFO: Analysis total time: 10:45.128 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 10:46.834s
INFO: Final Memory: 427M/1520M
INFO: ------------------------------------------------------------------------
The SonarScanner CLI has finished
10:42:16.344  Post-processing succeeded.
[Pipeline] timeout
Timeout set to expire in 5 min 0 sec
[Pipeline] {
[Pipeline] waitForQualityGate
[Pipeline] }
[Pipeline] // timeout
[Pipeline] }
[Pipeline] // withSonarQubeEnv
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
java.lang.IllegalStateException: No previous SonarQube analysis found on this pipeline execution. Please use the 'withSonarQubeEnv' wrapper to run your analysis.

Then tried this:

        stage('SonarQube Analysis') {
            environment {
              msbuildHome = tool 'MSBuild 16.10'
              scannerHome = tool 'SonarScanner for MSBuild for Product'
            }
        
            steps {
              withSonarQubeEnv('Arcos-Sonarqube') {
                bat "\"${scannerHome}\\SonarScanner.MSBuild.exe\" begin /k:\"KEY\""
                powershell('''
                        Write-Host "Starting Product.Web Build"
                        $env:PATH = "$env:PATH;C:\\Program Files\\nodejs;C:\\Users\\sa_jenkins\\AppData\\Roaming\\npm"
                        "appSettings.config", "connectionStrings.config", "qciFramework.config" | ForEach-Object {
                            Copy-Item $env:WORKSPACE\\Product.Web\\ConfigTemplates\\$_ $env:WORKSPACE\\Product.Web\\Config -Recurse -Force
                        }
                    ''')
                bat "\"${msbuildHome}\\MSBuild.exe\" Product.Web\\Product.Web.csproj /p:DeployOnBuild=true /p:PublishProfile=Debug.pubxml /p:Configuration=Debug /p:Platform=AnyCPU /p:VisualStudioVersion=16.0 /p:NoWarn=1591 /t:Clean /t:Rebuild /p:CurrentDirectory=%~dp0\\ -v:quiet"
                
                powershell('''
                        Write-Host "Starting Product.Web Angular Build"
                        # Angular Build
                        cd $env:WORKSPACE\\Product.Web
                        ng build EnhancedVacationBidding --output-path="..\\Product.Web.Deploy\\Publish Debug\\EnhancedVacationBidding" --configuration production
                        ng build Something2 --output-path="..\\Product.Web.Deploy\\Publish Debug\\Something2" --configuration production
                    ''')
                    
                bat "\"${scannerHome}\\SonarScanner.MSBuild.exe\" end"                
              }
            
              timeout(time: 5, unit: 'MINUTES') {
                withSonarQubeEnv('Arcos-Sonarqube') { waitForQualityGate abortPipeline: true } 
              }               
            }
        }
    }
}

Back to CERT error:

INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 10:52.398s
INFO: Final Memory: 427M/1508M
INFO: ------------------------------------------------------------------------
The SonarScanner CLI has finished
11:24:00.871  Post-processing succeeded.
[Pipeline] }
[Pipeline] // withSonarQubeEnv
[Pipeline] timeout
Timeout set to expire in 5 min 0 sec
[Pipeline] {
[Pipeline] withSonarQubeEnv
Injecting SonarQube environment variables using the configuration: Arcos-Sonarqube
[Pipeline] {
[Pipeline] waitForQualityGate
Checking status of SonarQube task 'AYcjqvuFgL2x6i4EXxtK' on server 'Arcos-Sonarqube'
[Pipeline] }
[Pipeline] // withSonarQubeEnv
[Pipeline] }
[Pipeline] // timeout
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

I’m really no .Net or MSBuild expert and i remember it was a bit tricky for us to find the right syntax for the Jenkinsfile, as there are different flavours - we use the sonar-scanner-msbuild-5.x.x.x-netcoreapp and have finally been able to solve it after a few attempts.

Your first try
java.lang.IllegalStateException: No previous SonarQube analysis found on this pipeline execution. Please use the 'withSonarQubeEnv' wrapper to run your analysis.

I see the scanner cli call with begin and end, but somehow the pipeline believes there was no scan.
Either the syntax is wrong or maybe the scanner report is not generated at the right place ?

Your second try, the same SunCertPathBuilderException again.

You may try to add a java that has the certs (%JAVA_HOME%\lib\security\cacerts)
GitHub - kaikramer/keystore-explorer: KeyStore Explorer is a free GUI replacement for the Java command-line utilities keytool and jarsigner. is a great tool for checking or use the keytool command

something like

environment {
  msbuildHome = tool 'MSBuild 16.10'
  scannerHome = tool 'SonarScanner for MSBuild for Product'
  JAVA_HOME = tool 'some.openjdk-11 or 17'
  PATH = "$JAVA_HOME\bin;${env.PATH}"
}

Thanks Gilbert. I added the CERT to all 3 versions of Java on the server and still the same issue. Next I will try your suggestion regarding the environment.

Thanks again for your continued help.

Th environment idea did not work either :pensive:

hmm, with the environment block at the start of the pipeline, the scan itself and the waitForQualityGate() step should use the same java !?

Which flavor of the .Net scanners do you use, see SonarScanner for .NET ?
From the Sonar CLI scanner i know there’s a version with a builtin JRE, and if the builtin JRE has the certs it works, but otherwise Java ssl connection fail.
But i don’t see such a version for .Net and you also mentioned you’ve added the certs to all Jenkins Java tool configurations and the default Java Jenkins runs on - yet the error is clearly about missing certs.

With our sonar-scanner-msbuild-5.x-netcoreapp we did only the normal Jenkins tool configuration,
nothing special. The tricky part was to find the right syntax for the Jenkinsfile.

Did you create a custom logger for Sonarqube in Jenkins and is there anything suspicious in the logs
of the Sonarqube log recorder or the general Jenkins log ?
Did you check the webhook delivery status in Sonarqube server ?
With https:// you have to use a reverse proxy - i.e. Apache, nginx, IIS. Anything in the reverse proxy logs ?

Otherwise i’ve run out of ideas :frowning_face:

Hi Gilbert,

Thanks again for all of your help. No matter what we do, we cannot get this to work. Currently, I am just thinking of writing my own script to perform this function.

Tony

Hey @Tony-Arcos

If I can suggest one more troubleshooting step, it would be to execute a tool like SSLPoke from your Jenkins master / agent, making sure the same Java version is used that is running Jenkins.

This would help isolate the issue from being something related to the Jenkins Extension, versus an issue that any Java process would have connecting to your SonarQube server if orchestrated by Jenkins.

Hi Colin,

I ran SSLPoke with our SonarQube URL for all 3 versions of Java on the server - and they all connected without issue.

My last hope is we rebooted Jenkins last night, as perhaps some of my changes would not take affect until after a reboot.

Thanks for the response.

Tony

Nothing worked, so we gave up on the Quality Gate stage for now - very disappointing.