Giter VIP home page Giter VIP logo

jenkinsci / pull-request-monitoring-plugin Goto Github PK

View Code? Open in Web Editor NEW
9.0 3.0 5.0 100.16 MB

Jenkins plugin to monitor pull requests with customizable dashboard. You can also provide a view for your plugin that other developers can use in their dashboard.

Home Page: https://plugins.jenkins.io/pull-request-monitoring/

License: MIT License

Java 68.79% CSS 7.69% JavaScript 23.51%
jenkins-plugin jenkins monitoring pull-requests pull-request dashboard metrics monitor ui view

pull-request-monitoring-plugin's Introduction

Gitter GitHub GitHub pull requests Open GitHub issues GitHub Workflow Status (branch) Build Status Contributions Jenkins Plugins Jenkins Plugin installs codecov Codacy Badge


Logo

Pull Request Monitoring

Jenkins plugin to monitor pull requests with a customizable dashboard.
Explore the docs »

Report Bug · Request Feature

At the Jenkins UX SIG Meeting on 28. April 2021, there was a live demo of the first beta version (1.0.3-beta).

Table of Contents

  1. About The Project
  2. Getting Started
  3. Usage
  4. Available Portlets
  5. Demo
  6. Roadmap
  7. Contributing
  8. License
  9. Credits
  10. Contact

About The Project

Many software teams have changed their development processes to lightweight pull requests. Changes to the software are packed into such a pull request, which is then manually reviewed and also automatically built in the CI/CD server. In Jenkins, however, these pull requests are not "first-class citizens"; the results of a pull request are currently simulated via branches.

For developers, this representation is insufficient: instead of having Git diffs, tests, static analysis, etc. as an overview in the overall project, a filtered representation of these results on the changes actually made would be much more helpful.

This plugin offers a possibility to display and aggregate the results (in the form of individual views) of a pull request in a configurable dashboard. Views can only be accessed or displayed if the corresponding plugin fulfils certain requirements and already provides a view.

Built With

Getting Started

Prerequisites

Currently, only multibranch pipelines projects are supported to use this plugin. Therefore, you have to install the corresponding Jenkins plugin Multibranch: Pipeline and connect to own of your SCM Repositories to use the Pull Request Monitoring Jenkins plugin.

Provide a portlet

This plugin relies on other plugins to provide a view that aggregates and provides delta metrics for a pull request.

The code behind

The MonitorPortlet class defines the base class for each portlet that is to be displayed. In order to register the portlet for the plugin, a factory class is required, which must be provided with the annotation @Extension. The factory has to extend the MonitorPortletFactory abstract class, receives the current Run<?,?>, delivers a set of MonitorPortlets and defines a displayedName, which appears as optgroup in the dashboard in the dropdown list of all available portlets and their corresponding factory.

Add portlet

One Instance Of One Portlet

Normally, one plugin delivers one portlet. A minimal example could look as follows:

/**
 *  An example Monitor Portlet implementation with one portlet delivered by factory.
 */
public class DemoPortlet extends MonitorPortlet {
    private final Run<?, ?> build;

    /**
     * Create a new {@link DemoPortlet}.
     *
     * @param run
     *          the {@link Run}
     */
    public DemoPortlet(Run<?, ?> run) {
        this.build = run;
    }

    /**
     * Defines the title of portlet. It will be shown in the 
     * upper left corner of the portlet.
     *
     * @return
     *          the title as string.
     */
    @Override
    public String getTitle() {
        return "Demo Portlet";
    }

    /**
     * Defines the id for the portlet.
     *
     * @return
     *          the id.
     */
    @Override
    public String getId() {
        return "demo-portlet-id";
    }

    /**
     * Defines whether the portlet is shown per default in the user dashboard or not.
     * 
     * @return
     *          true if portlet should be shown, false else.
     */
    @Override
    public boolean isDefault() {
        return true;
    }
    
    /**
     * Defines the preferred width of the portlet. It's 
     * possible to override the default width by user.
     *
     * @return
     *          the width as int. (range from 100 to 1000)
     */
    @Override
    public int getPreferredWidth() {
        return 300;
    }

    /**
     * Defines the preferred height of the portlet. It's 
     * possible to override the default height by user.
     *
     * @return
     *          the height as int. (range from 100 to 1000)
     */
    @Override
    public int getPreferredHeight() {
        return 200;
    }

    /**
     * Defines the icon, which will be shown in the dropdown of 
     * all available portlets in the dashboard.
     *
     * @return
     *          the icon url as {@link java.util.Optional} of string, or an
     *          empty Optional, if a default icon should be added.
     */
    @Override
    public Optional<String> getIconUrl() {
        return Optional.of("</path-to-icon/icon.png>");
    }

    /**
     * Defines a link to a detail view, if its needed. Links the title
     * of the portlet to this url.
     *
     * @return
     *          {@link java.util.Optional} of the url, or an empty Optional,
     *          if no link should be provided by portlet.
     */
    @Override
    public Optional<String> getDetailViewUrl() {
        return Optional.of("<link-to-detail-view>");
    }

    /**
     * Creates a new {@link ExamplePortletFactory}.
     */
    @Extension
    public static class ExamplePortletFactory extends MonitorPortletFactory {
        @Override
        public Collection<MonitorPortlet> getPortlets(Run<?, ?> build) {
            return Collections.singleton(new DemoPortlet(build));
        }

        @Override
        public String getDisplayName() {
            return "Demo Portlet Factory";
        }
    }
}

Null Check for used actions

Since an empty dashboard is always added by default, it is possible that the method getPortlets(Run) will be called (e.g. open the dashboard of actual run) even though the corresponding run may not be finished. It is possible that actions have not yet been added to the run. It is therefore advisable to perform a null check on the actions of the run required by your portlet and return an empty list if necessary. (Example: code-coverage-api)

Multiple Instances Of One Portlet

The factory can also deliver several portlets of one class.

⚠️ Unique portlet ID:

The id must be unique. Please make sure that the id is related to the plugin so that there are no conflicts with other plugins. It is recommended to use the artifact id of the plugin or parts of it as prefix. If several portlets of the same class are created in the factory, it must be ensured that the ID is always unique for each portlet!

Here is an example of a factory that delivers two instances of a class:

/**
 * An example Monitor Portlet implementation with multiple portlets delivered by factory.
 */
public class DemoPortlet extends MonitorPortlet {
    private final Run<?, ?> run;
    private final String id;

    /**
     * Create a new {@link DemoPortlet}.
     *
     * @param run
     *          the {@link Run}
     * @param id
     *          the id.
     */
    public DemoPortlet(Run<?, ?> run, String id) {
        this.run = run;
        this.id = id;
    }

    @Override
    public String getTitle() {
        return "Demo Portlet " + getId();
    }

    @Override
    public String getId() {
        return id;
    }
    
    // other interface methods, see example above. 
    
    /**
     * Creates a new {@link ExamplePortletFactory}.
     */
    @Extension
    public static class ExamplePortletFactory extends MonitorPortletFactory {
        @Override
        public Collection<MonitorPortlet> getPortlets(Run<?, ?> build) {
            List<MonitorPortlet> portlets = new ArrayList<>();
            portlets.add(new DemoPortlet(build, "example-portlet-first"));
            portlets.add(new DemoPortlet(build, "example-portlet-second"));
            return monitors;
        }

        @Override
        public String getDisplayName() {
            return "Demo Portlet Factory";
        }
    }
}

The corresponding jelly file

Each portlet have to have a corresponding monitor.jelly file, which is responsible for the content of the plugins portlet delivered on the dashboard later. Therefore you have to create a new monitor.jelly file in the directory, which corresponds to the MonitorView class.

Example: The code behind is defined in src/main/java/io/jenkins/plugins/sample/DemoPortlet.java. The related sources (e.g. the monitor.jelly file) have to be defined in src/main/resources/io/jenkins/plugins/sample/DemoPortlet/monitory.jelly.

Now the portlet, which can be added later in the dashboard, can be filled individually. Of course, all obligatory functions of the Jelly files, such as JEXL calls, can be used. To do this, please refer to the official Jenkins documentation. A minimal example:

<?jelly escape-by-default='true'?>

<j:jelly xmlns:j="jelly:core">

    <p>Portlet content goes here!</p>

</j:jelly>

Usage Of Monitoring

Introduction

This plugin offers the following monitoring options:

Project Level

The monitoring on the project level is very basic and is limited to the summary of all open pull requests of the associated SCM. From here, you can access the corresponding monitoring dashboards, view the pull request information and navigate to the respective pull request in the repository.

Example Overview

Build Level

The monitoring at build level is the core of the plugin and offers the possibility to observe various delta metrics of a pull request provided by other portlets.

The dashboard is only added to those builds whose branch SCMHead of the parent job is an instance of ChangeRequestSCMHead. Otherwise, the corresponding MonitoringBuildAction will not be added and no dashboard will be provided for the build. For more details, please refer to the logging in the console output of the respective build.

Persistence & Permissions

The configuration, which is set via the Jenkinsfile or via the Dahsboard, is saved per user as a hudson.model.UserProperty and is browser independent. The plugin therefore requires that you are logged in and have the appropriate permissions. Otherwise, the action will not be displayed!

Default Dashboard

💡 Reference build search:

The git-forensics-api plugin allows to find a reference build for a pull request build. It is highly recommended using this plugin and to search for the reference build in the pipeline with discoverGitReferenceBuild() (or configure it via the Jenkins UI). For more information please visit the plugin page or have a look into an example pipeline.

To start with the default dashboard, you have to do nothing. If the run is part of a pull request, the corresponding MonitoringDefaultAction is automatically added to the Run and later available on the sidepanel of the run.

Now you are able to add portlets to the dashboard, change the layout or remove it again. The configuration will be saved for each project per user. If you want to save the configuration permanently, it is best to copy and paste it into the Jenkinsfile and overwrite the default dashboard and use a custom dashboard.

🧩 Default Portlets for Dashboard:

Since version 1.7.0, the portlets can decide whether they should be displayed by default or not in the user dashboard. So when you start with the default dashboard, all available portlets that are marked as default are automatically loaded into your dashboard.

Custom Dashboard

The other way to add a dashboard is to set the configuration of the dashboard via the Jenkinsfile to pre-define your dashboard. It is recommended to add the monitoring at the end of your pipeline, to ensure that other plugins such as static code analysis are performed first and that the actions that may be required are available:

stage ('Pull Request Monitoring - Dashboard Configuration') {
    monitoring (
        '''
        [
            {
                // Minimal usage of one portlet 
                "id": "portlet-id"
            }, 
            {   
                // Feel free to customize the portlets
                "id": "another-portlet-id",
                "width": 200,
                "height": 100,
                "color": "#FF5733"
            }
        ]
        '''
 )
}

Therefore, the monitoring stage expects a JSONArray of JSONObjects. To validate your configured json, you could use a JSON Schema Validator and the corresponding JSON schema used for this plugin. Each JSONObject needs at least the id of the portlet to add. For width and height, the default preferredWidth and preferredHeight of the MonitorPortlet is used. #000000 is used as default color.

The dashboard will be added to your Run and the pre-defined monitor should be available.

🔥 Duplicate or missing portlet IDs:

Duplicates will be removed as well as missing portlet ids. The Run will not fail unless the provided json does not follow the scheme!

If there are unavailable portlets (e.g. corresponding plugin is uninstalled) in stored user configuration, and the dashboard tries to load this portlet, an alert will be displayed with the ids of the unavailable portlets:

Unavailable Portlet

Settings

Under the settings of each Run, various things can be tracked:

  1. Are there changes of the pre-defined dashboard since the last build?

  2. The current activated source of configuration (Default or User-specific).

    • Default means Jenkinsfile if monitoring is provided, else all available default portlets.

    • User-specific means the local changes of dashboard.

  3. Configuration synced with the default one? If needed, you can synchronize the actual configuration with the default one.

  4. The actual configuration

  5. The default configuration.

Prioritising of the different configurations:

By default, all available default portlets are loaded. If there is a user-specific configuration for one dashboard (per project), the user-specific configuration will be loaded per default. If you sync the current configuration with the default one, the user-specific configuration for current dashboard will be deleted, and the default configuration will be loaded. Deletion cannot be undone!

Settings

Available Portlets

If your plugin is not in the list but provides a portlet, feel free to add it with a pull request!

Plugin Number of delivered portlets Portlet ID Default?
Pull Request Monitoring Pull Request Monitoring 2 first-demo-portlet
second-demo-portlet
Warnings Next Generation Warnings Next Generation ≥ 100 depends on tool
Code Coverage API Code Coverage API 1 code-coverage

Demo

For the demo (v1.3.0-beta) I added two recorder (javadoc and pmd) of the Warnings Ng Plugin to the pipeline and added both as default portlet to the monitoring. After the run finished, the portlets will be shown in the dashboard.

Demo

Roadmap

See the open issues for a list of proposed features (and known issues).

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License. See LICENSE for more information.

Credits

The following icons, which are used by this plugin

made by Freepik from Flaticon.

Contact

Simon Symhoven - [email protected]

Project Link: https://github.com/jenkinsci/pull-request-monitoring-plugin

pull-request-monitoring-plugin's People

Contributors

codacy-badger avatar dependabot[bot] avatar gitter-badger avatar simonsymhoven avatar uhafner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

pull-request-monitoring-plugin's Issues

Default portelts

Dependencies

Nothing

Feature Request

With version 1.6.0 the api method isDefault() is introduced. Therefor a plugin can decide, whether it should be displayed by default or not. in the user dashboard. This flag is still ignored. The functionality has to be implemented.

Make portlets configurable inside of dashboard

Dependencies

Nothing

Feature Request

At this moment (v 1.3.1), you are able to edit existing portlets in the dashboard, but therefore you have to delete the corresponding portly and add it back again with desired changes. To avoid this, it would be much more better, if existing portlets could be edited without having to delete and re-add them.

Please bundle external resources with this plugin

Version report

Jenkins and plugins versions report:

Jenkins: 2.289.1
OS: Linux - 4.19.0-17-amd64
---
jdk-tool:1.5
apache-httpcomponents-client-4-api:4.5.13-1.0
git-server:1.9
email-ext:2.83
jira:3.3
docker-commons:1.17
blueocean-events:1.24.7
ansicolor:1.0.0
blueocean-github-pipeline:1.24.7
oauth-credentials:0.4
pipeline-stage-step:2.5
popper2-api:2.5.4-2
blueocean-autofavorite:1.2.4
cobertura:1.16
credentials:2.5
echarts-api:5.1.2-2
pipeline-stage-view:2.19
nodelabelparameter:1.8.1
pipeline-rest-api:2.19
blueocean-commons:1.24.7
git-forensics:1.0.0
jquery3-api:3.6.0-1
jaxb:2.3.0.1
data-tables-api:1.10.25-1
jackson2-api:2.12.3
htmlpublisher:1.25
checks-api:1.7.0
junit:1.50
github:1.33.1
momentjs:1.1.1
blueocean-config:1.24.7
pipeline-stage-tags-metadata:1.8.5
docker-plugin:1.2.2
pipeline-github-lib:1.0
mapdb-api:1.0.9.0
pipeline-graph-analysis:1.11
jsch:0.1.55.2
pipeline-build-step:2.13
workflow-step-api:2.23
blueocean-i18n:1.24.7
ssh-credentials:1.19
material-theme:0.3.3
select2-api:4.0.13-5
jquery:1.12.4-1
caffeine-api:2.9.1-23.v51c4e2c879c8
workflow-multibranch:2.26
plain-credentials:1.7
dashboard-view:2.17
ldap:2.7
favorite:2.3.3
publish-over:0.22
multibranch-build-strategy-extension:1.0.10
pipeline-input-step:2.12
forensics-api:1.1.0
basic-branch-build-strategies:1.3.2
pipeline-model-api:1.8.5
snakeyaml-api:1.29.1
theme-manager:0.6
credentials-binding:1.25
python:1.3
naginator:1.18.1
warnings-ng:9.2.0
blueocean-pipeline-scm-api:1.24.7
resource-disposer:0.16
workflow-support:3.8
bootstrap4-api:4.6.0-3
matrix-project:1.19
lockable-resources:2.11
blueocean-pipeline-editor:1.24.7
analysis-model-api:10.2.5
dependency-check-jenkins-plugin:5.1.1
google-oauth-plugin:1.0.6
ws-cleanup:0.39
workflow-aggregator:2.6
config-file-provider:3.8.0
jjwt-api:0.11.2-9.c8b45b8bb173
blueocean-rest-impl:1.24.7
configuration-as-code:1.51
plugin-util-api:2.3.0
solarized-theme:0.1
blueocean-personalization:1.24.7
jenkins-design-language:1.24.7
cloudbees-bitbucket-branch-source:2.9.9
blueocean-dashboard:1.24.7
blueocean-jira:1.24.7
docker-java-api:3.1.5.2
workflow-durable-task-step:2.39
pipeline-model-extensions:1.8.5
github-branch-source:2.11.1
antisamy-markup-formatter:2.1
handy-uri-templates-2-api:2.1.8-1.0
versioncolumn:2.1
branch-api:2.6.4
jquery-detached:1.2.1
variant:1.4
pipeline-model-definition:1.8.5
blueocean-web:1.24.7
cloudbees-folder:6.15
pull-request-monitoring:1.7.5
mailer:1.34
durable-task:1.37
dark-theme:0.0.12
scm-api:2.6.4
pubsub-light:1.16
structs:1.23
blueocean-jwt:1.24.7
build-timeout:1.20
timestamper:1.13
script-security:1.77
command-launcher:1.6
blueocean-display-url:2.4.1
google-metadata-plugin:0.3.1
okhttp-api:3.14.9
workflow-job:2.41
authentication-tokens:1.4
git:4.7.2
blueocean-pipeline-api-impl:1.24.7
docker-workflow:1.26
sshd:3.0.3
handlebars:3.0.8
bootstrap5-api:5.0.1-2
bouncycastle-api:2.20
github-api:1.123
popper-api:1.16.1-2
blueocean-core-js:1.24.7
ssh-agent:1.23
blueocean-bitbucket-pipeline:1.24.7
muuri-api:0.9.4-2
sse-gateway:1.24
pam-auth:1.6
copyartifact:1.46.1
workflow-basic-steps:2.23
pipeline-milestone-step:1.3.2
envinject-api:1.7
git-client:3.7.2
token-macro:2.15
google-storage-plugin:1.5.4
external-monitor-job:1.7
workflow-scm-step:2.13
ace-editor:1.1
workflow-api:2.45
monitoring:1.87.0
display-url-api:2.3.5
workflow-cps-global-lib:2.20
workflow-cps:2.92
blueocean-rest:1.24.7
jobConfigHistory:2.27
ssh-slaves:1.32.0
code-coverage-api:1.4.0
blueocean:1.24.7
matrix-auth:2.6.7
blueocean-git-pipeline:1.24.7
envinject:2.4.0
extended-read-permission:3.2
font-awesome-api:5.15.3-3
trilead-api:1.0.13
  • What Operating System are you using (both controller, and any agents involved in the problem)?
Jenkins server and client desktop: Devuan 3/Beowulf
Client browser: firefox-esr 78.11.0esr-1~deb10u1 (Package comes from Debian 10/Buster)

Reproduction steps

I have installed the latest version of pull-request-monitoring-plugin. I also have uBlock Origin installed in Firefox. When I visit the Pull Request Monitoring page for a specific PR build (eg. https://ci.example.com/job/Example/job/example/view/change-requests/job/PR-123/2/pull-request-monitoring/), it is reporting attempts to download external resources from www.jenkins.io and fonts.gstatic.com.

Results

Expected result:

I would like Jenkins to not fetch unnecessary resources from external third-party domains (ie. Google or jenkins.io). Any external resources (images, fonts, etc.) should be bundled in with the plugin so there are no UI errors when running Jenkins in a locked-down environment.

Actual result:

I can see two attempted requests for: https://www.jenkins.io/images/logos/JCasC/JCasC.png
and one attempted request for: https://fonts.gstatic.com/s/materialicons/v29/2fcrYFNaTjcS6g4U3t-Y5ZjZjT5FdEJ140U2DJYC3mY.woff2

and JS console errors for:

Request to access cookie or storage on “https://www.jenkins.io/images/logos/JCasC/JCasC.png” was blocked because we are blocking all third-party storage access requests and content blocking is enabled.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://fonts.gstatic.com/s/materialicons/v29/2fcrYFNaTjcS6g4U3t-Y5ZjZjT5FdEJ140U2DJYC3mY.woff2. (Reason: CORS request did not succeed).

I can also see occasional random errors for downloading css resources in the Firefox web developer tools.
eg. https://ci.example.com/static/34ca5e6c/css/responsive-grid.css shows SSL_ERROR_INTERNAL_ERROR_ALERT in Firefox->Web Developer->Network->Security tab

NullPointerException in MonitorConfigurationProperty.forCurrentUser

Version report

Jenkins and plugins versions report:

Jenkins: 2.289.1
OS: Windows Server 2012 R2 - 6.3
---
ace-editor:1.1
analysis-model-api:10.2.5
antisamy-markup-formatter:2.1
apache-httpcomponents-client-4-api:4.5.13-1.0
atlassian-bitbucket-server-integration:2.1.3
authentication-tokens:1.4
authorize-project:1.4.0
basic-branch-build-strategies:1.3.2
bitbucket-server-checks:1.0-SNAPSHOT (private-eedd5336-kalle)
bootstrap4-api:4.6.0-3
bootstrap5-api:5.0.1-2
bouncycastle-api:2.20
branch-api:2.6.4
build-monitor-plugin:1.12+build.201809061734
buildtriggerbadge:2.10
caffeine-api:2.9.1-23.v51c4e2c879c8
checks-api:1.7.0
cloudbees-bitbucket-branch-source:2.9.9
cloudbees-disk-usage-simple:0.10
cloudbees-folder:6.15
command-launcher:1.6
compress-artifacts:1.10
configuration-as-code:1.51
copyartifact:1.46.1
credentials-binding:1.25
credentials:2.5
crowd2:2.0.2
custom-tools-plugin:0.8
data-tables-api:1.10.25-1
display-url-api:2.3.5
dtkit-api:3.0.0
durable-task:1.37
echarts-api:5.1.2-2
extended-choice-parameter:0.82
extended-read-permission:3.2
folder-auth:1.3
font-awesome-api:5.15.3-3
forensics-api:1.1.0
git-client:3.7.2
git-forensics:1.0.0
git-server:1.9
git:4.7.2
github-api:1.123
github-branch-source:2.11.1
github:1.33.1
handlebars:3.0.8
handy-uri-templates-2-api:2.1.8-1.0
hudson-wsclean-plugin:1.0.8
jackson2-api:2.12.3
jdk-tool:1.5
jira:3.3
jjwt-api:0.11.2-9.c8b45b8bb173
job-restrictions:0.8
jquery:1.12.4-1
jquery3-api:3.6.0-1
jsch:0.1.55.2
junit:1.50
lockable-resources:2.11
mailer:1.34
matrix-auth:2.6.7
matrix-project:1.19
momentjs:1.1.1
mstest:1.0.0
multi-branch-priority-sorter:1.0
next-build-number:1.6
nunit:0.27
Office-365-Connector:4.15.0
okhttp-api:3.14.9
pipeline-aggregator-view:1.11
pipeline-build-step:2.13
pipeline-graph-analysis:1.11
pipeline-input-step:2.12
pipeline-milestone-step:1.3.2
pipeline-model-api:1.8.5
pipeline-model-definition:1.8.5
pipeline-model-extensions:1.8.5
pipeline-rest-api:2.19
pipeline-stage-step:2.5
pipeline-stage-tags-metadata:1.8.5
pipeline-stage-view:2.19
pipeline-utility-steps:2.8.0
plain-credentials:1.7
plugin-util-api:2.3.0
popper-api:1.16.1-2
popper2-api:2.5.4-2
PrioritySorter:4.0.0
resource-disposer:0.16
role-strategy:3.1.1
scm-api:2.6.4
script-security:1.77
security-inspector:0.5
sidebar-link:1.12.0
sidebar-update-notification:1.1.0
skip-notifications-trait:1.0.5
snakeyaml-api:1.29.1
ssh-credentials:1.19
sshd:3.0.3
structs:1.23
timestamper:1.13
token-macro:2.15
trilead-api:1.0.13
violation-comments-to-stash:1.126
vstestrunner:1.0.8
warnings-ng:9.2.0
windows-slaves:1.8
workflow-aggregator:2.6
workflow-api:2.44
workflow-basic-steps:2.23
workflow-cps-global-lib:2.19
workflow-cps:2.92
workflow-durable-task-step:2.39
workflow-job:2.41
workflow-multibranch:2.24
workflow-scm-step:2.12
workflow-step-api:2.23
workflow-support:3.8
ws-cleanup:0.39
xunit:3.0.2
muuri-api:0.9.4-2
select2-api:4.0.13-5
pull-request-monitoring:1.7.3
  • What Operating System are you using (both controller, and any agents involved in the problem)?
Windows Server 2012 R2

Reproduction steps

  • Install this plugin for the first time in the Jenkins instance.
  • Navigate to the web page of a project that has pull requests.
  • Click the "Pull Request Monitoring" link. The "Pull Request Monitoring: Overview" page opens.
  • Click the "Go To Monitoring Dashboard" button of a pull request.

Results

Expected result:

Should show the monitoring dashboard.

Actual result:

A red-faced Jenkins says "Oops! A problem occurred while processing the request." The Jenkins log contains the following error.

kesäkuuta 15, 2021 7:20:17 IP. WARNING hudson.init.impl.InstallUncaughtExceptionHandler handleException

Caught unhandled exception with ID 18375f8e-2505-4d03-b1ca-b08c397c340c
java.lang.NullPointerException
	at java.util.Objects.requireNonNull(Objects.java:203)
	at java.util.Optional.<init>(Optional.java:96)
	at java.util.Optional.of(Optional.java:108)
	at io.jenkins.plugins.monitoring.MonitorConfigurationProperty.forCurrentUser(MonitorConfigurationProperty.java:106)
	at io.jenkins.plugins.monitoring.MonitoringDefaultAction.setDefaultMonitorConfiguration(MonitoringDefaultAction.java:202)
	at io.jenkins.plugins.monitoring.MonitoringDefaultAction.getTarget(MonitoringDefaultAction.java:374)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:721)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$9.dispatch(MetaClass.java:457)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$9.dispatch(MetaClass.java:457)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:281)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:281)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:281)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:694)
	at org.kohsuke.stapler.Stapler.service(Stapler.java:240)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:791)
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1626)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
	at jenkins.telemetry.impl.UserLanguages$AcceptLanguageFilter.doFilter(UserLanguages.java:129)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at jenkins.security.ResourceDomainFilter.doFilter(ResourceDomainFilter.java:76)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at com.atlassian.bitbucket.jenkins.internal.applink.oauth.serviceprovider.auth.OAuth1aRequestFilter.doFilter(OAuth1aRequestFilter.java:91)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at com.smartcodeltd.jenkinsci.plugin.assetbundler.filters.LessCSS.doFilter(LessCSS.java:47)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:157)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:159)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:92)
	at jenkins.security.AcegiSecurityExceptionFilter.doFilter(AcegiSecurityExceptionFilter.java:52)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:101)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:92)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:218)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:93)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
	at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:62)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:109)
	at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:168)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:51)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at jenkins.security.SuspiciousRequestFilter.doFilter(SuspiciousRequestFilter.java:36)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1435)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1350)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:279)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:383)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
	at java.lang.Thread.run(Thread.java:748)

URISyntaxException due to backslash on Windows

Version report

Jenkins and plugins versions report:

Jenkins: 2.289.1
OS: Windows Server 2012 R2 - 6.3
---
ace-editor:1.1
analysis-model-api:10.2.5
antisamy-markup-formatter:2.1
apache-httpcomponents-client-4-api:4.5.13-1.0
atlassian-bitbucket-server-integration:2.1.3
authentication-tokens:1.4
authorize-project:1.4.0
basic-branch-build-strategies:1.3.2
bitbucket-server-checks:1.0-SNAPSHOT (private-eedd5336-kalle)
bootstrap4-api:4.6.0-3
bootstrap5-api:5.0.1-2
bouncycastle-api:2.20
branch-api:2.6.4
build-monitor-plugin:1.12+build.201809061734
buildtriggerbadge:2.10
caffeine-api:2.9.1-23.v51c4e2c879c8
checks-api:1.7.0
cloudbees-bitbucket-branch-source:2.9.9
cloudbees-disk-usage-simple:0.10
cloudbees-folder:6.15
command-launcher:1.6
compress-artifacts:1.10
configuration-as-code:1.51
copyartifact:1.46.1
credentials-binding:1.25
credentials:2.5
crowd2:2.0.2
custom-tools-plugin:0.8
data-tables-api:1.10.25-1
display-url-api:2.3.5
dtkit-api:3.0.0
durable-task:1.37
echarts-api:5.1.2-2
extended-choice-parameter:0.82
extended-read-permission:3.2
folder-auth:1.3
font-awesome-api:5.15.3-3
forensics-api:1.1.0
git-client:3.7.2
git-forensics:1.0.0
git-server:1.9
git:4.7.2
github-api:1.123
github-branch-source:2.11.1
github:1.33.1
handlebars:3.0.8
handy-uri-templates-2-api:2.1.8-1.0
hudson-wsclean-plugin:1.0.8
jackson2-api:2.12.3
jdk-tool:1.5
jira:3.3
jjwt-api:0.11.2-9.c8b45b8bb173
job-restrictions:0.8
jquery:1.12.4-1
jquery3-api:3.6.0-1
jsch:0.1.55.2
junit:1.50
lockable-resources:2.11
mailer:1.34
matrix-auth:2.6.7
matrix-project:1.19
momentjs:1.1.1
mstest:1.0.0
multi-branch-priority-sorter:1.0
next-build-number:1.6
nunit:0.27
Office-365-Connector:4.15.0
okhttp-api:3.14.9
pipeline-aggregator-view:1.11
pipeline-build-step:2.13
pipeline-graph-analysis:1.11
pipeline-input-step:2.12
pipeline-milestone-step:1.3.2
pipeline-model-api:1.8.5
pipeline-model-definition:1.8.5
pipeline-model-extensions:1.8.5
pipeline-rest-api:2.19
pipeline-stage-step:2.5
pipeline-stage-tags-metadata:1.8.5
pipeline-stage-view:2.19
pipeline-utility-steps:2.8.0
plain-credentials:1.7
plugin-util-api:2.3.0
popper-api:1.16.1-2
popper2-api:2.5.4-2
PrioritySorter:4.0.0
resource-disposer:0.16
role-strategy:3.1.1
scm-api:2.6.4
script-security:1.77
security-inspector:0.5
sidebar-link:1.12.0
sidebar-update-notification:1.1.0
skip-notifications-trait:1.0.5
snakeyaml-api:1.29.1
ssh-credentials:1.19
sshd:3.0.3
structs:1.23
timestamper:1.13
token-macro:2.15
trilead-api:1.0.13
violation-comments-to-stash:1.126
vstestrunner:1.0.8
warnings-ng:9.2.0
windows-slaves:1.8
workflow-aggregator:2.6
workflow-api:2.44
workflow-basic-steps:2.23
workflow-cps-global-lib:2.19
workflow-cps:2.92
workflow-durable-task-step:2.39
workflow-job:2.41
workflow-multibranch:2.24
workflow-scm-step:2.12
workflow-step-api:2.23
workflow-support:3.8
ws-cleanup:0.39
xunit:3.0.2
muuri-api:0.9.4-2
select2-api:4.0.13-5
pull-request-monitoring:1.7.3
  • What Operating System are you using (both controller, and any agents involved in the problem)?
Windows Server 2012 R2

Reproduction steps

Not sure. I guess it will happen with any pull request if the Jenkins controller is on Windows.

Results

Expected result:

The "Pull Request Monitoring '#11'" link on a pull-request page leads somewhere, and there are no errors in the log.

Actual result:

Clicking the "Pull Request Monitoring '#11'" link on a pull-request page does nothing, and there is an error in the log:

Failed to parse URL for io.jenkins.plugins.monitoring.MonitoringWorkflowJobAction@51c16297: java.net.URISyntaxException: Illegal character in path at index 2: 11\pull-request-monitoring

NoSuchMethodError because of j2html version mismatch

Version report

Jenkins and plugins versions report:

Jenkins: 2.289.1
OS: Windows Server 2012 R2 - 6.3
---
ace-editor:1.1
analysis-model-api:10.2.5
antisamy-markup-formatter:2.1
apache-httpcomponents-client-4-api:4.5.13-1.0
atlassian-bitbucket-server-integration:2.1.3
authentication-tokens:1.4
authorize-project:1.4.0
basic-branch-build-strategies:1.3.2
bitbucket-server-checks:1.0-SNAPSHOT (private-eedd5336-kalle)
bootstrap4-api:4.6.0-3
bootstrap5-api:5.0.1-2
bouncycastle-api:2.20
branch-api:2.6.4
build-monitor-plugin:1.12+build.201809061734
buildtriggerbadge:2.10
caffeine-api:2.9.1-23.v51c4e2c879c8
checks-api:1.7.0
cloudbees-bitbucket-branch-source:2.9.9
cloudbees-disk-usage-simple:0.10
cloudbees-folder:6.15
command-launcher:1.6
compress-artifacts:1.10
configuration-as-code:1.51
copyartifact:1.46.1
credentials-binding:1.25
credentials:2.5
crowd2:2.0.2
custom-tools-plugin:0.8
data-tables-api:1.10.25-1
display-url-api:2.3.5
dtkit-api:3.0.0
durable-task:1.37
echarts-api:5.1.2-2
extended-choice-parameter:0.82
extended-read-permission:3.2
folder-auth:1.3
font-awesome-api:5.15.3-3
forensics-api:1.1.0
git-client:3.7.2
git-forensics:1.0.0
git-server:1.9
git:4.7.2
github-api:1.123
github-branch-source:2.11.1
github:1.33.1
handlebars:3.0.8
handy-uri-templates-2-api:2.1.8-1.0
hudson-wsclean-plugin:1.0.8
jackson2-api:2.12.3
jdk-tool:1.5
jira:3.3
jjwt-api:0.11.2-9.c8b45b8bb173
job-restrictions:0.8
jquery:1.12.4-1
jquery3-api:3.6.0-1
jsch:0.1.55.2
junit:1.50
lockable-resources:2.11
mailer:1.34
matrix-auth:2.6.7
matrix-project:1.19
momentjs:1.1.1
mstest:1.0.0
multi-branch-priority-sorter:1.0
muuri-api:0.9.4-2
next-build-number:1.6
nunit:0.27
Office-365-Connector:4.15.0
okhttp-api:3.14.9
pipeline-aggregator-view:1.11
pipeline-build-step:2.13
pipeline-graph-analysis:1.11
pipeline-input-step:2.12
pipeline-milestone-step:1.3.2
pipeline-model-api:1.8.5
pipeline-model-definition:1.8.5
pipeline-model-extensions:1.8.5
pipeline-rest-api:2.19
pipeline-stage-step:2.5
pipeline-stage-tags-metadata:1.8.5
pipeline-stage-view:2.19
pipeline-utility-steps:2.8.0
plain-credentials:1.7
plugin-util-api:2.3.0
popper-api:1.16.1-2
popper2-api:2.5.4-2
PrioritySorter:4.0.0
pull-request-monitoring:1.7.4
resource-disposer:0.16
role-strategy:3.1.1
scm-api:2.6.4
script-security:1.77
security-inspector:0.5
select2-api:4.0.13-5
sidebar-link:1.12.0
sidebar-update-notification:1.1.0
skip-notifications-trait:1.0.5
snakeyaml-api:1.29.1
ssh-credentials:1.19
sshd:3.0.3
structs:1.23
timestamper:1.13
token-macro:2.15
trilead-api:1.0.13
violation-comments-to-stash:1.126
vstestrunner:1.0.8
warnings-ng:9.2.0
windows-slaves:1.8
workflow-aggregator:2.6
workflow-api:2.44
workflow-basic-steps:2.23
workflow-cps-global-lib:2.19
workflow-cps:2.92
workflow-durable-task-step:2.39
workflow-job:2.41
workflow-multibranch:2.24
workflow-scm-step:2.12
workflow-step-api:2.23
workflow-support:3.8
ws-cleanup:0.39
xunit:3.0.2
  • What Operating System are you using (both controller, and any agents involved in the problem)?
Windows Server 2012 R2

Java is AdoptOpenJDK 25.282-b08 (HotSpot).

Reproduction steps

  • Open a pull-request page.
  • Click the "Pull Request Monitoring '#11'" link.

Results

Expected result:

No errors.

Actual result:

Oops!
A problem occurred while processing the request.

Logging ID=59d6b378-acb2-4b48-a08a-1c41cbcd47a6

The log shows:

kesäkuuta 16, 2021 12:08:02 IP. WARNING hudson.init.impl.InstallUncaughtExceptionHandler handleException

Caught unhandled exception with ID 59d6b378-acb2-4b48-a08a-1c41cbcd47a6
org.apache.commons.jelly.JellyTagException: jar:file:/C:/Program%20Files%20(x86)/Jenkins/plugins/pull-request-monitoring/WEB-INF/lib/pull-request-monitoring.jar!/metadata/metadata.jelly:25:73: <j:out> j2html.TagCreator.span(Ljava/lang/String;)Lj2html/tags/specialized/SpanTag;
	at org.apache.commons.jelly.impl.TagScript.handleException(TagScript.java:745)
	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:289)
	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:100)
	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:100)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:100)
	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:100)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
	at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99)
	at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91)
	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.apache.commons.jelly.tags.core.CoreTagLibrary$1.run(CoreTagLibrary.java:98)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
	at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99)
	at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91)
	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:100)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:100)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:100)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:100)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99)
	at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91)
	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
	at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
	at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120)
	at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
	at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
	at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:95)
	at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:64)
	at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:54)
	at org.kohsuke.stapler.jelly.ScriptInvoker.execute(ScriptInvoker.java:56)
	at org.kohsuke.stapler.jelly.ScriptInvoker.execute(ScriptInvoker.java:43)
	at org.kohsuke.stapler.Facet.handleIndexRequest(Facet.java:284)
	at org.kohsuke.stapler.jelly.JellyFacet.handleIndexRequest(JellyFacet.java:100)
	at org.kohsuke.stapler.IndexViewDispatcher.dispatch(IndexViewDispatcher.java:32)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$9.dispatch(MetaClass.java:457)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$9.dispatch(MetaClass.java:457)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:281)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:281)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:281)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:694)
	at org.kohsuke.stapler.Stapler.service(Stapler.java:240)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:791)
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1626)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
	at jenkins.security.ResourceDomainFilter.doFilter(ResourceDomainFilter.java:76)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at jenkins.telemetry.impl.UserLanguages$AcceptLanguageFilter.doFilter(UserLanguages.java:129)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at com.atlassian.bitbucket.jenkins.internal.applink.oauth.serviceprovider.auth.OAuth1aRequestFilter.doFilter(OAuth1aRequestFilter.java:91)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at com.smartcodeltd.jenkinsci.plugin.assetbundler.filters.LessCSS.doFilter(LessCSS.java:47)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:157)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:159)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:92)
	at jenkins.security.AcegiSecurityExceptionFilter.doFilter(AcegiSecurityExceptionFilter.java:52)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:101)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:92)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:218)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:93)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
	at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:62)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:109)
	at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:168)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:51)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at jenkins.security.SuspiciousRequestFilter.doFilter(SuspiciousRequestFilter.java:36)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1435)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1350)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:279)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:383)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoSuchMethodError: j2html.TagCreator.span(Ljava/lang/String;)Lj2html/tags/specialized/SpanTag;
	at io.jenkins.plugins.monitoring.MonitoringDefaultAction.getPullRequestMetadataTitle(MonitoringDefaultAction.java:139)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.commons.jexl.util.introspection.UberspectImpl$VelMethodImpl.invoke(UberspectImpl.java:258)
	at org.apache.commons.jexl.parser.ASTMethod.execute(ASTMethod.java:104)
	at org.apache.commons.jexl.parser.ASTReference.execute(ASTReference.java:83)
	at org.apache.commons.jexl.parser.ASTReference.value(ASTReference.java:57)
	at org.apache.commons.jexl.parser.ASTReferenceExpression.value(ASTReferenceExpression.java:51)
	at org.apache.commons.jexl.ExpressionImpl.evaluate(ExpressionImpl.java:80)
	at hudson.ExpressionFactory2$JexlExpression.evaluate(ExpressionFactory2.java:74)
	at org.apache.commons.jelly.expression.ExpressionSupport.evaluateRecurse(ExpressionSupport.java:61)
	at org.apache.commons.jelly.expression.ExpressionSupport.evaluateAsString(ExpressionSupport.java:46)
	at org.apache.commons.jelly.tags.core.ExprTag.doTag(ExprTag.java:42)
	at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
	... 158 more
Caused: javax.servlet.ServletException
	at org.kohsuke.stapler.Facet.handleIndexRequest(Facet.java:287)
	at org.kohsuke.stapler.jelly.JellyFacet.handleIndexRequest(JellyFacet.java:100)
	at org.kohsuke.stapler.IndexViewDispatcher.dispatch(IndexViewDispatcher.java:32)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$9.dispatch(MetaClass.java:457)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$9.dispatch(MetaClass.java:457)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:281)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:281)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:281)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:766)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:898)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:694)
	at org.kohsuke.stapler.Stapler.service(Stapler.java:240)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:791)
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1626)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
	at jenkins.security.ResourceDomainFilter.doFilter(ResourceDomainFilter.java:76)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at jenkins.telemetry.impl.UserLanguages$AcceptLanguageFilter.doFilter(UserLanguages.java:129)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at com.atlassian.bitbucket.jenkins.internal.applink.oauth.serviceprovider.auth.OAuth1aRequestFilter.doFilter(OAuth1aRequestFilter.java:91)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at com.smartcodeltd.jenkinsci.plugin.assetbundler.filters.LessCSS.doFilter(LessCSS.java:47)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:151)
	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:157)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:159)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:92)
	at jenkins.security.AcegiSecurityExceptionFilter.doFilter(AcegiSecurityExceptionFilter.java:52)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:101)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:92)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:218)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:93)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
	at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:62)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:97)
	at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:109)
	at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:168)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:51)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:82)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at jenkins.security.SuspiciousRequestFilter.doFilter(SuspiciousRequestFilter.java:36)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1435)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1350)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:279)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:383)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
	at java.lang.Thread.run(Thread.java:748)

Analysis

In j2html-1.5.0, TagCreator.span(String) returns SpanTag (source). In j2html-1.4.0, TagCreator.span(String) returns ContainerTag (source). This was changed in tipsy/j2html#156.

Versions of j2html in installed plugins:

  • plugins\analysis-model-api\WEB-INF\lib\j2html-1.4.0.jar
  • plugins\font-awesome-api\WEB-INF\lib\j2html-1.4.0.jar
  • plugins\git-forensics\WEB-INF\lib\j2html-1.4.0.jar
  • plugins\pull-request-monitoring\WEB-INF\lib\j2html-1.5.0.jar
  • plugins\warnings\WEB-INF\lib\j2html-1.3.0.jar
  • plugins\warnings-ng\WEB-INF\lib\j2html-1.4.0.jar

It seems MonitoringDefaultAction.getPullRequestMetadataTitle tries to call TagCreator.span(String) returning SpanTag as in j2html-1.5.0, which is bundled with pull-request-monitoring, but j2html-1.4.0 was loaded instead. Perhaps j2html-1.4.0 came from font-awesome-api, on which pull-request-monitoring depends.

Please see Dependencies and Class Loading, especially the sections "Initiating vs. defining loaders" and "pluginFirstClassLoader and its discontents".

Json Configuration not well formatted and sorted

Version report

Jenkins and plugins versions report:

Jenkins: 2.249.1
OS: Mac OS X - 10.16
---
pull-request-monitoring:1.6.1-SNAPSHOT (private-fa99cbae-simonsymhoven)
jsch:0.1.55.2
echarts-api:5.1.0-2
structs:1.23
apache-httpcomponents-client-4-api:4.5.13-1.0
bootstrap5-api:5.0.1-1
mailer:1.34
git:4.6.0
bootstrap4-api:4.6.0-3
forensics-api:1.0.0
jquery3-api:3.6.0-1
command-launcher:1.2
workflow-api:2.42
workflow-job:2.40
analysis-model-api:10.2.5
ssh-credentials:1.18.1
github-branch-source:2.9.9
javadoc:1.6
jackson2-api:2.12.3
credentials:2.4.1
github:1.33.1
workflow-scm-step:2.12
pipeline-stage-step:2.5
antisamy-markup-formatter:2.1
pipeline-maven:3.10.0
bouncycastle-api:2.16.0
data-tables-api:1.10.23-3
checks-api:1.7.0
select2-api:4.0.13-4
plain-credentials:1.7
git-client:3.6.0
workflow-basic-steps:2.22
github-api:1.123
jaxb:2.3.0
maven-plugin:3.8
muuri-api:0.9.4-1
font-awesome-api:5.15.3-2
config-file-provider:3.8.0
token-macro:2.13
workflow-multibranch:2.24
script-security:1.77
snakeyaml-api:1.27.0
workflow-step-api:2.23
okhttp-api:3.14.9
popper2-api:2.5.4-1
plugin-util-api:2.2.0
workflow-cps:2.92
popper-api:1.16.1-2
workflow-durable-task-step:2.39
trilead-api:1.0.13
branch-api:2.6.2
jdk-tool:1.0
cloudbees-folder:6.15
h2-api:1.4.199
jjwt-api:0.11.2-9.c8b45b8bb173
git-forensics:1.0.0
durable-task:1.36
junit:1.49
caffeine-api:2.9.1-23.v51c4e2c879c8
scm-api:2.6.4
ace-editor:1.1
code-coverage-api:1.3.2
display-url-api:2.3.4
warnings-ng:9.1.0
workflow-support:3.8

Reproduction steps

  • Add portlets to the dashboard
  • Open the configuration panel

Results

Expected result:

  • the jsons (Default and custom) have the same order
  • the jsons are well formatted

Actual result:

  • the jsons aren't sorted
  • the json aren't formatted

NPE in some not supported projects

´´´
jenkins-controller_1 | java.lang.NullPointerException
jenkins-controller_1 | at io.jenkins.plugins.monitoring.util.PullRequestFinder.isPullRequest(PullRequestFinder.java:28)
jenkins-controller_1 | at io.jenkins.plugins.monitoring.MonitoringDefaultActionFactory.createFor(MonitoringDefaultActionFactory.java:36)
jenkins-controller_1 | at io.jenkins.plugins.monitoring.MonitoringDefaultActionFactory.createFor(MonitoringDefaultActionFactory.java:19)
jenkins-controller_1 | at hudson.model.Actionable.createFor(Actionable.java:114)
jenkins-controller_1 | at hudson.model.Actionable.getAllActions(Actionable.java:100)
jenkins-controller_1 | at hudson.model.Run.onLoad(Run.java:383)
jenkins-controller_1 | at hudson.model.RunMap.retrieve(RunMap.java:231)
jenkins-controller_1 | at hudson.model.RunMap.retrieve(RunMap.java:58)

´´´

Jenkins core is quite annoying with respect to null as return value. I think there need to be some guards that check for null.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.