Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Jira 10 + React + WRM: Cannot load 'entrypoint' from wr-defs.xml in simple plugin

DmSidorov
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
July 29, 2025

Hi, I'm migrating plugins to Jira 10.3.0 using React 18 and bundling via Webpack 5 with atlassian-webresource-webpack-plugin.

I have a plugin with the following setup:

  • Frontend entry: my-plugin (entry in webpack.config.js)

    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const WrmPlugin = require('atlassian-webresource-webpack-plugin');

    module.exports = {
    entry: {
    'my-plugin': './src/index.tsx',
    },
    output: {
    path: path.resolve(__dirname, '../backend/src/main/resources'),
    filename: 'js/[name].js',
    library: '[name]',
    libraryTarget: 'amd',
    publicPath: '',
    },
    resolve: {
    extensions: ['.tsx', '.ts', '.js'],
    },
    module: {
    rules: [
    {
    test: /\.(ts|tsx)$/,
    use: {
    loader: 'babel-loader',
    options: {
    presets: [
    '@babel/preset-env',
    '@babel/preset-typescript',
    '@babel/preset-react',
    ],
    },
    },
    exclude: /node_modules/,
    },
    {
    test: /\.css$/i,
    use: [MiniCssExtractPlugin.loader, 'css-loader'],
    },
    ],
    },
    externals: {
    react: 'jira/api/react-18',
    'react-dom': 'jira/api/react-dom-18',
    },
    optimization: {
    minimize: false,
    runtimeChunk: 'single'
    },
    plugins: [
    new WrmPlugin({
    pluginKey: 'com.example.my-jira-plugin-backend',
    xmlDescriptors: path.resolve(
    __dirname,
    '../backend/src/main/resources/META-INF/plugin-descriptors/wr-defs.xml'
    ),
    webResourceKey: 'entrypoint-my-plugin',
    providedDependencies: {
    react: {
    dependency: 'com.atlassian.plugins.jira-frontend-api:react-18',
    import: { amd: 'jira/api/react-18', var: 'React' },
    },
    'react-dom': {
    dependency: 'com.atlassian.plugins.jira-frontend-api:react-dom-18',
    import: { amd: 'jira/api/react-dom-18', var: 'ReactDOM' },
    },
    },
    }),
    new MiniCssExtractPlugin({
    filename: 'css/[name].css',
    }),
    ],
    };
  • Generated resources: js/my-plugin.js, css/my-plugin.css (visible inside the JAR under /js and /css)

  • Generated WR descriptor: wr-defs.xml is correctly placed under META-INF/plugin-descriptors/

    this is how it's generated:

    I don't understand where they came from split_my-plugin and transformation extension="soy"

    <bundles>
    <web-resource key="split_my-plugin">
    <transformation extension="js">
    <transformer key="jsI18n"/>
    </transformation>
    <dependency>com.atlassian.plugins.atlassian-plugins-webresource-plugin:context-path</dependency>
    <resource type="download" name="css/my-plugin.css" location="css/my-plugin.css"/>
    <resource type="download" name="js/my-plugin.js" location="js/my-plugin.js"/>
    </web-resource>
    <web-resource key="entrypoint-my-plugin">
    <transformation extension="js">
    <transformer key="jsI18n"/>
    </transformation>
    <transformation extension="soy">
    <transformer key="soyTransformer"/>
    <transformer key="jsI18n"/>
    </transformation>
    <dependency>com.example.my-jira-plugin-backend:common-runtime</dependency>
    <dependency>com.atlassian.plugins.atlassian-plugins-webresource-plugin:context-path</dependency>
    <dependency>com.example.my-jira-plugin-backend:split_my-plugin</dependency>
    </web-resource>
    <web-resource key="common-runtime">
    <transformation extension="js">
    <transformer key="jsI18n"/>
    </transformation>
    <dependency>com.atlassian.plugins.atlassian-plugins-webresource-plugin:context-path</dependency>
    <resource type="download" name="js/runtime.js" location="js/runtime.js"/>
    </web-resource>
    <web-resource key="assets-25934921-12b3-4c8c-934a-eb64dcc584cc">
    <transformation extension="js">
    <transformer key="jsI18n"/>
    </transformation>
    <transformation extension="soy">
    <transformer key="soyTransformer"/>
    <transformer key="jsI18n"/>
    </transformation>
    </web-resource>
    </bundles>
  • Servlet page renders a basic HTML that includes:

    package com.example.plugin;

    import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
    import com.atlassian.webresource.api.UrlMode;
    import com.atlassian.webresource.api.WebResourceManager;

    import javax.inject.Inject;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;

    public class MyReactPageServlet extends HttpServlet {

    private final WebResourceManager webResourceManager;

    @Inject
    public MyReactPageServlet(@ComponentImport WebResourceManager webResourceManager) {
    this.webResourceManager = webResourceManager;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    resp.setContentType("text/html;charset=utf-8");


    webResourceManager.requireResource("com.example.my-jira-plugin-backend:entrypoint-my-plugin");

    String html = """
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My React Page</title>
    %s
    </head>
    <body>
    <div id="my-plugin-container"></div>
    <script>
    WRM.require('wr!com.example.my-jira-plugin-backend:entrypoint-my-plugin').then(function() {
    require(['my-plugin'], function(mod) {
    if (mod?.default) {
    mod.default();
    } else {
    console.error('No default export in module');
    }
    });
    }).catch(function(err) {
    console.error('Failed to load web resources:', err);
    });
    </script>
    </body>
    </html>
    """.formatted(webResourceManager.getRequiredResources(UrlMode.RELATIVE));

    resp.getWriter().write(html);
    }
    }

In my atlasian-plugin.xml i connected my generated wr-defs.xml

<?xml version="1.0" encoding="UTF-8"?>
<atlassian-plugin key="com.example.my-jira-plugin-backend"
name="My Plugin"
plugins-version="2">

<plugin-info>
<description>My plugin description</description>
<version>1.0.0</version>
<vendor name="Example Company" url="https://example.com"/>
</plugin-info>


<web-resource-import key="wr-defs" file="META-INF/plugin-descriptors/wr-defs.xml"/>

<servlet name="My React Page Servlet"
key="my-react-page"
class="com.example.plugin.MyReactPageServlet">
<url-pattern>/my-react-page</url-pattern>
<load-on-startup>1</load-on-startup>
</servlet>

<rest key="my-rest" path="/myplugin" version="1.0">
<description>Provides REST endpoints for the plugin</description>
<package>com.example.plugin.api</package>
</rest>

</atlassian-plugin>

The assembly and installation of the plugin is successful, the only thing that confuses me is that there is a disabled mark opposite the wr-defs.

as a result, when I try to call my servlet, I get a 200 response from it and an error in the console:

Uncaught Error: undefined missing entrypoint-my-plugin.

Nothing else is downloaded in the network.

I've been struggling with the solution for several days now and would like to understand whether I'm thinking in the right direction or whether there is some other approach to writing jira 10 + react plugins without velosity and ajs.

And finally my pom file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.example</groupId>
<artifactId>my-jira-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<artifactId>my-jira-plugin-backend</artifactId>
<packaging>atlassian-plugin</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jira.version>10.3.0</jira.version>
<platform.version>8.0.3</platform.version>
<amps.version>8.2.0</amps.version>
<plugin.testrunner.version>2.0.2</plugin.testrunner.version>
<atlassian.spring.scanner.version>6.0.0</atlassian.spring.scanner.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.atlassian.platform.dependencies</groupId>
<artifactId>platform-public-api</artifactId>
<version>${platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<!-- Atlassian Dependencies -->

<dependency>
<groupId>com.atlassian.plugins</groupId>
<artifactId>atlassian-plugins-webresource-api</artifactId>
<version>8.0.0-m003</version>
<scope>provided</scope>
</dependency>




<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.soy</groupId>
<artifactId>soy-template-renderer-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.soy</groupId>
<artifactId>soy-template-renderer-plugin-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.audit</groupId>
<artifactId>atlassian-audit-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugins.rest</groupId>
<artifactId>atlassian-rest-v2-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.templaterenderer</groupId>
<artifactId>atlassian-template-renderer-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.cache</groupId>
<artifactId>atlassian-cache-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
<scope>provided</scope>
</dependency>


</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<encoding>${project.build.sourceEncoding}</encoding>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>jira-maven-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<configuration>
<productVersion>${jira.version}</productVersion>
<productDataVersion>${jira.version}</productDataVersion>
<instructions>
<Atlassian-Plugin-Key>${project.groupId}.${project.artifactId}</Atlassian-Plugin-Key>
<Export-Package>
com.example.plugin.api
</Export-Package>
<Spring-Context>*</Spring-Context>
<Import-Package>*</Import-Package>
</instructions>
</configuration>
</plugin>

<plugin>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<executions>
<execution>
<goals>
<goal>atlassian-spring-scanner</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<verbose>false</verbose>
</configuration>
</plugin>
</plugins>
</build>


<repositories>
<repository>
<id>atlassian-public</id>
<url>https://packages.atlassian.com/maven/repository/public</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>atlassian-public</id>
<url>https://packages.atlassian.com/maven/repository/public</url>
</pluginRepository>
</pluginRepositories>
</project>

 

 

 

 

 

1 answer

0 votes
Marc - Devoteam
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 29, 2025

HI @DmSidorov 

Welcome to the community.

Best is to ask this question in the Atlassian Developer Community

 

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
SERVER
VERSION
10.3
PRODUCT PLAN
STANDARD
TAGS
AUG Leaders

Atlassian Community Events