Preparing for Confluence 9.0 - EAP out now

Hello everyone,

Could someone from Atlassian please confirm if this issue is indeed a bug? This is a blocker for us, as our macro cannot load properly due to the resource not being included.

Thank you!

@MarekTokarski @TomRijnbeek can you please help here

Various other devmode breakages
When running with dev mode enabled, I see a few other basic things broken. For example, adding the Attachments macro to a page causes various JS errors and most of the interactive page features become non-functional, the sidebar does not render, and so on.

Hi @scott.dudley,

I’ve been unable to reproduce the issues you’ve encountered with dev mode enabled. Would you be able to provide any further detail on how you’re starting Confluence as well as any additional steps which could help us consistently trigger the issues you’re seeing? Thanks.

Maybe is better then, to update the guide of the rest v2 migration, in order to avoid confusion: Bitbucket

It would be a ServiceExceptionMapper that converts ReadOnlyException(amongst many other exceptions) to com.atlassian.confluence.rest.v2.api.model.RestError and would be across all REST endpoints in the product. RestError would contain 405 error code for

Will check about app specific Exception mapper. Is it required if we have a global exception mapper?

So what I understand is :

  1. By default have a Global mapper.
  2. Have app specific mapper and make this take precedence over global mapper?

Above needs to be clarified.

Thanks

Hi @aovsyannikov
I took a look at the sample plugin code. It is missing an import for active objects package under Import-Package section of com.atlassian.maven.plugins configuration in the pom.xml
Adding the import fixes the problem. I have verified it. Can you please let me know how it goes for you ? Thanks

                       <Import-Package>
                            com.atlassian.confluence.plugin.descriptor.web.conditions,
                            com.atlassian.confluence.plugin.descriptor.web.conditions.user,
                            com.atlassian.activeobjects.external,
                            com.atlassian.confluence.api.service.accessmode;resolution:="optional",
                            *;resolution:=optional,
                        </Import-Package>

@MarekTokarski Possible to respond to this from platform perspective.
Thanks

I’m working on getting this added globally - please feel free to wrap the method as a workaround for the time being (see @scott.dudley’s earlier message here)

Thanks for the additional information here @scott.dudley

Given the class originates from Confluence Core, this presumably narrows down the potential cause to the Velocity engine not loading the correct configuration.

The org.apache.commons.lang3.StringUtils#isNotEmpty(java.lang.CharSequence) method is allowlisted slightly differently to other methods. This method is allowlisted via the Velocity configuration property introspector.proper.allowlist.classes rather than introspector.proper.allowlist.methods. It was added to this configuration from 9.0.0-m86 onwards. Additionally, whether DevMode is enabled or not, should not impact how the Velocity allowlist configuration is loaded and enforced.

Given I’m still unable to reproduce this issue, can I kindly ask that you check your local dev instance doesn’t have any stale configuration or conflicting customisations to velocity-default.properties - or try setting up a fresh instance?

Hi @tobias.viehweger

REST v1 was registering single bean as both com.atlassian.sal.api.net.RequestFactory and com.atlassian.sal.api.net.MarshallingRequestFactory. It was causing errors in specific situations, so in REST v2 we decided to register that object only as com.atlassian.sal.api.net.MarshallingRequestFactory. With your question we realized that part isn’t included in our migration guide (Bitbucket), we will update that document soon.

I also checked why ComponentLocator.getComponent(RequestFactory.class) returns any values. Turns out it depends on product specific implementation and configuration - it is indeed “hacky”. Even though you get an instance, most probably it isn’t the one you would expect and we cannot ensure it will be working as expected.

Hi @mahesh,

Thank you for your investigation. Frankly speaking, I’ve tried this thing before. Adding this import to <Import-Package> partially deals with the problem. I could install the app, but I cannot enable it. Here is an error message from the logs:

com.atlassian.plugin.osgi.container.OsgiContainerException: Cannot start plugin: com.stiltsoft.confluence.test.app
	at com.atlassian.plugin.osgi.factory.OsgiPlugin.enableInternal(OsgiPlugin.java:427)
...
Caused by: org.osgi.framework.BundleException: Uses constraint violation. Unable to resolve resource com.stiltsoft.confluence.test.app [com.stiltsoft.confluence.test.app [292](R 292.0)] because it is exposed to package 'com.google.common.collect' from resources com.stiltsoft.confluence.test.app [com.stiltsoft.confluence.test.app [292](R 292.0)] and org.apache.felix.framework [org.apache.felix.framework [0](R 0)] via two dependency chains.

Chain 1:
  com.stiltsoft.confluence.test.app [com.stiltsoft.confluence.test.app [292](R 292.0)]
    import: (osgi.wiring.package=com.google.common.collect)
     |
    export: osgi.wiring.package: com.google.common.collect
  com.stiltsoft.confluence.test.app [com.stiltsoft.confluence.test.app [292](R 292.0)]

Chain 2:
  com.stiltsoft.confluence.test.app [com.stiltsoft.confluence.test.app [292](R 292.0)]
    import: (osgi.wiring.package=com.atlassian.activeobjects.external)
     |
    export: osgi.wiring.package=com.atlassian.activeobjects.external; uses:=com.google.common.collect
  com.atlassian.activeobjects.activeobjects-plugin [com.atlassian.activeobjects.activeobjects-plugin [8](R 8.0)]
    import: (osgi.wiring.package=com.google.common.collect)
     |
    export: osgi.wiring.package: com.google.common.collect
  org.apache.felix.framework [org.apache.felix.framework [0](R 0)] Unresolved requirements: [[com.stiltsoft.confluence.test.app [292](R 292.0)] osgi.wiring.package; (osgi.wiring.package=com.atlassian.activeobjects.external)]
	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)
	... 106 more

Any ideas on how to deal with it would be appreciated.

Hi @nunoMSsantos and @KDanial

Thank you for providing a sample plugin for reproduction.

The deprecated #standardHeader() macro has been deleted in Confluence 9.0, its direct replacement is #parse("/decorators/includes/header.vm") - apologies for the lack of update to the documentation.

As for resource loading, the #requireResource and #requireResourcesForContext macros do not directly inject the resources on the page, they only mark the resources for injection. The injection itself is conducted by $webResourceHelper.getConfluenceResourceTags which is called from the aforementioned header.vm.

If you replace any usages of #standardHeader() as above, you should find that your template resources should begin loading again.

1 Like

Thank you for the input, ill try this out and let you know.

edit: @Kusal Thank you this has solve the problem mentioned.

Hi @Kusal

I did some tests and I do see that the addition of -Dconfluence.devmode=true seems to be the trigger for the issue on my system, even if that is not supposed to happen. I’ll send you a DM with the specific diffs between my installation and the 9.0.0-rc1 tarball, since perhaps something else is a catalyst.

Hi @JordanAnslow I’ll send you a DM with the same information too, since I am still seeing those breakages.

I am testing both issues (the Velocity warnings as well as the “other devmode breakages”) on a two-node cluster. When one of the nodes is configured for devmode, the issues occur exclusively on that node, while the other non-devmode node works correctly (contemporaneously).

Thanks, all!

1 Like

Hi @SujayCHegde

Due to the changing classes in Conf 8 vs 9, I found that I can implement the following and have it work cross-major:

import javax.ws.rs.ext.ExceptionMapper;

@Priority(5000)
@Provider
public class RestExceptionMapper implements ExceptionMapper<Throwable> {
     public Response toResponse(E exception) {
         // ...
     }

Effectively, if 9.1 introduces its own exception mapper that handles read-only exceptions, can Atlassian make sure that either your or our ExceptionMapper will be used consistently? I don’t think I particularly care which one, so long as it does not break, because we still do need to ship something like the above for <= 9.0.

1 Like

I can also confirm that the issues I reported in the last two posts with -rc1 are still happening with -rc2.

Unrelated to those, I am now seeing the following exceptions consistently on both nodes of a cluster. This is new as of -rc2. There are no apps installed, and these exceptions show up every 20 seconds, regardless of whether or not I am using the instance, and regardless of the devmode setting.

2024-07-22 09:26:03,716 ERROR [hz.confluence.event-5] [atlassian.confluence.event.ConfluenceListenerInvoker] log java.lang.RuntimeException occurred dispatching com.atlassian.confluence.cluster.hazelcast.HazelcastClusterEventWrapper to [com.atlassian.migration.agent.service.execution.StepExecutionService]
java.lang.RuntimeException: 'com.atlassian.event.Event com.atlassian.confluence.event.events.cluster.ClusterEventWrapper.getEvent()'. Listener: com.atlassian.migration.agent.service.execution.StepExecutionService event: com.atlassian.confluence.cluster.hazelcast.HazelcastClusterEventWrapper
	at com.atlassian.event.internal.SingleParameterMethodListenerInvoker.invoke(SingleParameterMethodListenerInvoker.java:53)
	at com.atlassian.confluence.event.DelegatingListenerInvoker.invoke(DelegatingListenerInvoker.java:23)
	at com.atlassian.confluence.event.ConfluenceListenerInvoker.invoke(ConfluenceListenerInvoker.java:30)
	at com.atlassian.event.internal.ComparableListenerInvoker.invoke(ComparableListenerInvoker.java:48)
	at com.atlassian.event.internal.AsynchronousAbleEventDispatcher.lambda$static$0(AsynchronousAbleEventDispatcher.java:37)
	at com.atlassian.event.internal.AsynchronousAbleEventDispatcher.dispatch(AsynchronousAbleEventDispatcher.java:85)
	at com.atlassian.event.internal.EventPublisherImpl.publish(EventPublisherImpl.java:102)
	at com.atlassian.confluence.event.TimingEventPublisher.publish(TimingEventPublisher.java:75)
	at com.atlassian.confluence.impl.cluster.event.TopicEventPublisher.onEvent(TopicEventPublisher.java:102)
	at com.atlassian.confluence.impl.cluster.hazelcast.event.HazelcastTopicEventCluster.lambda$registerTopicListener$0(HazelcastTopicEventCluster.java:52)
	at com.hazelcast.topic.impl.TopicService.dispatchEvent(TopicService.java:151)
	at com.hazelcast.spi.impl.eventservice.impl.EventProcessor.process(EventProcessor.java:63)
	at com.hazelcast.spi.impl.eventservice.impl.RemoteEventProcessor.run(RemoteEventProcessor.java:48)
	at com.hazelcast.internal.util.executor.StripedExecutor$Worker.process(StripedExecutor.java:245)
	at com.hazelcast.internal.util.executor.StripedExecutor$Worker.run(StripedExecutor.java:228)
Caused by: java.lang.NoSuchMethodError: 'com.atlassian.event.Event com.atlassian.confluence.event.events.cluster.ClusterEventWrapper.getEvent()'
	at com.atlassian.migration.agent.service.execution.StepExecutionService.handleClusteredEvent(StepExecutionService.java:226)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at com.atlassian.event.internal.SingleParameterMethodListenerInvoker.invoke(SingleParameterMethodListenerInvoker.java:42)
	... 14 more

Same here, this has resolved our problem!
Thank you very much @Kusal

Should this be added somewhere in the documentation?

Hi @MarekTokarski

thanks - looking forward to that guide because at this point I tried everything (even MarshallingRequestFactory) and I can’t get it to work in the REST API. ComponentLocator did indeed provide a broken instance that was not usable.
I tried injecting it via

  • @ComponentImport
  • @Named + import via xml file (<osgi:…)
  • Via javaconfig

OSGI does not seem to be able to give me that instance…

//Edit… Ah yes, good old hour-long doing random code changes to see if it makes a difference…

// Works
@ComponentImport MarshallingRequestFactory requestFactory

// Does not work ....
@ComponentImport MarshallingRequestFactory<?> requestFactory
@ComponentImport MarshallingRequestFactory<Request<?, Response>> requestFactory

// Edit 2 - only in the REST API though. Using it in our PluginEventHandler it works with <?>.

Hi @aovsyannikov ,
It seems you are exporting everything in your pom.xml ( Export-Package= *)
If you limit the export-package to what you want to export, you should be able to enable your plugin.
For ex :
<Export-Package>com.stiltsoft.confluence.test.app</Export-Package>

Please refer to this guide.

1 Like

@mahesh

It helped me. The solution is more evident than I expected :slightly_smiling_face:. I appreciate your help!