JAX-WS: Getting DOMException - HIERARCHY_REQUEST_ERR upon trying to add security headers - soap

I am getting the below exception when I'm trying to add security headers to a SOAP envelope right before the request is sent out.
The exception is thrown upon trying to retrieve the message (so context.getMessage() is throwing the exception).
When I use SoapUI, everything works as planned. I'm using JAXB2 for marshalling on the client side, as well as the web service side.
I'm out of ideas already...Any help would be appreciated!
Thanks!!
P.S. When I take out the security check on the web service side, the exception is still thrown (and caught), but the request goes through, and the response is received without any issues.
Here is my code:
public class SoapSecurityHandler implements SOAPHandler {
private static Logger logger = Logger.getLogger(SoapSecurityHandler.class);
private final String clntUserName = "my_username";
private final String clntPassword = "my_password";
public boolean handleMessage(SOAPMessageContext context) {
logger.info("Enter handleMessage()");
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
try {
logger.info("Getting the message");
SOAPMessage message = context.getMessage();
logger.info("Getting the soappart");
SOAPPart soapPart = message.getSOAPPart();
logger.info("Getting the envelope");
SOAPEnvelope envelope = soapPart.getEnvelope();
logger.info("Getting the factory");
SOAPFactory factory = SOAPFactory.newInstance();
logger.info("Got the factory");
QName name = new QName(
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"Security", "wsse");
SOAPElement securityHeader = factory.createElement(name);
SOAPElement usernameTokenElement = securityHeader.addChildElement("UsernameToken");
SOAPElement usernameElement = usernameTokenElement.addChildElement("Username");
usernameElement.addTextNode(clntUserName);
SOAPElement pwdElement = usernameTokenElement.addChildElement("Password");
pwdElement.addTextNode(clntPassword);
logger.info("Added the username and password to the usernameToken element");
SOAPHeader header = envelope.addHeader();
logger.info("Added the header to the envelope");
header.addChildElement(securityHeader);
logger.info("Added the security header to the header");
} catch (Exception e) {
logger.error("Exception in handler: " + e);
e.printStackTrace();
}
} else {
logger.info("This is an inbound message");
}
logger.info("Exit handleMessage()");
return true;
}
public boolean handleFault(SOAPMessageContext context) {
return false;
}
public void close(MessageContext context) {
//
}
public Set getHeaders() {
return new HashSet();
}
}
org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
at org.apache.axiom.om.impl.dom.ParentNode.insertBefore(ParentNode.java:228)
at org.apache.axiom.om.impl.dom.NodeImpl.appendChild(NodeImpl.java:240)
at org.apache.axis2.saaj.SOAPPartImpl.appendChild(SOAPPartImpl.java:948)
at com.sun.xml.bind.marshaller.SAX2DOMEx.startElement(SAX2DOMEx.java:176)
at com.sun.xml.ws.message.AbstractMessageImpl.writeTo(AbstractMessageImpl.java:158)
at com.sun.xml.ws.message.AbstractMessageImpl.readAsSOAPMessage(AbstractMessageImpl.java:193)
at com.sun.xml.ws.handler.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:84)
at com.sun.xml.ws.handler.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:77)
at com.comcast.cet.web.service.routing.lb.f5.impl.SoapSecurityHandler.handleMessage(SoapSecurityHandler.java:40)
at com.comcast.cet.web.service.routing.lb.f5.impl.SoapSecurityHandler.handleMessage(SoapSecurityHandler.java:1)
at com.sun.xml.ws.handler.HandlerProcessor.callHandleMessage(HandlerProcessor.java:292)
at com.sun.xml.ws.handler.HandlerProcessor.callHandlersRequest(HandlerProcessor.java:133)
at com.sun.xml.ws.handler.ClientSOAPHandlerTube.callHandlersOnRequest(ClientSOAPHandlerTube.java:138)
at com.sun.xml.ws.handler.HandlerTube.processRequest(HandlerTube.java:116)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:598)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:557)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:542)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:439)
at com.sun.xml.ws.client.Stub.process(Stub.java:248)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:135)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:109)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118)
at $Proxy257.getWipInfoForSpecificPoolMember(Unknown Source)
at com.comcast.cet.web.service.routing.lb.LoadBalancerMain.getWipInfo(LoadBalancerMain.java:74)
at com.comcast.cet.web.service.routing.lb.LoadBalancerMain.getFarmStatus(LoadBalancerMain.java:42)
at com.comcast.cet.web.controllers.rpc.RoutingServiceImpl.getFarmStatus(RoutingServiceImpl.java:95)
at sun.reflect.GeneratedMethodAccessor130.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:562)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:544)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:504)
at com.comcast.cet.web.controllers.rpc.RoutingServiceRpcController.processCall(RoutingServiceRpcController.java:64)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:243)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
at com.comcast.cet.web.controllers.rpc.RoutingServiceRpcController.handleRequest(RoutingServiceRpcController.java:41)
at sun.reflect.GeneratedMethodAccessor129.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:42
6)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3496)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(Unknown Source)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2180)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2086)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)

Ok, after a lot of trial and error, this is what I added to the pom.xml to fix the issue:
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-jaxws</artifactId>
<version>1.5.4</version>
</dependency>
Weblogic was using its own impl jars, and they are, as always, outdated.
here are all of the axis2 declarations in my pom.xml file:
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-kernel</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-local</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-jaxws</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.apache.ws.commons.axiom</groupId>
<artifactId>axiom-api</artifactId>
<version>1.2.10</version>
</dependency>
<dependency>
<groupId>org.apache.ws.commons.axiom</groupId>
<artifactId>axiom-impl</artifactId>
<version>1.2.10</version>
</dependency>

I have received the same error after removing the axis2-jaxws-1.6.2.jar file from my classpath.
Actually axis2-jaxws-1.6.2.jar was causing another error so I couldn't put it back and looked for another solution. Finally I fix this error by also removing the axis2-saaj-1.6.2.jar from my classpath.
Removing axis2-saaj-1.6.2.jar prohibited the usage of org.apache.axis2.saaj.SoapPartImpl instead of com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPPart1_1Impl as extension of abstract class javax.xml.soap.SoapPart.
This resolved the issue in my case.

Related

org.apache.shiro.web.filter.authc.LogoutFilter is already configured in ShiroWebModule

I'm using Shiro 1.7.1 and Guice 4.2.3, below is the snippet of my POM file,
<properties>
<shiro.version>1.7.1</shiro.version>
<guice.version>4.2.3</guice.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-guice</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>${guice.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
<version>${guice.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
...
</dependencies>
I'm customizing Shiro's LogoutFilter by creating a new class,
package com.myshiro.myshiro;
import org.apache.shiro.web.filter.authc.LogoutFilter;
public class MyLogoutFilter extends LogoutFilter {
}
and bind org.apache.shiro.web.filter.authc.LogoutFilter to the above customized MyLogoutFilter,
package com.myshiro.myshiro;
public class MyShiroModule extends ShiroWebModule {
public MyShiroModule(ServletContext servletContext) {
super(servletContext);
}
protected void configureShiroWeb() {
try {
bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class));
} catch (NoSuchMethodException e) {
addError(e);
}
bind(org.apache.shiro.web.filter.authc.LogoutFilter.class).to(MyLogoutFilter.class).in(Scopes.SINGLETON);
addFilterChain("/logout", LOGOUT);
}
}
and I try to create the Guice injector in the unit test class like this,
public class MyShiroModuleTest {
#Mock
private ServletContext servletContext;
#Test
public void test() {
Guice.createInjector(new MyShiroModule(servletContext));
}
}
and it failed with the following errors,
1) Binding to null instances is not allowed. Use toProvider(Providers.of(null)) if this is your intended behaviour.
at org.apache.shiro.guice.web.ShiroWebModule.configureShiro(ShiroWebModule.java:136)
2) A binding to org.apache.shiro.web.filter.authc.LogoutFilter was already configured at com.myshiro.myshiro.MyShiroModule.configureShiroWeb(MyShiroModule.java:25).
at org.apache.shiro.guice.web.ShiroWebModule.setupFilterChainConfigs(ShiroWebModule.java:209)
From the second note above, it explained that the binding to org.apache.shiro.web.filter.authc.LogoutFilter is already configured in both MyShiroModule and ShiroWebModule. Do you have any idea of how to bind to my customized LogoutFilter?
This issue did not happened in Shiro 1.3.x.
My sample project is available here, you can see the error simply when you mvn clean install.
Sounds like your problem is related to Guice 4, and less about Shiro. Instead of re-using the same binding key, define a new one, something like:
bind(MyLogoutFilter.class).to(MyLogoutFilter.class).in(Scopes.SINGLETON);
addFilterChain("/logout", Key.get(MyLogoutFilter.class));

Embedded mongodb to spring-boot application java exception

I need to set embedded mongodb in my springboot project but it show infinite error logs. Someone can help me?
I use these dependencies
<!-- https://mvnrepository.com/artifact/de.flapdoodle.embed/de.flapdoodle.embed.mongo -->
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>2.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cz.jirutka.spring/embedmongo-spring -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>3.8.0</version>
<exclusions>
<exclusion>
<groupId>org.mongodb</groupId> <!-- Exclude Project-E from Project-B -->
<artifactId>bson</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-core</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>cz.jirutka.spring</groupId>
<artifactId>embedmongo-spring</artifactId>
<version>1.3.1</version>
</dependency>
And then i configure the mongoTemplate with this method in a configuration class
private static final String MONGO_DB_URL = "localhost";
private static final String MONGO_DB_NAME = "embedded_db";
#Bean
public MongoTemplate mongoTemplate() throws IOException {
EmbeddedMongoFactoryBean mongo = new EmbeddedMongoFactoryBean();
mongo.setBindIp(MONGO_DB_URL);
MongoClient mongoClient = (MongoClient) mongo.getObject();
return new MongoTemplate(mongoClient, MONGO_DB_NAME);
}
But when i run my application it show this error+
Exception in thread "main" 11:56:00.710 [Thread-0] DEBUG de.flapdoodle.embed.process.store.CachingArtifactStore - force delete for PRODUCTION:Windows:B64 and de.flapdoodle.embed.process.extract.ImmutableExtractedFileSet#545997b1
11:56:00.710 [Thread-1] DEBUG de.flapdoodle.embed.mongo.AbstractMongoProcess - try to stop mongod
java.lang.NoSuchMethodError: 'void com.mongodb.client.internal.MongoClientDelegate.<init>(com.mongodb.connection.Cluster, java.util.List, java.lang.Object)'
at com.mongodb.Mongo.<init>(Mongo.java:319)
at com.mongodb.Mongo.<init>(Mongo.java:291)
at com.mongodb.Mongo.<init>(Mongo.java:286)
at com.mongodb.Mongo.<init>(Mongo.java:282)
at com.mongodb.MongoClient.<init>(MongoClient.java:180)
at com.mongodb.MongoClient.<init>(MongoClient.java:155)
at com.mongodb.MongoClient.<init>(MongoClient.java:145)
at cz.jirutka.spring.embedmongo.EmbeddedMongoBuilder.build(EmbeddedMongoBuilder.java:104)
at cz.jirutka.spring.embedmongo.EmbeddedMongoFactoryBean.getObject(EmbeddedMongoFactoryBean.java:52)
at com.nextage.arcacrmconnector.commons.EmbeddedMongoDb.mongoTemplate(EmbeddedMongoDb.java:20)
at com.nextage.arcacrmconnector.commons.MongoTemplateSingleton.setMongoTemplate(MongoTemplateSingleton.java:20)
at com.nextage.arcacrmconnector.commons.MongoTemplateSingleton.getMongoTemplate(MongoTemplateSingleton.java:13)
at com.nextage.arcacrmconnector.services.CommonMongoService.<init>(CommonMongoService.java:12)
at com.nextage.arcacrmconnector.services.LogService.<init>(LogService.java:18)
at com.nextage.arcacrmconnector.consumer.QueueConsumerTimerTask.<init>(QueueConsumerTimerTask.java:23)
at com.nextage.arcacrmconnector.application.Application.<clinit>(Application.java:30)
11:56:00.716 [Thread-0] WARN de.flapdoodle.embed.process.io.file.Files - could not delete C:\Users\DONATE~1\AppData\Local\Temp\extract-70ac2cd1-bb5b-4276-9243-cdf6b52db3famongod.exe. Will try to delete it again when program exits.
Exception in thread "Thread-0" java.lang.IllegalStateException: Shutdown in progress
at java.base/java.lang.ApplicationShutdownHooks.add(ApplicationShutdownHooks.java:66)
at java.base/java.lang.Runtime.addShutdownHook(Runtime.java:213)
at de.flapdoodle.embed.process.io.file.FileCleaner.forceDeleteOnExit(FileCleaner.java:51)
at de.flapdoodle.embed.process.io.file.Files.forceDelete(Files.java:128)
at de.flapdoodle.embed.process.extract.ExtractedFileSets.delete(ExtractedFileSets.java:77)
at de.flapdoodle.embed.process.store.ArtifactStore.removeFileSet(ArtifactStore.java:90)
at de.flapdoodle.embed.process.store.CachingArtifactStore$FilesWithCounter.forceDelete(CachingArtifactStore.java:176)
at de.flapdoodle.embed.process.store.CachingArtifactStore.removeAll(CachingArtifactStore.java:100)
at de.flapdoodle.embed.process.store.CachingArtifactStore$CacheCleaner.run(CachingArtifactStore.java:196)
at java.base/java.lang.Thread.run(Thread.java:830)
How can i fix it? It is a dependency version error?
String tempFile = System.getenv("temp") + File.separator + "extract-" + System.getenv("USERNAME") + "-extractmongod";
String executable;
if (System.getenv("OS") != null && System.getenv("OS").contains("Windows")) {
executable = tempFile + ".exe";
} else {
executable = tempFile + ".sh";
}
Files.deleteIfExists(new File(executable).toPath());
Files.deleteIfExists(new File(tempFile + ".pid").toPath());
please try this temporary solution. write this in mongo config file,This should be executed before the start of embedded mongo db
link is : https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo/issues/171

How to solve java.lang.ClassNotFoundException in appium java?

I have to perform login activity in appium for android application. But I am getting class not found error in my script. My application is opened in but after opening application login not performed.
public class AppiumTest2 {
AppiumDriver driver;
public void setup() throws Exception {
DesiredCapabilities Capabilities = new DesiredCapabilities();
Capabilities.setCapability("deviceName", "codeblaze");
Capabilities.setCapability("platforVersion", "7.0");
Capabilities.setCapability("platformName", "Adnroid");
Capabilities.setCapability("appPackage", "package name");
Capabilities.setCapability("appActivity", "activity name");
driver = new AndroidDriver(new URL("http://0.0.0.0:4723/wd/hub"), Capabilities);
}
public void tearDown() throws Exception {
driver.quit();
}
public void LogInWithInvalidEmail() {
//WebElement emailLoginButton = driver.findElement(By.id("lllogin"));
//emailLoginButton.click();
WebElement emailTextField = (new WebDriverWait(driver,60)).until(ExpectedConditions.presenceOfElementLocated(By.id("etusername")));
emailTextField.sendKeys("Invalid Email");
WebElement passwordTextField = driver.findElement(By.id("etpassword"));
passwordTextField.sendKeys("Random Password");
WebElement loginButton = driver.findElement(By.id("lllogin"));
loginButton.click();
}
}
Actual Result: I am getting below error:
java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils
Expected Result: above mention error should not come and login activity should perform in application.
I was facing the same issue, the RCA was I was using appium-java Client from Reference libraries and Selenium-server jar from Maven Dependency section of my dev tool(Eclipse). That is causing sync in issue when driver is calling Java client to interact with Appium jar.
When I imported java client in my POM this issue resolved for me.
<dependencies>
<!-- http://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-server -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>7.4.1</version>
</dependency>
</dependencies>

Facing java.lang.NoSuchMethodError: org.keycloak.adapters.KeycloakDeployment.setDelegateBearerErrorResponseSending with keycloak

We are trying to secure kafka connect rest api , since it uses embedded jetty server and as of now keycloak does not have any plugin adapters we decided to use keycloak-spring-security-adapter. Server is starting normally but while trying to access any resource it is giving
HTTP ERROR: 500
Problem accessing /. Reason:
java.lang.NoSuchMethodError: org.keycloak.adapters.KeycloakDeployment.setDelegateBearerErrorResponseSending(Z)V
Here is a part of my pom.xml :
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>4.1.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.25.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.containers/jersey-container-servlet -->
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.26</version>
</dependency>
</dependencies>
Here is my security config
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
#Override
protected KeycloakLogoutHandler keycloakLogoutHandler() throws Exception {
return super.keycloakLogoutHandler();
}
#Bean
#Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
#Override
protected void configure(HttpSecurity http) throws Exception
{
super.configure(http);
http
.authorizeRequests()
.antMatchers("/*").hasRole("user")
.antMatchers("/*").hasRole("admin")
.anyRequest().permitAll();
}
}
Here is the code snippet where jetty server is being started.
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addServlet(servletHolder, "/*");
context.addEventListener( new ContextLoaderListener() );
context.setInitParameter( "contextClass", AnnotationConfigWebApplicationContext.class.getName() );
context.setInitParameter( "contextConfigLocation", SecurityConfig.class.getName() );
context.addFilter( new FilterHolder( new DelegatingFilterProxy( "springSecurityFilterChain" ) ), "/*", EnumSet.allOf( DispatcherType.class ));
String allowedOrigins = config.getString(WorkerConfig.ACCESS_CONTROL_ALLOW_ORIGIN_CONFIG);
if (allowedOrigins != null && !allowedOrigins.trim().isEmpty()) {
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
filterHolder.setName("cross-origin");
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, allowedOrigins);
String allowedMethods = config.getString(WorkerConfig.ACCESS_CONTROL_ALLOW_METHODS_CONFIG);
if (allowedMethods != null && !allowedOrigins.trim().isEmpty()) {
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, allowedMethods);
}
context.addFilter(filterHolder, "/*", EnumSet.of(DispatcherType.REQUEST));
}
RequestLogHandler requestLogHandler = new RequestLogHandler();
Slf4jRequestLog requestLog = new Slf4jRequestLog();
requestLog.setLoggerName(RestServer.class.getCanonicalName());
requestLog.setLogLatency(true);
requestLogHandler.setRequestLog(requestLog);
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler[]{context, new DefaultHandler(), requestLogHandler});
/* Needed for graceful shutdown as per `setStopTimeout` documentation */
StatisticsHandler statsHandler = new StatisticsHandler();
statsHandler.setHandler(handlers);
jettyServer.setHandler(statsHandler);
jettyServer.setStopTimeout(GRACEFUL_SHUTDOWN_TIMEOUT_MS);
jettyServer.setStopAtShutdown(true);
try {
jettyServer.start();
} catch (Exception e) {
throw new ConnectException("Unable to start REST server", e);
}
Can anyone please help me understand what that error really means?
Adding full error trace while accessing rest resource :
WARN Error for /sso/login (org.eclipse.jetty.servlet.ServletHandler:667)
java.lang.NoSuchMethodError: org.keycloak.adapters.KeycloakDeployment.setDelegateBearerErrorResponseSending(Z)V
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.attemptAuthentication(KeycloakAuthenticationProcessingFilter.java:141)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:159)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:499)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
Try downgrading version of keycloak-spring-security-adapter to 4.0.0 as follows:
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>4.0.0.Final</version>
</dependency>
org.keycloak.adapters.KeycloakDeployment.setDelegateBearerErrorResponseSending() has been introduced by this commit since 4.1.0.
You built your module with Keycloak 4.1.0 but probably you are using it with Keycloak 4.0.0 or earlier.

Java Config for Spring Gemfire xml

I've defined my Gemfire's "client-cache.xml" as below:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<gfe:pool id="client" subscription-enabled="true">
<gfe:locator host="localhost" port="41114"/>
</gfe:pool>
<gfe:client-cache pool-name="client"/>
<gfe:client-region id="dataRegion" name="dataRegion" pool-name="client" shortcut="PROXY"/>
</beans>
I want to create a corresponding Java Configuration for the same.
I've tried below configuration:
#Resource
private Cache gemfireCache;
#Resource
private Pool client;
#Bean
public PoolFactoryBean client() {
PoolFactoryBean client = new PoolFactoryBean();
client.setSubscriptionEnabled(true);
client.addLocators(new ConnectionEndpoint("localhost", 41114));
return client;
}
#Bean
public ClientRegionFactoryBean<String, AbstractContent> dataRegion() {
ClientRegionFactoryBean<String, AbstractContent> dataRegionFactory = new ClientRegionFactoryBean<>();
dataRegionFactory.setPoolName("client");
dataRegionFactory.setName("dataRegion");
dataRegionFactory.setShortcut(ClientRegionShortcut.PROXY);
return dataRegionFactory;
}
#Bean
public ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean();
clientCacheFactory.setPoolName("client");
clientCacheFactory.setPdxSerializer(mappingPdxSerializer());
return clientCacheFactory;
}
#Bean
public PlatformTransactionManager gemfireTransactionManager() throws Exception {
return new GemfireTransactionManager(gemfireCache);
}
However, I keep running into exception saying :
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.gemstone.gemfire.cache.client.ClientCache] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:372)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:369)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
at org.springframework.data.gemfire.client.PoolFactoryBean.eagerlyInitializeClientCacheIfNotPresent(PoolFactoryBean.java:218)
at org.springframework.data.gemfire.client.PoolFactoryBean.getObject(PoolFactoryBean.java:171)
at org.springframework.data.gemfire.client.PoolFactoryBean.getObject(PoolFactoryBean.java:65)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1590)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
Is it not possible to transform the above XML into Java based configuration?
Any help would be appreciated.
Thanks.
===============Edited below per John's comments==============
#John,
I tried the example mentioned # sample test case for gemfire client and the sample as it is, worked fine.
I'm using locator and the example worked fine with the locators configuration as
gemfirePool.setLocators(Collections.singletonList(new InetSocketAddress(host, port))).
However, I'm using spring-data-gemfire version 1.8.2.RELEASE as per recommendations of Pivotal support.
So, I
upgraded the spring-data-gemfire version to 1.8.2.RELEASE # pom.xml,
fixed the compilation errors
(commented gemfireCache.setLazyInitialize(true)),
and changed gemfirePool.setLocators(Collections.singletonList(new InetSocketAddress(locatorHost, locatorPort))) to gemfirePool.addLocators(Collections.singletonList(new ConnectionEndpoint(locatorHost, locatorPort))),
the test case went for a toss.
The test case started giving me below exception:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:249)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gemfireCache' defined in io.pivotal.gemfire.cache.client.SpringGemFireClientCacheTest$SpringGemFireClientConfiguration: Unsatisfied dependency expressed through constructor argument with index 1 of type [com.gemstone.gemfire.cache.client.Pool]: : Error creating bean with name 'gemfirePool': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.gemstone.gemfire.cache.client.ClientCache] is defined; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gemfirePool': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.gemstone.gemfire.cache.client.ClientCache] is defined
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:753)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:125)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:109)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:261)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 25 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gemfirePool': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.gemstone.gemfire.cache.client.ClientCache] is defined
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:175)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1585)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:254)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 43 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.gemstone.gemfire.cache.client.ClientCache] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:372)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
at org.springframework.data.gemfire.client.PoolFactoryBean.eagerlyInitializeClientCacheIfNotPresent(PoolFactoryBean.java:218)
at org.springframework.data.gemfire.client.PoolFactoryBean.getObject(PoolFactoryBean.java:171)
at org.springframework.data.gemfire.client.PoolFactoryBean.getObject(PoolFactoryBean.java:65)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
... 52 more
So, it looks like, it's an issue with the spring-data-gemfire 1.8.2.RELEASE.
I'm not really sure if I should simply revert back to 1.6.2.RELEASE and, what would I lose on reverting back to a previous revision.
I created another sample spring boot application:
pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.cdk.test
TestGemfireLocators
0.0.1-SNAPSHOT
<parent>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>2.0.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-gemfire</artifactId>
<version>1.8.2.RELEASE</version>
</dependency>
</dependencies>
Application.java
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean(name = "region")
public ClientRegionFactoryBean region(ClientCache gemfireCache, Pool gemfirePool) {
ClientRegionFactoryBean versionedRegion = new ClientRegionFactoryBean();
versionedRegion.setName("region");
versionedRegion.setCache(gemfireCache);
versionedRegion.setPool(gemfirePool);
versionedRegion.setShortcut(ClientRegionShortcut.PROXY);
return versionedRegion;
}
#Bean
public ClientCacheFactoryBean gemfireCache(#Qualifier("gemfireProperties") Properties gemfireProperties,
Pool gemfirePool) {
ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean();
gemfireCache.setPool(gemfirePool);
gemfireCache.setProperties(gemfireProperties);
return gemfireCache;
}
#Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME)
public PoolFactoryBean gemfirePool(#Value("${locator.host}") String host, #Value("${locator.port}") int port) {
PoolFactoryBean gemfirePool = new PoolFactoryBean();
gemfirePool.setName(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME);
gemfirePool.setSubscriptionEnabled(true);
gemfirePool.addLocators(new ConnectionEndpoint(host, port));
return gemfirePool;
}
#Bean
public Properties gemfireProperties(#Value("${gemfire.log.level:config}") String logLevel) {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("log-level", logLevel);
return gemfireProperties;
}
}
The above code too, doesn't work and returns same exception. I tried above code with the default version of "spring-data-gemfire" contained with-in io.spring.platform (1.7.4.RELEASE) and still the same result.
-------------POST John's comments and reference program-------------------
Thanks a lot John. The sample provided by you helped me, however, I had to make a few changes to the code. Below is how my final project looks like (if you notice, I'm injecting GemfireCache instead of ClientCache):
pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.cdk.test
TestGemfireLocators
0.0.1-SNAPSHOT
<parent>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-gemfire</artifactId>
<version>1.8.2.RELEASE</version>
</dependency>
</dependencies>
Application.java
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Resource(name = "myRegion")
private Region<String, Object> myRegion;
int intValue(Long value) {
return value.intValue();
}
String logLevel() {
return System.getProperty("gemfire.log-level", "config");
}
Properties gemfireProperties() {
Properties gemfireProperties = new Properties();
gemfireProperties.setProperty("log-level", logLevel());
return gemfireProperties;
}
#Bean
ClientCacheFactoryBean gemfireCache() {
ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean();
gemfireCache.setClose(true);
gemfireCache.setProperties(gemfireProperties());
return gemfireCache;
}
#Bean(name = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME)
PoolFactoryBean gemfirePool(#Value("${locator.host}") String host, #Value("${locator.port}") int port) {
PoolFactoryBean gemfirePool = new PoolFactoryBean();
gemfirePool.setKeepAlive(false);
gemfirePool.setSubscriptionEnabled(true);
gemfirePool.setThreadLocalConnections(false);
gemfirePool.addLocators(new ConnectionEndpoint(host, port));
return gemfirePool;
}
#Bean(name = "myRegion")
ClientRegionFactoryBean<String, Object> myRegion(#Value("${region.name}") String regionName, GemFireCache gemfireCache,
Pool gemfirePool) {
ClientRegionFactoryBean<String, Object> myRegion = new ClientRegionFactoryBean<>();
myRegion.setCache(gemfireCache);
myRegion.setName(regionName);
myRegion.setPool(gemfirePool);
myRegion.setShortcut(ClientRegionShortcut.PROXY);
return myRegion;
}
#Bean
PlatformTransactionManager gemfireTransactionManager(GemFireCache gemfireCache) {
return new GemfireTransactionManager((Cache) gemfireCache);
}
}
The NoSuchBeanDefinitionException pertains to the injected Cache reference in your application Java configuration class...
#Resource
private Cache gemfireCache
NOTE: you might prefer to use #Inject or Spring's #Autowired annotation instead, since this is technically more accurate.
The problem here is there is no Spring bean defined of type "Cache" in your Spring Java configuration.
If you look more closely at the ClientCacheFactoryBean, getObjectType() method, which Spring uses to inspect bean (definitions) during autowiring of application components "by type", you see that it returns ClientCache.class. Technically, ClientCacheFactoryBean.getObjectType() also returns the actual cache object's type, but I do not recall when Spring inspects the available bean definitions to resolve type dependencies. Plus, I think the Spring container also maintains a type-to-bean mapping (a.k.a. cache) during parsing. The only reason the later is relevant is because GemFire only has 1 implementation of Cache and ClientCache, and that implementation, namely GemFireCacheImpl implements both interfaces. So, it seemingly should be resolvable, but...
Anyway, all of this is to explain the exception with a bit more clarity.
Unfortunately, you cannot use...
return new GemfireTransactionManager(gemfireCache());
Since the gemfireCache() bean definition "method" returns an instance of the ClientCacheFactoryBean and the GemfireTransactionManager constructor expects an instance of Cache.
However, you can define arguments of type Cache, ClientCache and GemFireCache as needed by the SDG FactoryBeans. For instance, your gemfireTransactionManager bean can be defined as...
#Bean
public PlatformTransactionManager gemfireTransactionManager(GemFireCache gemfireCache) {
return new GemfireTransactionManager((Cache) gemfireCache));
}
NOTE: ClientCache extends GemFireCache.
Likewise, your Region bean definition, "dataRegion" also expects and can take an instance of the cache like so...
#Bean
public ClientRegionFactoryBean<String, AbstractContent> dataRegion(ClientCache gemfireCache, Pool gemfirePool) {
...
dataRegion.setCache(gemfireCache);
dataRegion.setPool(gemfirePool);
...
}
Also notice, I can pass a reference to the GemFire Pool that the Region should use for data access operations to the cluster servers.
Spring treats Java configuration #Bean definition method parameters as "type dependencies", so you can just defined the expected, resulting bean type required by the bean component in question (e.g. "gemfireTransactionManager" which expects a "Cache" bean dependency).
In general, there is no problem switching from XML to Java configuration. In fact, I encourage it and have even been using Java config more and more in my examples (for instance). In time I plan to convert most of the spring-gemfire-examples over to using Spring Boot and Java configuration.
Speaking of the spring-gemfire-examples, there is also an example with Java config. But, I think this example demonstrates a peer cache. So, you may find the examples in 3 more helpful since I compare and contrast both GemFire native configuration and Spring configuration using both XML and Java.
For instance, my ClientCache Java configuration example has both a GemFire Cache server Java config and client Java config.
Anyway, hope this helps and if you more questions, feel free to reach out.
Cheers,
John
Update - 2016-07-19
Example (& test) for this problem using your GemFire cache client, Spring Java configuration provided here.
Try using the bean method instead of #Resource, e.g.
return new GemfireTransactionManager(gemfireCache());
Running spring boot tests with Geode I had startup error like this (paths redacted):
Invalid bean definition with name 'gemfireCache' defined in class path resource... CacheServerConfiguration... There is already... ClientCacheConfiguration... defined in class path resource... bound
It was fixed by adding
spring.main.allow-bean-definition-overriding=true to my application.properties file