Creating JAAS Configuration Using Java in Felix OSGI - apache-felix

I want to set a default JAAS configuration in Apache Sling for a SAML2 sign on bundle (not using the /system/console/configMgr UI)
jaas.classname="org.apache.sling.auth.saml2.sp.Saml2LoginModule"
jaas.controlFlag="Sufficient"
jaas.ranking=110
jaas.realmName="jackrabbit.oak"
I am considering two options:
A) Creating a "config" node in a JCR Filevault package under /apps
B) Creating the configuration using Java in a bundle's activate method
Approach A works OK upon package install. It does set the configuration I want, but upon restart Sling is not happy, and never completes start up. There is an error in the logs shown below. I interpret this as some kind of timing conflict as bundle mentioned in the JAAS config which provides the LoginModule is not activated yet. (Feel free to post your thoughts about that)
Approach A ERROR upon restart...
27.06.2020 14:28:45.985 ERROR [Apache Sling Resource Provider Change Notifier] org.apache.sling.extensions.threaddump.internal.Activator Uncaught exception in Thread Thread[Apache Sling Resource Provider Change Notifier,5,main]
java.lang.AssertionError: No bundle exists to create LoginModule from org.apache.sling.auth.saml2.sp.Saml2LoginModule
at org.apache.felix.jaas.internal.BundleLoginModuleCreator.newInstance(BundleLoginModuleCreator.java:59) [org.apache.felix.jaas:1.0.2]
at org.apache.felix.jaas.internal.ConfigLoginModuleProvider.createLoginModule(ConfigLoginModuleProvider.java:80) [org.apache.felix.jaas:1.0.2]
at org.apache.felix.jaas.boot.ProxyLoginModule.initialize(ProxyLoginModule.java:46) [org.apache.felix.jaas:1.0.2]
at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:716)
at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:665)
at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:663)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:663)
at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:574)
at org.apache.jackrabbit.oak.core.ContentRepositoryImpl.login(ContentRepositoryImpl.java:163) [org.apache.jackrabbit.oak-core:1.26.0]
at org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl.login(RepositoryImpl.java:282) [org.apache.jackrabbit.oak-jcr:1.26.0]
at org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl.login(RepositoryImpl.java:225) [org.apache.jackrabbit.oak-jcr:1.26.0]
at org.apache.jackrabbit.oak.jcr.session.SessionImpl.impersonate(SessionImpl.java:275) [org.apache.jackrabbit.oak-jcr:1.26.0]
at org.apache.sling.jcr.oak.server.internal.TcclWrappingJackrabbitSession.impersonate(TcclWrappingJackrabbitSession.java:84) [org.apache.sling.jcr.oak.server:1.2.4]
at org.apache.sling.jcr.base.AbstractSlingRepository2.createServiceSession(AbstractSlingRepository2.java:205) [org.apache.sling.jcr.base:3.1.0]
at org.apache.sling.jcr.base.AbstractSlingRepository2.createServiceSession(AbstractSlingRepository2.java:170) [org.apache.sling.jcr.base:3.1.0]
at org.apache.sling.jcr.base.AbstractSlingRepository2.loginService(AbstractSlingRepository2.java:383) [org.apache.sling.jcr.base:3.1.0]
at org.apache.sling.jcr.resource.internal.helper.jcr.JcrProviderStateFactory.createProviderState(JcrProviderStateFactory.java:115) [org.apache.sling.jcr.resource:3.0.20]
at org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProvider.authenticate(JcrResourceProvider.java:303) [org.apache.sling.jcr.resource:3.0.20]
at org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProvider.authenticate(JcrResourceProvider.java:75) [org.apache.sling.jcr.resource:3.0.20]
at org.apache.sling.resourceresolver.impl.providers.stateful.ProviderManager.authenticate(ProviderManager.java:161) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.providers.stateful.ProviderManager.getOrCreateProvider(ProviderManager.java:87) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.providers.stateful.ProviderManager.authenticateAll(ProviderManager.java:129) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.ResourceResolverImpl.createControl(ResourceResolverImpl.java:143) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.ResourceResolverImpl.(ResourceResolverImpl.java:104) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.ResourceResolverImpl.(ResourceResolverImpl.java:98) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.CommonResourceResolverFactoryImpl.getResourceResolverInternal(CommonResourceResolverFactoryImpl.java:280) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.ResourceResolverFactoryImpl.getServiceResourceResolver(ResourceResolverFactoryImpl.java:89) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.i18n.impl.JcrResourceBundleProvider.createResourceResolver(JcrResourceBundleProvider.java:163) [org.apache.sling.i18n:2.5.14]
at org.apache.sling.i18n.impl.JcrResourceBundleProvider.onChange(JcrResourceBundleProvider.java:266) [org.apache.sling.i18n:2.5.14]
at org.apache.sling.i18n.impl.JcrResourceBundleProvider.onChange(JcrResourceBundleProvider.java:216) [org.apache.sling.i18n:2.5.14]
at org.apache.sling.resourceresolver.impl.observation.BasicObservationReporter.reportChanges(BasicObservationReporter.java:211) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.observation.BasicObservationReporter.reportChanges(BasicObservationReporter.java:189) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker.postResourceProviderChange(ResourceProviderTracker.java:406) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker.access$400(ResourceProviderTracker.java:59) [org.apache.sling.resourceresolver:1.6.16]
at org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker$2.run(ResourceProviderTracker.java:517) [org.apache.sling.resourceresolver:1.6.16]
at java.base/java.lang.Thread.run(Thread.java:834)
With Approach B I don't think I there will be this race condition or timing issue, and it should be possible to write a configuration using the Java code below.
void createSaml2Jaas(){
logger.info("create saml2 jaas");
try {
Configuration jaasConfig = configAdmin.createFactoryConfiguration(JAAS_SAML2PID);
Dictionary<String, Object> properties = new Hashtable<>();
properties.put("jaas.classname", "org.apache.sling.auth.saml2.sp.Saml2LoginModule");
properties.put("jaas.controlFlag", "Sufficient");
properties.put("jaas.ranking","110");
properties.put("jaas.realmName","jackrabbit.oak");
jaasConfig.update(properties);
} catch (IOException e) {
logger.error("Problem creating JAAS Configs", e);
}
}
This creates an OSGI config, but it is not bound properly. The config as shown in the Web Console states the following
This form is automatically generated from existing properties because no property descriptors are available for this configuration. This may be cause by the absence of the OSGi Metatype Service or the absence of a MetaType descriptor for this configuration.
Question: What do I need to do to create an org.apache.felix.jaas.Configuration.factory OSGI Config programmatically (or via a package) that is properly bound without causing problems with application startup?

Admittedly, my 'problem' is a little different than the exact 'question' posted. With regard to the question, I would still like to know how to write Felix OSGI configurations for a bundle using Java code.
There is a solution in this post
How is the OSGi bundle start level defined? about setting the bundle startup value. Apache Sling JCR Installer (org.apache.sling.installer.provider.jcr) is the bundle responsible for creating OSGI configurations from definitions in JCR nodes under '/apps' under 'runmode/config' This bundle has a Start Level of 20.
Changing the start level of my bundle from 20 to 19. Resolved the Java exception printed in the error.log
public class Activator implements BundleActivator {
private static final int START_LEVEL = 19;
public void start(BundleContext context) throws Exception {
context.getBundle().adapt(BundleStartLevel.class).setStartLevel(START_LEVEL);

Related

Spring Boot Geode Unsatisfied dependency expressed through method 'sessionRegion'

The correct dependencies for my gradle.build are driving me crazy!
In order to access an Apache Geode 1.10 server, I am using:
// Geode client dependency
implementation 'org.springframework.geode:spring-geode-starter:1.2.13.RELEASE'
implementation 'org.springframework.data:spring-data-geode:2.2.12.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-tomcat:2.2.13.RELEASE'
This fails with the error:
org.springframework.context.support.AbstractApplicationContext 596 refresh:
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'ClusteredSpringSessions' defined in class path resource
[org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.class]:
Unsatisfied dependency expressed through method 'sessionRegion' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app')
What is there to tell me the dependency missing for the UnsatisfiedDependencyException for 'ClusteredSpringSessions'?
If I remove the #EnableGemFireHttpSession annotation then I get the error
2021-02-02T19:29:49,011 WARN [main] org.springframework.context.support.AbstractApplicationContext 596 refresh:
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'cacheManager' defined in class path resource [org/springframework/data/gemfire/cache/config/GemfireCachingConfiguration.class]:
Unsatisfied dependency expressed through method 'cacheManager' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app')
What is there to tell me the dependency missing for the UnsatisfiedDependencyException for 'cacheManager'?
Thanks
UPDATE The App is run like Spring Boot #ComponentScan finds candidate component class but does not inject #Configuration beans but more specifically
#SpringBootApplication
#ComponentScan({"api", "rsocket", "pricing", "listeners", "dealing", "web"}) // scans packages for # components
#EnableLogging(logLevel="debug", logFile="geodeApi.log")
public class Api {
private static final Logger log = LogManager.getLogger(Api.class);
public static void main(String[] args) {
log.info("In Main");
SpringApplication app = new SpringApplication(Api.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
SpringApplication.run(Api.class, args);
log.info("Out Main");
}
}
The component scan finds various #Component annotated classes for example
#Component
#EnableClusterDefinedRegions(clientRegionShortcut=ClientRegionShortcut.PROXY)
public class ClientCache {
private static final Logger log = LogManager.getLogger(ClientCache.class);
#Resource
private Region<String, String> admin;
#Autowired
LQuote lQuote;
#Autowired
LReject lReject;
#Autowired
LDeal lDeal;
#Autowired
DealNumber dealNumber;
#Autowired
PriceService priceService;
#PreDestroy
public void onDestroy() throws Exception {
log.info("onDestroy");
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
admin.put(guid, "API Shutdown");
// TODO: Cancel all open quote streams
log.traceExit();
}
#Bean
ApplicationRunner StartedUp(){
log.traceEntry("StartedUp");
return args -> {
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
admin.put(guid, "API Started");
lQuote.addListener();
lReject.addListener();
lDeal.addListener();
// Get latest deal number
int currentId = dealNumber.readCurrentId();
// Set it + 1 in case the web server was reboot on the fly
priceService.setCurrentId(currentId + 1);
log.traceExit();
};
}
A lot of the problem was using Java JDK version 15.
The correct versions require Java 11.
// Geode client dependency
implementation 'org.springframework.geode:spring-geode-starter:1.2.8.RELEASE'
implementation 'org.springframework.data:spring-data-geode:2.2.8.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-tomcat'
Technically, it is not necessary to explicitly declare the SDG dependency.
The SBDG dependency (i.e. org.springframework.geode:spring-geode-starter) already includes SDG (org.springframework.data:spring-data-geode). You can follow the dependency trail starting here, then here and finally, here.
As the Version Compatibility Matrix for SBDG specifies, SBDG 1.2.13.RELEASE specifically includes, and is based on, SDG 2.2.12.RELEASE (already), which is (technically) based on Apache Geode 1.9.2.
However, if you need to use Apache Geode 1.10, then you could (recommended) simply declare dependency management to enforce the use of Apache Geode 1.10 in your Gradle build:
plugins {
id 'org.springframework.boot' version '2.2.13.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
dependencyManagement {
dependencies {
dependency 'org.apache.geode:geode-core:1.10.0'
dependency 'org.apache.geode:geode-cq:1.10.0'
dependency 'org.apache.geode:geode-lucene:1.10.0'
dependency 'org.apache.geode:geode-wan:1.10.0'
}
}
dependencies {
implementation 'org.springframework.geode:spring-geode-starter:1.2.13.RELEASE`
implementation 'org.springframework.boot:spring-boot-starter-tomcat'
}
...
WARNING: SDG 2.2.12.RELEASE is officially based on Apache Geode 1.9.2, and though it should work reasonably well with Apache Geode 1.10, there could expectedly be limitations in certain use cases.
This is not unlike what Spring Initializer conveniently generates for you. Of course, Spring Initializer now uses the new SBDG BOM that makes managing individual SBDG module dependencies even easier, which is not unlike how Spring Boot's dependency management manages transitive dependencies, including 3rd party libs.
Regarding the Exceptions...
It really seems to me like you are having configuration problems rather than dependency problems, actually.
Of course, it is hard to say for certain given you shared very minimal Gradle build configuration and no code snippets from your Spring Boot application configuration, only mentions and what I am able to derive from the Exception messages. So, for now, I'll proceed based on what you provided and what I know or could derive.
Looking at this part of the (first) Exception message:
Error creating bean with name 'ClusteredSpringSessions' defined in class path resource
[org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.class]:
Unsatisfied dependency expressed through method 'sessionRegion' parameter 0
And, specifically:
Unsatisfied dependency expressed through method 'sessionRegion' parameter 0
This message refers to the (Spring Java) configuration provided by SSDG and imported/auto-configured by SBDG.
The "Unsatisfied dependency", or "parameter 0", is the 1st method parameter in the sessionRegion(..) (Spring JavaConfig-based) #Bean definition method declared in SSDG's configuration. It is the dependency on the GemFire cache instance (e.g. ClientCache) required to create the "ClusteredSpringSessions" Region.
So now, the question becomes, how is the cache created?
Well, this is what the framework is trying to do next... resolve the cache bean dependency (instance reference), which necessary triggers the cache creation first (due to dependency order)...
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError
We see that an IllegalAccessError occurred (O.o) which already smells like a version problem to me, but...
The ClientCacheConfiguration is provided by SDG.
Finally, we arrive at the underlying cause...
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
NOTE: ClientCacheConfiguration extends AbstractCacheConfiguration, which extends AbstractAnnotationConfigSupport, and therefore should have "access" to the protected hasValue(:Number) method.
The main Thread appears to be in one of these Lambdas where the AbstractAnnotationConfig.hasValue(:Number) method is used.
I am no entirely sure what this means...
org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$703/0x0000000801025d10
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app'
Are you possibly using Spring Boot's new (Layered) Docker Image support by chance?
The 2nd Exception message (involving the cacheManager bean this time) leads to the same outcome, actually. It is no different, but simply involves another bean (i.e. cacheManager bean) with the same dependency on the cache instance:
Error creating bean with name 'cacheManager' defined in class path resource
[org/springframework/data/gemfire/cache/config/GemfireCachingConfiguration.class]
: Unsatisfied dependency expressed through method 'cacheManager' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.data.gemfire.config.annotation.ClientCacheConfiguration':
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
class org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
tried to access protected method 'boolean org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport.hasValue(java.lang.Number)'
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport are in unnamed module of loader 'app')
And, specifically:
Initialization of bean failed; nested exception is java.lang.IllegalAccessError:
tried to access protected method 'boolean org.springframework.data.gemfire
.config.annotation.support.AbstractAnnotationConfigSupport
.hasValue(java.lang.Number)'
And:
(org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration$$Lambda$679/0x00000008010306b8
and org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
are in unnamed module of loader 'app')
I am not familiar with this error messages (basically, said class(es) "are in unnamed module of loader 'app'.") What?
How is this Spring Boot app being run?
Definitely providing a sample app, one or more tests, your configuration, logs, Stack Traces in addition to Exception messages, setup, runtime environment, etc, etc, will go along way in trying to understand the context of this problem.
At this point, I am really trying to point you in a direction to start untangling the problem.
Sorry, I cannot (currently) be of more help in this case.

started geode spring boot and save to remote region but failed to start bean gemfireClusterSchemaObjectInitializer

With a simple client app, make an object and object repository, connect to a Geode cluster, then run a #Bean ApplicationRunner to put some data to a remote region.
#ClientCacheApplication(name = "Web", locators = #Locator, logLevel = "debug", subscriptionEnabled = true)
#EnableClusterDefinedRegions
#EnableClusterConfiguration(useHttp = true)
#EnablePdx
public class MyCache {
private static final Logger log = LoggerFactory.getLogger(MyCache.class);
#Bean
ApplicationRunner StartedUp(MyRepository myRepo){
log.info("In StartedUp");
return args -> {
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
MyObject msg = new MyObject(guid, "Started");
myRepo.save(msg);
log.info("Out StartedUp");
};
}
The "save" put fails with
org.springframework.context.ApplicationContextException: Failed to start bean 'gemfireClusterSchemaObjectInitializer'; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://localhost:7070/gemfire/v1/regions": Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect
Problem creating region and persist region to disk Geode Gemfire Spring Boot helped. The problem is the #EnableClusterConfiguration(useHttp = true)
This annotation makes the remote cluster appear to be a localhost. If I remove it altogether then the put works.
If remove just the useHttp = true there is another error:
org.springframework.context.ApplicationContextException: Failed to start bean 'gemfireClusterSchemaObjectInitializer'; nested exception is org.apache.geode.cache.client.ServerOperationException: remote server on #.#.#.#(Web:9408:loner)### The function is not registered for function id CreateRegionFunction
In a nutshell, the SDG #EnableClusterConfiguration annotation (details available here) enables configuration metadata defined and declared on the client (i.e. Spring [Boot] Data, GemFire/Geode application) to be pushed from the client-side to the cluster (of GemFire/Geode servers).
I say "enable" because it depends on the client-side configuration metadata (i.e. Spring bean definitions you have explicitly or implicitly defined/declared). Explicit configuration is configuration you defined with a bean definition (in XML, or JavaConfig with #Bean, etc). Implicit configuration is auto-configuration or using SDG annotations like #EnableEntityDefinedRegions or #EnableCachingDefinedRegions, etc.
By default, the #EnableClusterConfiguration annotation assumes the cluster of GemFire or Geode servers were configured and bootstrapped with Spring, and specifically using the SDG Annotation configuration model. When the GemFire or Geode servers are configured and bootstrapped with Spring, then SDG goes on to register some provided, canned GemFire Functions that the #EnableClusterConfiguration annotation calls (by default and...) as a fallback.
NOTE: See the appendix in the SBDG reference documentation on configuring and bootstrapping a GemFire or Geode server, or even a cluster of servers, with Spring. This certainly simplifies local development and debugging as opposed to using Gfsh. You can do all sorts of interesting combinations: Gfsh Locator with Spring servers, Spring [embedded|standalone] Locator with both Gfsh and Spring servers, etc.
Most of the time, users are using Spring on the client and Gfsh to (partially) configure and bootstrap their cluster (of servers). When this is the case, then Spring is generally not on the servers' classpath and the "provided, canned" Functions I referred to above are not present and automatically registered. In which case, you must rely on GemFire/Geodes internal, Management REST API (something I know a thing or 2 about, ;-) to send the configuration metadata from the client to the server/cluster. This is why the useHttp attribute on the #EnableClusterConfiguration annotation must be set to true.
This is why you saw the Exception...
org.springframework.context.ApplicationContextException: Failed to start bean 'gemfireClusterSchemaObjectInitializer';
nested exception is org.apache.geode.cache.client.ServerOperationException: remote server on #.#.#.#(Web:9408:loner)###
The function is not registered for function id CreateRegionFunction
The CreateRegionFunction is the canned Function provided by SDG out of the box, but only when Spring is used to both configure and bootstrap the servers in the cluster.
This generally works well for CI/CD environments, and especially our own test infrastructure since we typically do not have a full installations of either Apache Geode or Pivotal GemFire available to test with in those environments. For 1, those artifacts must be resolvable from and artifact repository like Maven Central. The Apache Geode (and especially) Pivotal GemFire distributions are not. The JARs are, but the full distro isn't. Anyway...
Hopefully, all of this makes sense up to this point.
I do have a recommendation if I may.
Given your application class definition begins with...
#ClientCacheApplication(name = "Web", locators = #Locator,
logLevel = "debug", subscriptionEnabled = true)
#EnableClusterDefinedRegions
#EnableClusterConfiguration(useHttp = true)
#EnablePdx
public class MyCache { ... }
I would highly recommend simply using Spring Boot for Apache Geode (and Pivotal GemFire), i.e. SBDG, in place of SDG directly.
Your application class could then be simplified to:
#SpringBootApplication
#EnableClusterAware
#EnableClusterDefinedRegions
public class MyCache { ... }
You can then externalize some of the hard coded configuration settings using the Spring Boot application.properties file:
spring.application.name=Web
spring.data.gemfire.cache.log-level=debug
spring.data.gemfire.pool.subscription-enabled=true
NOTE: #EnableClusterAware is a much more robust and capable extension of #EnableClusterConfiguration. See additional details here.
Here are a few resources to get you going:
Project Overview
Getting Started Sample Guide
Use Case Driven Guides/Samples
Useful resources in the Appendix TOC.
Detailed information on SBDG provided Auto-configuration.
Detailed information on Declarative Configuration.
Detailed information on Externalized Configuration.
In general, SBDG, which is based on SDG, SSDG and STDG, is the preferred/recommended starting point for all things Spring for Apache Geode and Pivotal GemFire (or now, Pivotal Cloud Cache).
Hope this helps.

Resteasy Bean Validation Not Working on Remote Server

I have a problem similar to the one described here.
I am using RESTEasy within a standalone Jetty application. When I start the application locally and call a service (e.g. localhost:16880/rest/user/login) bean validation works fine, i.e. I get validation errors like this:
[PARAMETER]
[UserService#login(arg0).appKey]
[app_key may not be null or empty]
[]
However, when I deploy my application to a remote host and call the same service (e.g. remotehost:16880/rest/user/login) bean validation is not invoked at all.
I am using the #ValidateRequest annotation for the service and #Valid annotation for the bean parameter.
My Resteasy version is 3.0.13.Final, though I have tried earlier versions as well. I have tried to write my custom validator, but that didn't work either.
I am puzzled why the validation works locally, but not on remote server. Any suggestions would be highly appreciated.
Since you are using Jetty as standalone server, you have to define RESTEasy validation providers where you define ServletContextHandler. Note that in standalone server there is no container to scan for #Provider classes and to activate them, so you must do it manually.
I expect that you create and start your server app something like:
//create a server listening at some port
Server server= new Server(port);
//add server handlers
HandlerList handlers= new HandlerList();
initHandlers(handlers);
server.setHandler(handlers);
//start the server
server.start();
In initHandlers you must have defined your RESTEasy support:
public void initHandlers(List<HandlerList> handlers) {
//define root context handler
ServletContextHandler servletContextHandler= new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContextHandler.setContextPath("/");
handlers.addHandler(servletContextHandler);
//define RESTEasy handler
ServletHolder restServlet= new ServletHolder(new HttpServlet30Dispatcher());
//since this is a standalone server, somewhere you have to define RESTful services and Singletons
restServlet.setInitParameter("javax.ws.rs.Application", "com.exampleapp.MyRestApplication");
restServlet.setInitParameter("resteasy.servlet.mapping.prefix", "rest");
servletContextHandler.addServlet(restServlet, "rest/*");
}
So what is left to do now is to add Validation provider as init parameter:
restServlet.setInitParameter("resteasy.providers", "org.jboss.resteasy.plugins.validation.ValidatorContextResolver,org.jboss.resteasy.api.validation.ResteasyViolationExceptionMapper");
On this link I tried to find the name of the validator providers: https://docs.jboss.org/resteasy/docs/3.0.4.Final/userguide/html/Validation.html
RESTEasy obtains a bean validation implemenation by looking in the available META-INF/services/javax.ws.rs.Providers files for an implementation of ContextResolver
So it does not say what, but says where. Now open the "resteasy-hibernatevalidator-provider-3...*.jar (from Eclipse -> Maven dependencies or manually unzip) and look into META-INF/services/javax.ws.rs.ext.Providers It says:
org.jboss.resteasy.plugins.validation.hibernate.ValidatorContextResolver
org.jboss.resteasy.api.validation.ResteasyViolationExceptionMapper
If you don't have this dependency, then add it to your pom file:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-hibernatevalidator-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
One more note: that at the same place where you described validation providers, you also add other providers, if you happen to need them (such as JacksonJaxbJson, etc).

Cannot derive user name for bundle org.demo.anthony.mybundle.core [446] and sub service null

I have a bundle that was working completely fine in AEM 6. I just upgraded to AEM 6.1 and when I deploy the bundle, I'm getting the error below:
javax.jcr.LoginException: Cannot derive user name for bundle
org.demo.anthony.mybundle.core [446] and sub service null at
org.apache.sling.jcr.base.AbstractSlingRepository2.loginService(AbstractSlingRepository2.java:336)
at
org.demo.anthony.mybundle.core.impl.EvernoteSyncServiceImpl.getSession(EvernoteSyncServiceImpl.java:108)
at
org.demo.anthony.mybundle.core.impl.EvernoteSyncServiceImpl.syncNotes(EvernoteSyncServiceImpl.java:201)
at
org.demo.anthony.mybundle.core.impl.EvernoteSyncServiceImpl.syncWebClipperNotes(EvernoteSyncServiceImpl.java:174)
at
org.demo.nennig.evernote.core.impl.schedulers.EvernoteSyncTask.run(EvernoteSyncTask.java:96)
at
org.apache.sling.commons.scheduler.impl.QuartzJobExecutor.execute(QuartzJobExecutor.java:105)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
This is how I'm getting hold of the session (this is line 108 in the code as referenced in the stacktrace):
session = repository.loginService(null, null);
Until AEM 6.0, the services were allowed to be accessed by default "admin" user. From 6.1, you have to specify a "system user" and/or another user for a specific service. You can define these mapping in Sling Service User Mapper
We had similar issues and below are some of my solutions, see if they'll help:
ResourceResolverFactory getServiceResourceResolver throws Exception in AEM 6.1
How to create a system user (rep:SystemUser) in AEM 6.1?
One more example from Adobe:
https://helpx.adobe.com/experience-manager/using/querying-experience-manager-sling.html

LogManager Exception in JBOSS AS 7.1 with java.util.Logger

I created a java application and initialize a java.util.Logger with that application and run that application as -javaagent with jboss AS 7 server and i got IllegalStateException (i am using eclipse IDE).Here follows my logger initialization code
static public void setup() throws IOException {
// Get the global logger to configure it
Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
logger.setLevel(Level.INFO);
fileTxt = new FileHandler("C:/Users/abc/Desktop/ATAGENT/Logging.txt");
fileHTML = new FileHandler("C:/Users/abc/Desktop/ATAGENT/Logging.html");
// create txt Formatter
formatterTxt = new SimpleFormatter();
fileTxt.setFormatter(formatterTxt);
logger.addHandler(fileTxt);
// create HTML Formatter
formatterHTML = new BMITHtmlFormatter();
fileHTML.setFormatter(formatterHTML);
logger.addHandler(fileHTML);
}
When i create -javaagent jar appended with above lines of code and run with jboss as7 server i got following exception
WARNING: Failed to load the specified log manager class org.jboss.logmanager.LogManager
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.jboss.as.server.Main.main(Main.java:73)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.modules.Module.run(Module.java:260)
at org.jboss.modules.Main.main(Main.java:291)
Caused by: java.lang.IllegalStateException: The LogManager was not properly installed (you must set the "java.util.logging.manager" system property to "org.jboss.logmanager.LogManager")
at org.jboss.logmanager.Logger.getLogger(Logger.java:60)
at org.jboss.logmanager.log4j.BridgeRepositorySelector.(BridgeRepositorySelector.java:42)
... 7 more
And i serched in fourms and i got a solution which is Open the launch configuration for the server definition.
and add -logmodule org.jboss.logmanager to the program arguments before org.jboss.as.standalone.
But it results the same exception with some additional warning. Here follows the exception
WARNING: -logmodule is deprecated. Please use the system property 'java.util.logging.manager' or the 'java.util.logging.LogManager' service loader.
WARNING: Failed to load the specified log manager class org.jboss.logmanager.LogManager
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.jboss.as.server.Main.main(Main.java:73)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.modules.Module.run(Module.java:260)
at org.jboss.modules.Main.main(Main.java:291)
Caused by: java.lang.IllegalStateException: The LogManager was not properly installed (you must set the "java.util.logging.manager" system property to "org.jboss.logmanager.LogManager")
at org.jboss.logmanager.Logger.getLogger(Logger.java:60)
at org.jboss.logmanager.log4j.BridgeRepositorySelector.(BridgeRepositorySelector.java:42)
... 7 more
I had the same problem with JBOSS EAP 6, it took me 2 days for find a solution !.
The cause is that your agent need to create a Logger at statup, he need to be able to access the logmanager classes before JBOSS Modules has been initialized. You need to add JBoss LogManager to the boot classloader. Then, there will be a conflict between LogManager available via ModuleClassLoader and classes loaded via system classloader.
The solution is to make Java Agent and JBoss Modules use the same classloader to load the LogManager classes.
For EAP 6, In your standalone.conf (or domain) (It must be close for your version)
add
JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
JAVA_OPTS="$JAVA_OPTS -Xbootclasspath/p:$JBOSS_HOME/modules/org/jboss/logmanager/main/jboss-logmanager-1.3.1.jar"
and for make Java Agent and JBoss Modules use the same classloader
modify this piece of code in adding org.jboss.logmanager like this :
if [ "x$JBOSS_MODULES_SYSTEM_PKGS" = "x" ]; then
JBOSS_MODULES_SYSTEM_PKGS="org.jboss.byteman,org.jboss.logmanager"
fi
Hope this will help.
I found the solution after searching for couple of days in the below link.
https://github.com/jbossas/jboss-as-maven-plugin/issues/40#issuecomment-14943429
I have to tweak a little bit to get is work in Windows 7.
Open Eclipse.
Add Jboss 7.1 Runtime 1 server.
Select the Server and press F3.
Click on Open Launch Config.
Goto VM arguments.
Add the below two entries.
"-Djboss.modules.system.pkgs=org.jboss.byteman,org.jboss.logmanager"
"-Djava.util.logging.manager=org.jboss.logmanager.LogManager"
Now select the Classpath TAB
Select User Entries
Click Add External Jars
Select the three jar files
a) jboss-logmanager-1.2.0.GA.jar
b) jboss-logmanager-log4j-1.0.0.GA.jar
c) log4j-1.2.16.jar
Paths
C:/jboss-as-7.1.1.Final/modules/org/jboss/logmanager/main/jboss-logmanager-1.2.0.GA.jar"
C:/jboss-as-7.1.1.Final/modules/org/jboss/logmanager/log4j/main/jboss-logmanager-log4j-1.0.0.GA.jar"
C:/jboss-as-7.1.1.Final/modules/org/apache/log4j/main/log4j-1.2.16.jar"
This will start the standalone jboss without any issues.
In EAP 6.4, the correct logmanager's path should be
$JBOSS_HOME/modules/system/layers/base/org/jboss/logmanager/main/jboss-logmanager-1.5.4.Final-redhat-1.jar