Preparing for Confluence 9.0 - EAP out now

Dear @JordanAnslow

sorry for the late answer. Your assumption is correct, the URL is internal. This url however should not come into force here - the image placeholder is only for the editor and not the export.

I did not see anything in the logs.

Best regards

Andreas

Hi @scott.dudley,
This issue has been fixed and would be available in next EAP release. Let us know if you have any questions.

@kmacleod, that was very helpfull, thanks a lot. Here just a little suggestion, why not in Documentation providing a kind of recommanded section, with recommanded pom xml with the recommanded elements to add, with some comments explaining, like in the code below, i think that this will make life easier for everybody including Atlassian staff.
Again thanks for the clue.

Pom xml file
...
...
<dependencies>
    <!-- when version xml tag is not provided, dependencyManagement will assign the right version-->
    <dependency>
        <groupId>com.atlassian.mywork</groupId>
        <artifactId>mywork-api</artifactId>
        <scope>provided</scope>
    </dependency>    
    ...
    other necessary dependencies 
    ...
    <!-- for this dependency removing the version causes a compilation error -->    
    <dependency>
        <groupId>com.atlassian.plugins</groupId>
        <artifactId>atlassian-plugins-osgi-javaconfig</artifactId>
        <version>0.6.0</version>
    </dependency>  
</dependencies>
<!-- recommanded use of dependencyManagement : this will assign the right versions to the dependecies  -->
<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>
    </dependencies>
</dependencyManagement>
...

Hi kmacleod,

I have made my pom as you suggested and then I got the below compile errors
no suitable method found for metadata(com.fasterxml.jackson.databind.node.ObjectNode)
method

com.atlassian.mywork.model.NotificationBuilder.metadata(org.codehaus.jackson.node.ObjectNode) is not applicable
      (argument mismatch; com.fasterxml.jackson.databind.node.ObjectNode cannot be converted to org.codehaus.jackson.node.ObjectNode)
    method com.atlassian.mywork.model.NotificationBuilder.metadata(java.lang.String) is not applicable
      (argument mismatch; com.fasterxml.jackson.databind.node.ObjectNode cannot be converted to java.lang.String)

Then changed my code to use fasterxml ObjectNode and it worked on confluence 9 beta2
Now the thing is
when I carry the same jar working on Confluence 9-beta2 and deploy in Confluence 8.9.1 I am getting the below exception and the plugin fails to enable as it is failing in loading the @configuration class

Caused by: java.lang.NoClassDefFoundError: com/atlassian/mywork/service/RegistrationProvider
 at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
 at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3402)
 at java.base/java.lang.Class.getDeclaredMethods(Class.java:2504)
 at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:467)
 ... 22 more
Caused by: java.lang.ClassNotFoundException: com.atlassian.mywork.service.RegistrationProvider not found by com.simplenia.confluence.plugins.polls [306]
 at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1591)
 at org.apache.felix.framework.BundleWiringImpl.access$300(BundleWiringImpl.java:79)
 at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1976)
 at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
 ... 26 more

Please throw some light on how to deal this to get it working on 8.x version of confluence also along with 9

Hey together,

I noticed a problem with the ClusterEventWrapper.

In Confluence 8 the method getEvent from the com.atlassian.confluence.event.events.cluster.ClusterEventWrapper returns com.atlassian.event.Event, but Confluence 9 it returns a com.atlassian.confluence.event.events.ConfluenceEvent.

	@EventListener
	public void listenToClusterMessageEvent(ClusterEventWrapper wrapper) {
		log.debug("Received cluster message event");

		ClusterEvent event = wrapper.getEvent(); // In Confluence 8 the provided type is Event, not ClusterEvent
		if ( event instanceof ClusterMessageEvent ) {
			ClusterMessage message = ((ClusterMessageEvent) event).getMessage();
			if ( message.getChannel() != null ) {
				this.consumers.get(message.getChannel().toString()).receive(message);
			}
		}
	}

Any idea how I can use the same method in Confluence 9 and 8?

Cheers,
Marcel

Hi @AtulyaRastogi

Thank you—and I do indeed have a question. With this upcoming fix, do you mean that the ServiceExceptionMapper package has been unbanned, or do we need to change it to something else, or do something else? (I am again making reference to the instructions here.)

I had the same problem, some reflection seemed to do the trick.

Object event = ClusterEventWrapper.class.getMethod("getEvent").invoke(wrapper);

Not sure what you’re doing with it, but we’ve always needed to typecast that event to the appropriate event type right after we do the instanceof check anyhow.

if (event instanceof MyEvent) {
    ((MyEvent) event).someMethod();
}

So it doesn’t seem to matter that it lives as an Object briefly.

Also, are you publishing and listening for your own custom events? I’ve noticed that clusterManager.publishEvent still accepts a ConfluenceEvent argument, despite that class just being deprecated in 8.9. Don’t think I’ve seen that mentioned anywhere yet.

Hi @scott.dudley

Can you please which version of Javaz.ws.rs you are using. You need to use 2.x version

Regards
Nikhil jain

Hey @AndrewMorton,
thanks for the answer. I was also thinking about reflections, but if possible I try to not use it.

Luckily I found another solution, where I do not need the ClusterEventWrapper. I just replaced the Wrapper with the ClusterEvent class. As I need the listener for just one single event.

So far, it’s working on Confluence 9. The test for Confluence 8 is pending… (I hope there it works as well).

	@EventListener
	public void listenToClusterMessageEvent(ClusterEvent event) {
		log.debug("Received cluster message event");

		if ( event instanceof ClusterMessageEvent ) {
			ClusterMessage message = ((ClusterMessageEvent) event).getMessage();
			if ( message.getChannel() != null ) {
				this.consumers.get(message.getChannel().toString()).receive(message);
			}
		}
	}

Cheers

1 Like

@nunoMSsantos Unfortunately not. I’m now just extending ConfluenceActionSupport and pulling down the necessary pieces of code from AbstractUserProfileAction. But I haven’t checked anymore with the more recent versions. Let me know if you’d like to see the code I pulled down. You can also find me on the vendors Slack workspace if you wanna chat about it.

Hi @NikhilJain

My pom declares jakarta.ws.rs:jakarta.ws.rs-api:jar:2.1.6:provided, but I think the pom is probably irrelevant (it shouldn’t even matter what version I declare there), because the only thing that the package scanner sees is the manifest import of javax.ws.rs.

I cannot pin the manifest import to [2.0,) because doing this would cause it to fail to load on Confluence 8. It seems that the only problem is that Atlassian is exporting two versions of javax.ws.rs and trying to resolve my import against both, and it is generating warnings against the banned 1.x version even though it will successfully resolve against 2.x.

Hi Developer Community!

Just a quick FYI that we’ve just released the first Release Candidate (RC) for Confluence 9.0. You can download the RC from our site to test your app for compatibility.

For more detailed information, check out our Beta release notes and Preparing for Confluence 9.0 documentation.

This update was also released on the Confluence DC changelog , if not already, please consider subscribing to the RSS feed for the most timely updates on product changes.

Cheers!

Seems like is due to RESTV1/old version of com.atlassian.mywork.common-plugin .
Could you try with latest/RC version of Confluence DC please.

Thanks and Regards,
Sujay

Hi @SujayCHegde ,

The issue of the chain conflict was resolved but we cannot do the injection of NotificationService using @ComponentImport annotation. The error:

Error creating bean with name 'adhocInAppNotificationServiceImpl': Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.atlassian.mywork.service.LocalNotificationService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport("")}

Don’t know if related, but there are some WARN message before the error:

 filterMatches Package javax.ws.rs is internal and is not available for export to plugin com.comalatech.workflow
 -- url: /confluence/rest/plugins/1.0/ | userName: admin | referer: http://localhost:8090/confluence/plugins/servlet/upm | traceId: 6081316a400c4217
2024-07-15 09:37:08,716 WARN [UpmAsynchronousTaskManager:thread-3] [osgi.hook.dmz.DmzResolverHook] filterMatches Package javax.ws.rs.core is internal and is not available for export to plugin com.comalatech.workflow

These messages should not be displayed, right ? They are available to import if I’m not wrong. My endpoints are working properly with Rest V2.

Gorka.

We’ve noticed a German translation glitch on the password reset page.

In English, it’s “Send”, so should probably be “Absenden” in German. Used to be “An mich senden” in the earlier releases.

Edit:

Oh, it’s an HTML issue. Looks ugly.

<input name="confirm" [...] value="An" mich="" senden="" tabindex="4" resolved="">

I use MarkSelectionModifier to highlight text and in Confluence 9.0.0-rc1 I have this error:

java.lang.NoClassDefFoundError: com/google/common/collect/ImmutableSet
	at com.atlassian.confluence.plugins.highlight.xml.MarkStateTracker.<clinit>(MarkStateTracker.java:12)
	at com.atlassian.confluence.plugins.highlight.service.MarkSelectionModifier.createModificationStateTracker(MarkSelectionModifier.java:43)
	at com.atlassian.confluence.plugins.highlight.service.DefaultSelectionModifier.modify(DefaultSelectionModifier.java:67)
	at com.atlassian.confluence.plugins.highlight.service.DefaultSelectionModifier.modify(DefaultSelectionModifier.java:54)

I tried to add this dependency , but enforcer plugin failed, banningExclude didn’t help.

<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>33.2.1-jre</version>
        </dependency>

Yes, MarkStateTracker really uses ImmutableSet

Is it possible to solve this issue somehow? For example, Set.of is available since java 9.

Kind regards

Hi @AtulyaRastogi

I tried again with today’s 9.0.0-rc1, but I’m still getting this error with trying to define a ServiceExceptionMapper:

2024-07-15 09:29:47,126 WARN [QuickReload - Plugin Installer] [osgi.hook.dmz.DmzResolverHook] filterMatches Package com.atlassian.confluence.rest.api.exception is internal and is not available for export to plugin com.myapp
[...]
Caused by: org.osgi.framework.BundleException: Unable to resolve com.myapp [294](R 294.0): missing requirement [com.myapp [294](R 294.0)] osgi.wiring.package; (osgi.wiring.package=com.atlassian.confluence.rest.api.exception) Unresolved requirements: [[com.myapp [294](R 294.0)] osgi.wiring.package; (osgi.wiring.package=com.atlassian.confluence.rest.api.exception)]
        at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:4398)
        at org.apache.felix.framework.Felix.startBundle(Felix.java:2308)
        at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:1006)
        at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:992)
        at com.atlassian.plugin.osgi.factory.OsgiPlugin.enableInternal(OsgiPlugin.java:408)

Any suggestions on how to resolve this?

@scott.dudley Please use v2 equivalent of com.atlassian.confluence.rest.api.exception.ServiceExceptionMapper, specifically
com.atlassian.confluence.rest.v2.api.exception.ServiceExceptionMapper
cc: @AtulyaRastogi

Could you use:

            <dependency>
                  <groupId>com.atlassian.confluence</groupId>
                  <artifactId>confluence-rest-v2-api</artifactId>
                 <scope>provided</scope>
        </dependency>

This provides the RESTV2 version of ServiceExceptionMapper

Thanks

Regarding @ReadOnlyAccessAllowed → Its actually handled by a filter and Interceptor(for Struts actions) in Confluence DC and not really the platform . But yes does not need any real work from dev besides using the annotation.

Regarding Platformizing ServiceExceptionMapper, would need inputs from @MarekTokarski

Thanks