Error creating bean with name 'userManager'

Hello, I’m having an issue with getting an admin config page setup with the Injection flags and the PluginSettingsFactory.

I get this error on load.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userManager': FactoryBean threw exception on object creation; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.sun.proxy.$Proxy3022
Full Stack Trace
[INFO] [talledLocalContainer] 2020-08-26 16:18:38,805 ERROR [ThreadPoolAsyncTaskExecutor::Thread 35] [plugin.osgi.factory.OsgiPlugin] onPluginContainerFailed Unable to start the plugin container for plugin 'me.nhalstead.confluence.splunkcf.splunkcf'
[INFO] [talledLocalContainer] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userManager': FactoryBean threw exception on object creation; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.sun.proxy.$Proxy3022
[INFO] [talledLocalContainer]   at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:178)
[INFO] [talledLocalContainer]   at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:101)
[INFO] [talledLocalContainer]   at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1674)
[INFO] [talledLocalContainer]   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getObjectForBeanInstance(AbstractAutowireCapableBeanFactory.java:1248)
[INFO] [talledLocalContainer]   at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:257)
[INFO] [talledLocalContainer]   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
[INFO] [talledLocalContainer]   at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:842)
[INFO] [talledLocalContainer]   at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.access$1600(AbstractDelegatedExecutionApplicationContext.java:57)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext$4.run(AbstractDelegatedExecutionApplicationContext.java:322)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.util.internal.PrivilegedUtils.executeWithCustomTCCL(PrivilegedUtils.java:85)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.context.support.AbstractDelegatedExecutionApplicationContext.completeRefresh(AbstractDelegatedExecutionApplicationContext.java:287)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor$CompleteRefreshTask.run(DependencyWaiterApplicationContextExecutor.java:137)
[INFO] [talledLocalContainer]   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[INFO] [talledLocalContainer]   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[INFO] [talledLocalContainer]   at java.lang.Thread.run(Thread.java:748)
[INFO] [talledLocalContainer] Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.sun.proxy.$Proxy3022
[INFO] [talledLocalContainer]   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[INFO] [talledLocalContainer]   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
[INFO] [talledLocalContainer]   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[INFO] [talledLocalContainer]   at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
[INFO] [talledLocalContainer]   at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:739)
[INFO] [talledLocalContainer]   at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:123)
[INFO] [talledLocalContainer]   at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.service.util.internal.aop.ProxyUtils.createProxy(ProxyUtils.java:68)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.service.util.internal.aop.ProxyUtils.createProxy(ProxyUtils.java:37)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.service.importer.support.AbstractServiceProxyCreator.createServiceProxy(AbstractServiceProxyCreator.java:105)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.service.importer.support.OsgiServiceProxyFactoryBean.createProxy(OsgiServiceProxyFactoryBean.java:176)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.service.importer.support.AbstractServiceImporterProxyFactoryBean.getObject(AbstractServiceImporterProxyFactoryBean.java:95)
[INFO] [talledLocalContainer]   at org.eclipse.gemini.blueprint.service.importer.support.OsgiServiceProxyFactoryBean.getObject(OsgiServiceProxyFactoryBean.java:122)
[INFO] [talledLocalContainer]   at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:171)
[INFO] [talledLocalContainer]   ... 15 more

I have followed the tutorial from the Developer Docs found here, not much has been changed but a change was made to the user validation as this tutorial is old and out of date.

Code
package me.nhalstead.confluence.splunkcf.admin;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import javax.inject.Inject;

import com.atlassian.sal.api.pluginsettings.PluginSettings;
import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
import com.atlassian.sal.api.transaction.TransactionCallback;
import com.atlassian.sal.api.transaction.TransactionTemplate;
import com.atlassian.sal.api.user.UserManager;
import com.atlassian.sal.api.user.UserProfile;

@Path("/")
@Scanned
public class ConfigResource
{
	@ComponentImport
	private final UserManager userManager;
	@ComponentImport
	private final PluginSettingsFactory pluginSettingsFactory;
	@ComponentImport
	private final TransactionTemplate transactionTemplate;

	@Inject
	public ConfigResource(UserManager userManager, PluginSettingsFactory pluginSettingsFactory, TransactionTemplate transactionTemplate)
	{
		this.userManager = userManager;
		this.pluginSettingsFactory = pluginSettingsFactory;
		this.transactionTemplate = transactionTemplate;
	}

	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public Response get(@Context HttpServletRequest request) {
		UserProfile user = userManager.getRemoteUser(request);
		if (user == null || !userManager.isSystemAdmin(user.getUserKey())) {
			return Response.status(Status.UNAUTHORIZED).build();
		}

		return Response.ok(transactionTemplate.execute(new TransactionCallback() {
			public Object doInTransaction() {
				PluginSettings settings = pluginSettingsFactory.createGlobalSettings();
				Config config = new Config();
				config.setHost((String) settings.get(Config.class.getName() + ".host"));

				String port = (String) settings.get(Config.class.getName() + ".port");
				if (port != null) {
					config.setPort(Integer.parseInt(port));
				}

				config.setToken((String) settings.get(Config.class.getName() + ".token"));

				return config;
			}
		})).build();
	}

	@PUT
	@Consumes(MediaType.APPLICATION_JSON)
	public Response put(final Config config, @Context HttpServletRequest request) {
		UserProfile user = userManager.getRemoteUser(request);
		if (user == null || !userManager.isSystemAdmin(user.getUserKey())) {
			return Response.status(Status.UNAUTHORIZED).build();
		}

		transactionTemplate.execute(new TransactionCallback() {
			public Object doInTransaction() {
				PluginSettings pluginSettings = pluginSettingsFactory.createGlobalSettings();
				pluginSettings.put(Config.class.getName() + ".host", config.getHost());
				pluginSettings.put(Config.class.getName()  +".port", Integer.toString(config.getPort()));
				pluginSettings.put(Config.class.getName()  +".token", config.getToken());
				return null;
			}
		});
		return Response.noContent().build();
	}

}

Lastly, I’m trying to get the configuration settings stored using PluginSettingsFactory in a Macro (the com.atlassian.confluence.macro.Macro instance) so can I use the same ComponentImport Scanned and Inject annotations to get an instance to read those values?

If anyone has links to any open-source repo(s) with code that is up to date with the confluence server plugins, that would be a help. When looking around not many people who have their code published are using the up to date edition of the Java API or even use the configuration pages etc that the tutorials show you (despite being out of date).

Thanks, Noah

I had a similar issue but it was addressed by changing the dependency to have a scope of provided.

from

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>

to

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

This page may also be useful