Preparing for Confluence 9.0 - EAP out now

Hi Community.

I tried today 9.0.0-m41 and have this error:

Caused by: java.lang.ClassNotFoundException: com.atlassian.plugin.webresource.condition.UrlReadingCondition
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1329)
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1141)
	at org.apache.felix.framework.ExtensionManager$ExtensionManagerWiring.getClassByDelegation(ExtensionManager.java:1212)
	at org.apache.felix.framework.BundleWiringImpl.searchImports(BundleWiringImpl.java:1612)
	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1528)
	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(Unknown Source)
	... 136 more

I CustomCondition implements UrlReadingCondition .

My pom.xml is

<Import-Package>
         com.atlassian.confluence.plugin.descriptor.web.conditions,
        com.atlassian.confluence.plugin.descriptor.web.conditions.user,
        *;resolution:=optional,
</Import-Package>

and the dependency for com.atlassian.plugins:atlassian-plugins-webresource-api:5.6.7:provided .

Does anybody knows how to fix this? 9.0.0-m26 is working without changes above.

Kind regards

2 Likes

Hi @aorlov

this class has been moved

Old fully-qualified type name New fully-qualified type name
com.atlassian.plugin.webresource.condition.UrlReadingCondition com.atlassian.webresource.spi.condition.UrlReadingCondition

More changes can be found here → https://developer.atlassian.com/platform/marketplace/dc-apps-platform-7/

Cheers
Adam

1 Like

Hi @adam.labus

Thanks for the info, I’m also facing similar issues as @aorlov did.

Caused by: java.lang.ClassNotFoundException: com.atlassian.plugin.webresource.transformer.WebResourceTransformerFactory
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1329)
	at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1141)
	at org.apache.felix.framework.ExtensionManager$ExtensionManagerWiring.getClassByDelegation(ExtensionManager.java:1212)
	at org.apache.felix.framework.BundleWiringImpl.searchImports(BundleWiringImpl.java:1612)
	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1528)
	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)

It got me thinking would the new changes were compatible with the older version of Confluence such as Confluence 8.0.0. We can see that the new fully-qualified type name of WebResourceTransformerFactory.java only available from v6.3.0. And Confluence 8.0.0 seems to be still depending v6.1.0, I’m kinda stuck as I want to make my plugin to implements WebResourceTransformerFactory and compatible with Confluence 8 → 9.

Appreciate if there’s any input regards to this.

Regards
Leon.

2 Likes

We’re using the Confluence Excerpter (@ComponentImport com.atlassian.confluence.content.render.xhtml.view.excerpt.Excerpter), but it does not seem to be available in Confluence 9:
No qualifying bean of type 'com.atlassian.confluence.content.render.xhtml.view.excerpt.Excerpter' available: expected at least 1 bean which qualifies as autowire candidate.

Has someone else encountered this?

Also: The Atlassian Maven repository Index of maven-external/com/atlassian/confluence/confluence only contains Confluence 9.0.0-m34, not m41. Any experience how long new milestones take to be available there?

1 Like

Thanks for the info @adam.labus

Hi @kmacleod / @WendyR / whoever else might be able to help:

Regarding the posts above regarding new ClassNotFoundExceptions for UrlReadingCondition (and also as @cheinig has noted), this has become impossible to debug at build time (it now shows up only at runtime) because the latest milestone builds of Confluence (such as this week’s 9.0.0-m41) are no longer available on your Nexus and developers cannot verify binary compatibility.

I guess this is related to the changelog about interim builds no longer being published, but it says that EAP builds should be available, so perhaps this was an oversight.

Is there any way to get this published quickly? As of -m41, the ecosystem is flying in the dark. Developers need the 9.0.0-m41 main artifact, plus all dependent artifacts that are shipped with Confluence, in order to build our products.

2 Likes

We’re also affected by this. And 9.0.0-m41 is especially important because it finished the gray API removal work according to the changelog.
Hiding exactly this milestone from us is blocking us in our compatibility efforts and prevents us from providing early feedback on included changes.

1 Like

hi jens, this will be available by early next week

2 Likes

Hi @NikhilJain

I am glad to hear that the release artifacts will be published next week. For clarity, will the release process be fixed so that the artifacts for future EAPs will be made available at the same time as the EAP? (There will presumably be another EAP milestone release next Tuesday, so publishing only the -m41 artifacts would be less than ideal.)

Scott

5 Likes

Breaking changes to the Maven publication process during a major release cycle seems reckless. Another slap in the face for vendors working around the clock on platform 7.

3 Likes

Hello @aorlov,
Did you figure out how to get past the java.lang.ClassNotFoundException: com.atlassian.util.concurrent.Supplier

and then the Class com.atlassian.spring.container.LazyComponentReference does not implement the requested interface com.atlassian.util.concurrent.Supplier ?

I ran into the same problem (on Confluence 8.9 in dev mode)

First the ClassNotFoundException for com.atlassian.util.concurrent.Supplier and I worked around that by adding a dependency:

        <dependency>
            <groupId>com.atlassian.util.concurrent</groupId>
            <artifactId>atlassian-util-concurrent</artifactId>
            <version>3.0.0</version>
        </dependency>

and then ran into the Class com.atlassian.spring.container.LazyComponentReference does not implement the requested interface com.atlassian.util.concurrent.Supplier

In the atlassian-confluence.log file I can see that the problem w/ LazyComponentReference is a java.lang.IncompatibleClassChangeError and it happens when my plugin calls com.atlassian.confluence.compat.api.service.accessmode.impl.DefaultAccessModeCompatService.isReadOnlyAccessModeEnabled (which is in confluence-compat-lib)

LazyComponentReference is in atlassian-spring. Supplier is in atlassian-util-concurrent.

I am using the (latest?) version 1.6.1 of the confluence-compat-lib.

Maybe the 1.6.1 confluence-compat-lib isn’t built using the right version of atlassian-spring for it to work for Platform 7?

[INFO] [talledLocalContainer] java.lang.IncompatibleClassChangeError: Class com.atlassian.spring.container.LazyComponentReference does not implement the requested interface com.atlassian.util.concurrent.Supplier
[INFO] [talledLocalContainer] 	at com.atlassian.confluence.compat.api.service.accessmode.impl.DefaultAccessModeCompatService.getAccessModeService(DefaultAccessModeCompatService.java:40)
[INFO] [talledLocalContainer] 	at com.atlassian.confluence.compat.api.service.accessmode.impl.DefaultAccessModeCompatService.isReadOnlyAccessModeEnabled(DefaultAccessModeCompatService.java:21)

I’m sure this is an oversight, but it’s one of many, the cumulative impact on morale is going to harm Atlassian in the future.

1 Like

@aorlov I worked around my problem with the confluence-compat-lib having an incompatible class for LazyComponentReference in it by eliminating my use of confluence-compat-lib.

Maybe that sounds like a bad workaround but, in my case, I was only using the confluence-compat-lib for AccessModeCompatService#isReadOnlyAccessModeEnabled.

The DefaultAccessModeCompatService in the confluence-compat-lib does its magic by using LazyComponentReference as a Supplier for a AccessModeService that may or may not exist. Maybe the 1.6.1 version is compiled against some old spring (atlassian-spring?) library that is incompatible w/ newer Confluence?

I discovered that the backwards compat for that part is only for REALLY old Confluence, like Confluence 6 or something like that. I don’t care about compat w/ Confluence 6 so I deleted the confluence-compat-lib and changed to directly using the AccessModeService instead of the AccessModeCompatService. (I realized the backwards-compat was for ancient Confluence by reading this: https://developer.atlassian.com/server/confluence/how-to-make-your-add-on-compatible-with-read-only-mode/ )

This works fine on both Confluence 7.19 (oldest non-EOL) and Confluence 8.9 (I’m still not caught up enough to start working on Confluence 9 compat… but I guess all this work for 8.7/8.8/8.9 is technically working towards Confluence 9 compat).

2 Likes

Hello @turehoefner_appfire

Today I solved it, but a little different. Maybe it helps somebody.

I also use DefaultAccessModeCompatService.isReadOnlyAccessModeEnabled.

I commented

<Import-Package>                    
   <!--com.atlassian.confluence.api.service.accessmode;resolution:="optional",-->
   *;resolution:=optional,
</Import-Package>

And then added class Supplier in my project manually:

I created DefaultAccessModeCompatService via java configuration like that:

@Bean
    public AccessModeCompatService accessModeCompatService() {
        return new DefaultAccessModeCompatService();
    }

importOsgiService doesn’t work properly for this class. It’s hard to say why.

I know, it can be a little stupid solution, but it works )))).

Thank you for your solution.

Kind regards

1 Like

@aorlov If you compile at least against Confluence 6.8.0 you can remove the hacks and simply OSGi import the proper AccessModeService component directly via its interface:

import com.atlassian.confluence.api.service.accessmode.AccessModeService;
...
@ComponentImport @Autowired private AccessModeService accessModeService;

I suppose javaconfig importOsgiService should also work on the interface. You can’t use it on DefaultAccessModeCompatService because that’s a bean that’s set up by the compat lib within your own app’s spring context.

@NikhilJain As @scott.dudley already mentioned: I hope you will also publish all the artifacts that are referenced by the maven modules from the milestones, because otherwise we still won’t be able to compile against it.

Being able to compile against a milestone is crucial in compatibility testing and for providing early feedback. If we have to wait for a week after an EAP milestone is published, there is little point in using it at all because by that time there’s typically a new one.

Please don’t put additional obstacles like this in our way. We are already spending a lot of time with the compatibility efforts and this doesn’t help at all.

3 Likes

Hi all,

Please accept my sincere apologies for 9.0.0-m41 artifacts being unavailable. This was a result of new internal security requirements that have begun rolling out, and was an oversight in release publishing that we have now been able to work through.

All artifacts for 9.0.0-m41 should now be available for consumption.

Please do let me know if you come across any outliers, I will endeavour to investigate on priority.

Kind regards.

5 Likes

I had missed the fact that 1.6.2 and 1.6.3 versions of confluence-compat-lib were recently released.

The new version probably has the solution for the problem of the compat library being compiled against a version of atlassian-spring that doesn’t work on Platform 7 (maybe?)… which I suspect causes:

[INFO] [talledLocalContainer] java.lang.IncompatibleClassChangeError: Class com.atlassian.spring.container.LazyComponentReference does not implement the requested interface com.atlassian.util.concurrent.Supplier
[INFO] [talledLocalContainer] 	at com.atlassian.confluence.compat.api.service.accessmode.impl.DefaultAccessModeCompatService.getAccessModeService(DefaultAccessModeCompatService.java:40)
[INFO] [talledLocalContainer] 	at com.atlassian.confluence.compat.api.service.accessmode.impl.DefaultAccessModeCompatService.isReadOnlyAccessModeEnabled(DefaultAccessModeCompatService.java:21)

Anyways, my workaround to stop using the compat lib works fine because all I need is the isReadOnlyAccessModeEnabled method and it is available in the “new” AccessModeService in Confluence 7.19+.

I’ll start a habit of checking Atlassian’s maven repository for new versions: https://packages.atlassian.com/mvn/maven-external/com/atlassian/confluence/compat/confluence-compat-lib/ … I had accidentally been peeking at the wrong maven repository and had only seen the old 1.6.1 version… don’t know why my IDE didn’t notify me of the more recent versions

Hi @JamesWhitehead

BUG 1)

I don’t know if it’s because of the lack of the m41 version for this artifact, but so far everything has worked without a problem, since the m41 version I get an error as below.

[INFO] [talledLocalContainer] Caused by: java.lang.NoClassDefFoundError: com/atlassian/confluence/plugins/ia/service/SidebarLinkService
[INFO] [talledLocalContainer] 	at java.base/java.lang.Class.getDeclaredFields0(Native Method)
[INFO] [talledLocalContainer] 	at java.base/java.lang.Class.privateGetDeclaredFields(Class.java:3297)
[INFO] [talledLocalContainer] 	at java.base/java.lang.Class.getDeclaredFields(Class.java:2371)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.internal.util.ReflectionHelper$4.run(ReflectionHelper.java:290)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.internal.util.ReflectionHelper$4.run(ReflectionHelper.java:287)
[INFO] [talledLocalContainer] 	at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.model.IntrospectionModeller.checkResourceClassFields(IntrospectionModeller.java:203)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.model.IntrospectionModeller.doCreateResourceBuilder(IntrospectionModeller.java:117)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.model.IntrospectionModeller.access$000(IntrospectionModeller.java:58)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.model.IntrospectionModeller$1.call(IntrospectionModeller.java:90)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.model.IntrospectionModeller$1.call(IntrospectionModeller.java:87)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)

I tried to add a dependency to pom (m34, because there is no m41) but it still has the same error

        <dependency>
            <groupId>com.atlassian.confluence.plugins</groupId>
            <artifactId>confluence-nav-links</artifactId>
            <version>9.0.0-m34</version>
            <scope>provided</scope>
        </dependency>

BUG 2

9.0.0-m41 broke all my REST API’a :frowning:

[INFO] [talledLocalContainer] io.atlassian.util.concurrent.LazyReference$InitializationException: java.lang.IllegalStateException: The resource configuration is not modifiable in this context.
[INFO] [talledLocalContainer] 	at io.atlassian.util.concurrent.LazyReference.getInterruptibly(LazyReference.java:156)
[INFO] [talledLocalContainer] 	at io.atlassian.util.concurrent.LazyReference.get(LazyReference.java:116)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.servlet.DefaultServletModuleManager.getInstance(DefaultServletModuleManager.java:432)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.servlet.DefaultServletModuleManager.getFilter(DefaultServletModuleManager.java:425)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.servlet.DefaultServletModuleManager.getFilters(DefaultServletModuleManager.java:290)
[INFO] [talledLocalContainer] 	at com.atlassian.plugins.rest.v2.servlet.DefaultRestServletModuleManager.getFilters(DefaultRestServletModuleManager.java:201)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:54)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter.doFilter(ServletFilterModuleContainerFilter.java:44)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.servlet.filter.DelegatingPluginFilter.doFilter(DelegatingPluginFilter.java:62)
[INFO] [talledLocalContainer] 	at com.atlassian.confluence.plugin.servlet.filter.AccessCheckPluginDelegateFilter.doFilter(AccessCheckPluginDelegateFilter.java:34)
[INFO] [talledLocalContainer] 	at com.atlassian.plugin.servlet.filter.IteratingFilterChain.doFilter(IteratingFilterChain.java:37)

BUG 3

All classes that have my own class in their constructor, exported as service, report an error:

@ExportAsService({MyHelper.class})
@Named("myHelper")
[INFO] [talledLocalContainer] java.lang.NoSuchMethodException: Could not find a suitable constructor in com.myapp.test.MyOwnUtils class.
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.inject.hk2.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:168)
[INFO] [talledLocalContainer] 	at org.jvnet.hk2.internal.Utilities.getConstructor(Utilities.java:156)
[INFO] [talledLocalContainer] 	at org.jvnet.hk2.internal.Utilities.justCreate(Utilities.java:1042)
[INFO] [talledLocalContainer] 	at org.jvnet.hk2.internal.ServiceLocatorImpl.create(ServiceLocatorImpl.java:968)
[INFO] [talledLocalContainer] 	at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1072)
[INFO] [talledLocalContainer] 	at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1064)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.createAndInitialize(AbstractHk2InjectionManager.java:201)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.createAndInitialize(ImmediateHk2InjectionManager.java:30)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:123)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:260)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:51)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:86)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89)
[INFO] [talledLocalContainer] 	at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89)

It seems to me that this version (m41) is probably not entirely suitable for testing, everything worked fine in the previous ones

UPDATE:

BUG 1) Still exist - Is this a bug in recent versions (m41 and m48) or has something changed?

<confluence.version>9.0.0-m48</confluence.version>
<platform.version>7.0.0-m57</platform.version>

BUG 2) After commenting everything with SidebarLinkService the error does not occur

BUG 3) I fixed it by adding @Inject to every constructor that has @ConfluenceImport and importing custom services

Cheers
Adam

2 Likes

Hi Adam,

Can you please share the complete stack trace for Bug2 and Bug3. Currently it is very high level.
For Bug1 i will get back to you

Regards
Nikhil Jain