Preparing for Confluence 9.0 - EAP out now

@Kusal With confluence 9.0.1 (or any previous conf 9 rcs) the icon in a system.content.button web-item isn’t rendered or resolved properly.

It’s definition looks like that:

    <web-item key="..." name="..." section="system.content.button" weight="80">
        <link linkId="..." absolute="true"/>
        <label key="..."/>
        <icon height="16" width="16">
            <link>/download/resources/${app.key}/asdf.svg</link>
        </icon>
        <condition class="com.atlassian.confluence.plugin.descriptor.web.conditions.HasPageCondition"/>
    </web-item>

The confluence html then looks like that, with what looks like unresolved variables:

<img alt="..." src="$icon.url.getDisplayableUrl($request, $webInterfaceContext)" height="$icon.height" width="$icon.width" title="...">

In the confluence logs I see this on page load:

2024-08-08 12:09:20,044 WARN [http-nio-1990-exec-9 url: /confluence/pages/viewpage.action; user: admin] [velocity] log Invocation blocked as method is not allowlisted: com.atlassian.confluence.impl.plugin.web.readonly.ReadOnlyWebIcon#getUrl()
2024-08-08 12:09:20,045 WARN [http-nio-1990-exec-9 url: /confluence/pages/viewpage.action; user: admin] [velocity] log Invocation blocked as method is not allowlisted: com.atlassian.confluence.impl.plugin.web.readonly.ReadOnlyWebIcon#getHeight()
2024-08-08 12:09:20,045 WARN [http-nio-1990-exec-9 url: /confluence/pages/viewpage.action; user: admin] [velocity] log Invocation blocked as method is not allowlisted: com.atlassian.confluence.impl.plugin.web.readonly.ReadOnlyWebIcon#getWidth()

We are not including it as a dependency, only as like here - https://developer.atlassian.com/server/framework/atlassian-sdk/managing-dependencies/

Hi @PhilippSeeger

Thanks for reporting this - it will be rectified from Confluence 9.0.3 onwards

2 Likes

@Kusal Will this impact all sections?
I’m having the same problem when trying to add an icon to my web item in the system.header/left section for Confluence. However, I’m not seeing any warnings so far.

Hi everyone,

We are calling our REST endpoint which has the DTO with this annotations:

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
  @JsonSubTypes.Type(value = PageInstantiationDto.class, name = "page"),
  @JsonSubTypes.Type(value = SpaceInstantiationDto.class, name = "space")
})

But we are getting this kind of error:

Unrecognized field "type" (class eps.focuspro.tca.entities.InstantiationDto), not marked as ignorable (13 known properties: "topPageLabels", "sourcePageId", "jiraCreationType", "targetSpaceKey", "unselectedPages", "resolvePageTitles", "jumpIntoEdit", "creationType", "tagReplacements", "labels", "pagesToWatch", "targetPageId", "pageTitlePrefix"])
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 193] (through reference chain: eps.focuspro.tca.entities.InstantiationDto["type"])

Can someone help us because we’re stuck solving it.

Thanks.

4 Likes

Hi Atlassian Team,

I don’t want to create a new thread, but after the release of version 9.0.2 the confluence-space-ia artifact cannot be downloaded

import com.atlassian.confluence.plugins.ia.DisplayableSidebarLink;
import com.atlassian.confluence.plugins.ia.SidebarLinkCategory;
import com.atlassian.confluence.plugins.ia.service.SidebarLinkService;
[ERROR] dependency: com.atlassian.confluence.plugins:confluence-space-ia:jar:19.0.118 (provided)
[ERROR] 	com.atlassian.confluence.plugins:confluence-space-ia:jar:19.0.118 was not found in https://packages.atlassian.com/maven-atlassian-external/ during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of atlassian-packages-external has elapsed or updates are forced
[ERROR] 	com.atlassian.confluence.plugins:confluence-space-ia:jar:19.0.118 was not found in https://maven.atlassian.com/repository/public during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of atlassian-public has elapsed or updates are forced
[ERROR] 	com.atlassian.confluence.plugins:confluence-space-ia:jar:19.0.118 was not found in file:///Applications/Atlassian/atlassian-plugin-sdk/repository during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of atlassian-plugin-sdk has elapsed or updates are forced
[ERROR] 	com.atlassian.confluence.plugins:confluence-space-ia:jar:19.0.118 was not found in https://repo.maven.apache.org/maven2 during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of central has elapsed or updates are forced

pom.xml

        <dependency>
            <groupId>com.atlassian.confluence.plugins</groupId>
            <artifactId>confluence-space-ia</artifactId>
            <scope>provided</scope>
        </dependency>

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

Cheers
Adam

Hi @ShahrimanMohammad

Did you find a solution to your problem?
We are experiencing the same since Jira 10 EAP08

ping @RobinDelmas

Fabien

Hi @Kusal

After converting codehaus to fasterxml all annotation working properly in confluence 9 but in backward version confluence 8. I am getting below error.

org.codehaus.jackson.map.JsonMappingException: No serializer found for class “class name” and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: java.util.ArrayList[0])

I think confluence 8 internally initializing ObjectMapper using codehaus is there any way to resolved this like override initialize ObjectMapper using fasterxml.

2 Likes

I also converted from codehaus to fasterxml and it works fine in all supported versions of Confluence, as far as I know.

Which annotations are you using? This one, for example? … com.fasterxml.jackson.annotation.JsonProperty

Hi @turehoefner_appfire
Thanks for replay.
Yes we are using @JsonProperty annotation. @JsonIgnore working find but @JsonProperty not working. do you know any specific configuration for this annotation.

Hi @mihirvarsani
I don’t think we are doing anything special. We have some POJOs that use the fasterxml jackson annotations and they are used as arguments for requests to a REST endpoint. The REST endpoint was refactored to have a no-arg constructor for REST V2 compat.

I passed that app to someone else months ago but I have not heard anything about it breaking recently.

Here is what I have in pom.xml (using version 2.5.13)

 <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>
1 Like

Despite all the questions I posted on this forum and all the useful answers I got, I still do not fully understand how the dependencies are managed with Confluence 9.

TL;DR: If I depend on a service from another app (both are mine) that uses a type provided by a Confluence Plugin (BlueprintContext in my example), the class is loaded by two different class loaders and the service cannot be called. How can I resolve this issue?

This is my problem when I work with two apps (only an issue with Confluence 9).

  • One is providing services, the other is consuming it.
  • As long as all the classes in my API (parameter types, return types) are not part of another dependency (in my case com.atlassian.confluence.plugins:confluence-create-content-api) everything works fine.
  • But if there is such a type found in my API, I either get complaints at deploy time or at runtime that
    • there are two classes named BlueprintContext
    • there is no class with the name BlueprintContext (in case I do set the Confluence Content API to scope ‘provided’)

So this is my service interface that is implemented by a service in the same app. There are two methods. The execute() method can be called without issues, the transform() method has the type issue.

package com.example.lib.api;
 
import com.atlassian.confluence.plugins.createcontent.api.contextproviders.BlueprintContext;
 
public interface BlueprintContextTransformer {
  void execute();
 
  BlueprintContext transform(BlueprintContext context);
}

According to https://developer.atlassian.com/server/framework/atlassian-sdk/configuration-of-instructions-in-atlassian-plugins/ and https://developer.atlassian.com/server/framework/atlassian-sdk/spring-java-config-plugin-xml/ I should - as I understand this - not need to add any dependencies in the Import Instructions. But I assume it does not hurt and the errors the same.

Both apps declare this dependency:

<dependency>
  <groupId>com.atlassian.confluence.plugins</groupId>
  <artifactId>confluence-create-content-plugin</artifactId>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>com.atlassian.confluence.plugins</groupId>
  <artifactId>confluence-create-content-api</artifactId>
</dependency>

These are the instructions for the service provider, exporting the package containing the service interface and service implementation:

<instructions>
  <Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
 
  <Export-Package>
    com.example.lib.api
  </Export-Package>
 
  <Import-Package>
    org.springframework.osgi.*;resolution:="optional",
    org.eclipse.gemini.blueprint.*;resolution:="optional",
    com.atlassian.confluence.plugins.createcontent.api.*;resolution:="optional",
    *
  </Import-Package>
 
  <Spring-Context>*</Spring-Context>
</instructions>

The instructions for the service consumer:

<instructions>
  <Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
 
   <Import-Package>
     org.springframework.osgi.*;resolution:="optional",
     org.eclipse.gemini.blueprint.*;resolution:="optional",
     com.atlassian.confluence.plugins.createcontent.api.*;resolution:="optional",
     com.example.lib.api.*,
     *
   </Import-Package>
 
  <Spring-Context>*</Spring-Context>
</instructions>

I also tried to import com.atlassian.confluence.plugins.createcontent.api.contextproviders.* and usually prefer not using resolution optional (which should simplify the imports to a single ‘*’), but the results are basically the same.

Here is the error message:

confluence-1  | Uncaught exception b1a48162-5e75-4aa5-af14-91714d65c9fd thrown by REST service: loader constraint violation:
when resolving interface method
  'BlueprintContext BlueprintContextTransformer.transform(BlueprintContext)'
the class loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @43ceadd8 of the current class, com/example/plugins/tutorial/confluence/simplebp/MyContextProvider,
and the class loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @77e190f0 for the method's defining class, com/example/lib/api/BlueprintContextTransformer,
have different Class objects for the type com/atlassian/confluence/plugins/createcontent/api/contextproviders/BlueprintContext
used in the signature
  (com.example.plugins.tutorial.confluence.simplebp.MyContextProvider is in unnamed module of loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @43ceadd8,
     parent loader org.apache.catalina.loader.ParallelWebappClassLoader @452acb84;
   com.example.lib.api.BlueprintContextTransformer is in unnamed module of loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @77e190f0,
     parent loader org.apache.catalina.loader.ParallelWebappClassLoader @452acb84)
confluence-1  |  -- url: /rest/create-dialog/1.0/content-blueprint/create-draft | userName: admin | referer: http://localhost:8080/display/CBS/q5 | traceId: 2834180fd06ac39b
confluence-1  | java.lang.LinkageError: loader constraint violation:
when resolving interface method
  'BlueprintContext BlueprintContextTransformer.transform(BlueprintContext)'
the class loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @43ceadd8 of the current class, com/example/plugins/tutorial/confluence/simplebp/MyContextProvider,
and the class loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @77e190f0 for the method's defining class, com/example/lib/api/BlueprintContextTransformer,
have different Class objects for the type com/atlassian/confluence/plugins/createcontent/api/contextproviders/BlueprintContext
used in the signature
  (com.example.plugins.tutorial.confluence.simplebp.MyContextProvider is in unnamed module of loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @43ceadd8,
     parent loader org.apache.catalina.loader.ParallelWebappClassLoader @452acb84;
   com.example.lib.api.BlueprintContextTransformer is in unnamed module of loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @77e190f0, parent loader org.apache.catalina.loader.ParallelWebappClassLoader @452acb84)
confluence-1  |         at com.example.plugins.tutorial.confluence.simplebp.MyContextProvider.updateBlueprintContext(MyContextProvider.java:29)
confluence-1  |         at com.atlassian.confluence.plugins.createcontent.api.contextproviders.AbstractBlueprintContextProvider.getContextMap(AbstractBlueprintContextProvider.java:41)                                                                                                                                                                                                                                                                                         
confluence-1  |         at com.atlassian.confluence.plugins.createcontent.actions.DefaultBlueprintContentGenerator.getContentTemplateContext(DefaultBlueprintContentGenerator.java:196)
confluence-1  |         at com.atlassian.confluence.plugins.createcontent.actions.DefaultBlueprintContentGenerator.generateBlueprintPageObject(DefaultBlueprintContentGenerator.java:115)                                                                                                                                                                                                                                                                                       
confluence-1  |         at com.atlassian.confluence.plugins.createcontent.actions.DefaultBlueprintContentGenerator.generateBlueprintPageObject(DefaultBlueprintContentGenerator.java:93)                                                                                                                                                                                                                                                                                        
confluence-1  |         at com.atlassian.confluence.plugins.createcontent.impl.DefaultContentBlueprintService.createContentDraft(DefaultContentBlueprintService.java:266)                                                                                                                                                                                                                                                                                                       
confluence-1  |         at com.atlassian.confluence.plugins.createcontent.rest.ContentBlueprintResource.createDraft(ContentBlueprintResource.java:95)                                                                                                                                                                                                                                                                                                                           
confluence-1  |         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Where

  1. BlueprintContext = com.atlassian.confluence.plugins.createcontent.api.contextproviders.BlueprintContext
  2. BlueprintContextTransformer = com.example.lib.api.BlueprintContextTransformer

MyContextProvider is the class in the service consuming app that uses the service BlueprintContextTransformer provided by the service providing app. Both reference the type BlueprintContext from the Confluence API dependency.

Everything works in Confluence < 9.

I do the injection with Spring Java Config. And since I can call a service (void execute() in the example above) without types from another dependency successfully, I’d like to think that the issue is not in the Java classes.

I am using a modified version of the adjusted project Bitbucket which is based on the example provided by Atlassian (adjusted to run on Confluence 9 with Spring Java Config).

So this (finally) is my question:

Both of my apps load a class named BlueprintContext and when the consuming app tries to provide an instance of this class as an argument to the call of a service of the second app, the object of type BlueprintContext loaded by the calling app is not assignable to the parameter type BlueprintContext of the second service providing app.

Is my analysis correct?

  1. yes: how can I configure both apps so that they can actually work together? Is it with the Import, the Export, the scope of the dependencies, …? Are there special rules for the service providing app that I am missing?
  2. no: What is it then? Where can I look? What am I missing?

Edit: In case the original sources would be helpful to understand my problem:

When I add a REST service to this demo app and follow the advice given in Confluence 8.9 release EAP available now - #27 by SujayCHegde then I can call the the service from my other app without issues.

The Listener still complains about classloading issues when he tries to process the event. But if I remove the listener, no issues are logged by Confluence.

I still cannot explain any of this and it may be that not everything in the configuration is necessary, but I hope that someone also struggling with classloading issues on Confluence 9 finds this helpful … (even if the root cause is probably a comma in some XML … :smile:)

So it has nothing to do with the REST service, it is just this line in the Imports:

com.atlassian.confluence.plugins.createcontent.api.contextproviders;version="0.0.0",

If you then use the correct event type, the call to the external service and the listener work.

So it has not been a comma, but the asterisk … :smile:

Just in case someone is interested: https://bitbucket.org/smartics/confluence-eventlistener-blueprint/src/external-service_listener/.

1 Like

Hi,

I am having an issue with the new behaviours in velocity template rendering introduced in 9.x.

Basically, calls to standard Atlassian classes, like PageManager do not work anymore, as they did in previous versions.

Take this sample velocity file, where $pages is a list of confluence contentIds.

<table>
    <tbody>
        #foreach($pageId in $pages)
            #set($ceo = $pageManager.getById($pageId))
            <tr>
                <td>
                    $pageManager, $pageId, $ceo, <a href="$globalSettings.BaseUrl/$ceo.getUrlPath()">$ceo.getTitle()</a>
                </td>
            </tr>
        #end
    </tbody>
</table>

Prior to 9.0, the $pageManager.getById() function worked. Now it does not. Here is the output. If this list has 1 contentId in it…

com.atlassian.confluence.impl.content.DefaultPageManager@6b17d139, 163841, $ceo, [$ceo.getTitle()](http://my-pc:1990/confluence/$ceo.getUrlPath())

Adding <method> entry for PageManager or DefaultPageManager also breaks the <velocity-allowlist> module introduced in 9.x???

So, I am really stuck, has anyone come across this?

@mr.chris.kent You cannot allowlist Atlassian classes for velocity anymore. I suggest you write a wrapper Java class in you own project which has a PageManager as a member and delegates the method calls (just replicate the entire API). Then you can allowlist your own class. That way you can maintain the same API and don’t really have to change the velocity templates, you only need to wrap the class in your own when putting into the model.

1 Like

Hi @EliasBrattliSorensen ,

Thanks for that answer, it makes sense, but very unfortunate if there are a lot of Atlassian classes used in Velocity. For me in this case, I only have about half a dozen.

Hi @turehoefner_appfire

Thanks for replay I also doing same things but getting that error.

In my plugin the @AnonymousSiteAccess, @UnrestrictedAccess annotations do not work on Confluence 8.9.5. They deny access to an anonymous user when the REST endpoint should be available.

This only happens when I use <rest-migration key="rest-migration-key"><rest-v2/></rest-migration> in preparation for Platform 7. That causes the REST endpoint to switch from V1 to V2 for Confluence 8.9.5. Or, I should say, it causes the container to instantiate my REST endpoint using the arg-less constructor that I have supplied in preparation for simultaneously supporting REST V1 and V2 (so I can have a single installer for all supported versions).

I am not sure if there is something about my migration implementation that is wrong or if those anonymous access annotations really are broken in Confluence 8.9.5 for REST V2. I have not yet been able to deploy my plugin on Confluence 9.x (fugue problems) so I’m only partway to Platform 7 compat.

How, exactly, do @AnonymousSiteAccess and @UnrestrictedAccess work? Can we have a psuedo-code description of the logic? Or can we have the source code?

Thanks.

Hey Ture!

First of all, <rest-migration> tag is not needed, in Confluence 9 it will switch automatically to REST v2 . I don’t know if you need it because of something.

Second, yes, I had problems as well with @UnrestrictedAccess under the package com.atlassian.plugins.rest.common.security that, according to this document, it should be working for both versions, Confluence 8 & 9. So, I tried to add both annotations (@com.atlassian.annotations.security.UnrestrictedAccess & com.atlassian.plugins.rest.common.security.UnrestrictedAccess), and apparently it works (if I did correctly all the tests)

1 Like