Not able to perform query using vertx-db2-client with Spring Boot and getting error - spring-boot

I'm trying to connect and query to DB2 using vertx-db2-client, but it is not working. I'm using Spring Boot 2.6.6 and vertx-db2-client library to perform query in reactive way. I've created a class which implements CommandLineRunner
Dependency in my build.gradle
implementation 'io.vertx:vertx-db2-client:4.2.6'
implementation 'io.vertx:vertx-reactive-streams:4.2.6'
Below is my CommandLineRunner class.
import io.vertx.db2client.DB2ConnectOptions;
import io.vertx.db2client.DB2Pool;
import io.vertx.sqlclient.PoolOptions;
import io.vertx.sqlclient.Row;
import io.vertx.sqlclient.RowSet;
import io.vertx.sqlclient.SqlClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
#Configuration
#Slf4j
public class DB2DataLoader implements CommandLineRunner {
/**
* Callback used to run the bean.
*
* #param args incoming main method arguments
* #throws Exception on error
*/
#Override
public void run(String... args) throws Exception {
DB2ConnectOptions connectOptions =
new DB2ConnectOptions()
.setPort(50001)
.setHost("db_host_name")
.setDatabase("db_name")
.setUser("username")
.setPassword("password");
// Pool options
PoolOptions poolOptions = new PoolOptions().setMaxSize(5);
// Create the client pool
SqlClient client = DB2Pool.client(connectOptions, poolOptions);
// A simple query
client
.query("SELECT * FROM SCHEMA.TABLE")
.execute(
ar -> {
if (ar.succeeded()) {
RowSet<Row> result = ar.result();
System.out.println("Got " + result.size() + " rows ");
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
// Now close the pool
client.close();
});
}
}
I'm not seeing any connection issues. The error that I see right after the deployment is below:
2022-04-11 15:35:11.740 INFO 2736 --- [ main] c.h.t.p.ServiceApp : Started ServiceApp in 3.746 seconds (JVM running for 4.719)
Failure: SQLState.NET_VCM_VCS_LENGTHS_INVALID: VCM and VCS lengths are mutually exclusive but both were set: vcsLen=255 vcmLen=12336
I'm not sure what is this "Failure: **" means. Can anyone please help me understand this and how to fix. Database connection parameters are correct. I've just masked here. I was following this documentation for the example.

Related

How to configure Spring Boot App to connect to Axon Server and register event handler

First, I have a spring boot application using axon 4.5.5 libraries connecting to server 4.2.4. Is this supported?
This spring boot app is suppose to listen to several events coming from the (main app emitted to the) axon server and here is my sprint boot axon client configuration in application.yml below.
Second, this application connects to the axon server but fails to handle any events causing all the said events to be blacklisted. I have trace it to the event handler registration is probably causing the issue. We are using the EventStore as the StreamableMessageSource when calling registerTrackingEventProcessor().
Do you guys have any ideas why the registered event handlers are not firing? I can see the spring boot app is connected to the axon server on the dashboard as well as the main app that fires the events. I can also see the fired events when searching it in the dashboard and their blacklisting in the axon server log. So my guess it is the configuration causing issues.
Here is my library versions (from pom.xml):
Version 4.5.5
axon-test
axon-spring-boot-autoconfigure
axon-spring-boot-starter
axon-modelling
axon-metrics
axon-messaging
axon-eventsourcing
Version 2.6.0
spring-boot-starter-web
Here is my application.yml axon fragment:
axon:
axonserver:
client-id: reporting-etl-client
component-name: reporting-etl
query-threads: ${AXON_QUERY_THREADS_MAX:50}
servers: ${AXON_AXONSERVER_SERVERS:axonserver}
serializer:
events: jackson
and AxonConfig.java:
package com.fedeee.reporting.config;
import com.fedeee.reporting.axon.events.EventHandlerProjector;
import com.thoughtworks.xstream.XStream;
import org.axonframework.axonserver.connector.query.AxonServerQueryBus;
import org.axonframework.config.EventProcessingConfigurer;
import org.axonframework.config.ProcessingGroup;
import org.axonframework.eventhandling.EventBus;
import org.axonframework.eventhandling.TrackingEventProcessorConfiguration;
import org.axonframework.eventhandling.gateway.DefaultEventGateway;
import org.axonframework.eventhandling.gateway.EventGateway;
import org.axonframework.queryhandling.DefaultQueryGateway;
import org.axonframework.queryhandling.QueryBus;
import org.axonframework.queryhandling.QueryGateway;
import org.axonframework.serialization.AbstractXStreamSerializer;
import org.axonframework.serialization.Serializer;
import org.axonframework.serialization.xml.XStreamSerializer;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.Assert;
import java.util.Set;
#Configuration
public class AxonConfig {
private static final Logger LOG = LoggerFactory.getLogger(AxonConfig.class);
/**
* Correctly configuring the XStream serializer to avoid security warnings.
*/
#Autowired
public void configureXStream(Serializer serializer) {
if (serializer instanceof AbstractXStreamSerializer) {
XStream xStream = ((XStreamSerializer) serializer).getXStream();
XStream.setupDefaultSecurity(xStream);
xStream.allowTypesByWildcard(new String[] {"com.fedeee.pkg.api.events.**", "org.axonframework.**"});
}
}
/**
*
* #param configurer
* #param context
*/
#Autowired
public void configure(EventProcessingConfigurer configurer, ApplicationContext context) {
LOG.info("Setting up TrackingEventProcessors for threads, batch size and other configurations..."
+ " annotated with #ProcessingGroup...");
// find classes in the com.fedeee.* package that has methods annotated with #ProcessingGroup to configure
Reflections reflections = new Reflections("com.fedeee.reporting.axon.events");
Set<Class<?>> annotatedClasses = reflections.getTypesAnnotatedWith(ProcessingGroup.class);
// Configure each identified class
annotatedClasses.stream().forEach(annotatedClass -> {
// Locate the appropriate spring bean to get appropriate values from each one.
String beanName = annotatedClass.getName().substring(annotatedClass.getName().lastIndexOf(".") + 1);
beanName = beanName.substring(0,1).toLowerCase() + beanName.substring(1);
Object projObj = context.getBean(beanName);
if (projObj instanceof EventHandlerProjector) {
EventHandlerProjector projector = (EventHandlerProjector) projObj;
LOG.info("Configuring EventHandlerProjector Bean '{}' with maxThreads: {} and batchSize: {}.",
beanName, projector.getMaxThreads(), projector.getBatchSize());
ProcessingGroup pgAnnotation = annotatedClass.getAnnotation(ProcessingGroup.class);
String processingGroup = pgAnnotation.value();
configurer.registerTrackingEventProcessor(
processingGroup,
org.axonframework.config.Configuration::eventStore,
conf -> TrackingEventProcessorConfiguration.forParallelProcessing(projector.getMaxThreads())
.andBatchSize(projector.getBatchSize())
).registerHandlerInterceptor(processingGroup, configuration -> new EventHandlerLoggingInterceptor());
// Enable logging for EventHandlers
LOG.info(".. '{}' successfully configured with processing group '{}'.", beanName, processingGroup);
} else {
LOG.info(".. '{}' failed to configure with any processing group.", beanName);
}
});
// TODO: handle tracking event processor initialization. See the axon mailing list thread:
// *****************************************************************************************************************
// https://groups.google.com/forum/#!topic/axonframework/eyw0rRiSzUw
// In that thread there is a discussion about properly initializing the token store to avoid recreating query models.
// I still need to understand more about this...
// *****************************************************************************************************************
}
// #Autowired
// public void configureErrorHandling(
// EventProcessingConfigurer configurer, ErrorHandler errorHandler
// ) {
// configurer.registerDefaultListenerInvocationErrorHandler(c -> errorHandler);
// }
#Autowired
public void registerInterceptors(QueryBus queryBus) {
Assert.notNull(queryBus, "Invalid configuration, queryBus is null!");
if (AxonServerQueryBus.class.isAssignableFrom(queryBus.getClass())) {
queryBus.registerHandlerInterceptor(InterceptorSupport.authorizationHandlerInterceptor());
}
}
#Bean
public QueryGateway queryGateway(QueryBus queryBus) {
return DefaultQueryGateway.builder().queryBus(queryBus).build();
}
#Bean
public EventGateway eventGateway(EventBus eventBus) {
return DefaultEventGateway.builder().eventBus(eventBus).build();
}
}
Here is the EventHandlerProjector.java:
package com.fedeee.reporting.axon.events;
/**
* Defines a contract to ensure we specify the number of threads and batch size to be allowed by the event
*/
public interface EventHandlerProjector {
/**
* Specifies the number of records per batch to be handled by the tracking processor.
* #return
*/
public default Integer getBatchSize() {
return 1;
}
/**
* Specifies the maximumn number of threads the tracking processor can be specified to use.
* #return
*/
public default Integer getMaxThreads() {
return 1;
}
}
And finally the event handler class:
package com.fedeee.reporting.axon.events.pkg;
import com.fedeee.api.UserInfo;
import com.fedeee.pkg.api.events.*;
import com.fedeee.reporting._shared.utils.MdcAutoClosable;
import com.fedeee.reporting.axon.events.EventHandlerProjector;
import com.fedeee.reporting.recover.packageevents.PackageCreatedDto;
import com.fedeee.reporting.recover.packageevents.RecoverPackageCreatedRequest;
import com.fedeee.reporting.recover.packageevents.RecoverPackageEditedDto;
import com.fedeee.reporting.recover.packageevents.RecoverPackageEventsService;
import com.fedeee.reporting.recover.translators.PackageEventTranslator;
import com.fedeee.reporting.recover.translators.UserInfoTranslator;
import com.fedeee.reporting.recover.user.RecoverUserDto;
import org.axonframework.config.ProcessingGroup;
import org.axonframework.eventhandling.EventHandler;
import org.axonframework.eventhandling.Timestamp;
import org.axonframework.messaging.annotation.MetaDataValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.time.Instant;
import static com.fedeee.api.AxonMessageMetadataKeys.USER_INFO;
/**
* Event TrackingProcessor for PackageRecord-based Events handled by Axon.
*
* Configurations can be provided with the given batchSize and maxThreads options via .env or docker-compose.
*
* IMPORTANT! <code>AxonConfig</code> looks for the <em>#ProcessingGroup</em> annotation to set everything up properly.
*/
#ProcessingGroup(value = "Package-Record")
#Component
public class PackageRecordProjector implements EventHandlerProjector {
#Value("${reporting-etl.tp-batch-size.package-record:1}")
private Integer batchSize;
#Value("${reporting-etl.tp-max-threads.package-record:5}")
private Integer maxThreads;
private RecoverPackageEventsService recoverPackageEventsService;
#Autowired
public PackageRecordProjector(RecoverPackageEventsService recoverPackageEventsService) {
super();
this.recoverPackageEventsService = recoverPackageEventsService;
}
private final Logger LOG = LoggerFactory.getLogger(this.getClass());
/**
* Event handler to handle packages created in Recover.
*
* This replaces the REST endpoint exposed and used by Recover in RecoverPackageEventsController.created().
*
* #param event
* #param occurrenceInstant
* #param userInfo
*/
#EventHandler
void on(PackageCreated event, #Timestamp Instant occurrenceInstant, #MetaDataValue(USER_INFO) UserInfo userInfo) {
try (MdcAutoClosable mdc = new MdcAutoClosable()) {
mdcInit(event, userInfo, mdc);
LOG.info("Handling PackageCreated event...");
PackageCreatedDto createdDto = PackageEventTranslator.from(event, occurrenceInstant, userInfo);
RecoverUserDto recoverUserDto = UserInfoTranslator.from(userInfo);
RecoverPackageCreatedRequest request = new RecoverPackageCreatedRequest(createdDto, recoverUserDto);
/* Once we are ready, comment this in and make appropriate changes to RecoverPackageEventsController to
disallow duplication via the REST endpoint. (There are comments in there already. :) )
*/
recoverPackageEventsService.save(request);
LOG.info("Finished handling PackageCreated event.");
} catch (Exception e) {
LOG.info("An Exception has been thrown : ", e);
throw e;
}
}
#EventHandler
void on(PackageTypeCorrected event, #Timestamp Instant occurrenceInstant, #MetaDataValue(USER_INFO) UserInfo userInfo) {
try (MdcAutoClosable mdc = new MdcAutoClosable()) {
mdcInit(event, userInfo, mdc);
// TODO: not implemented (Recover and Reporting-ETL)
LOG.info("Finished handling PackageTypeCorrected event.");
} catch (Exception e) {
LOG.info("An Exception has been thrown : ", e);
throw e;
}
}
#EventHandler
void on(PackageDeleted event, #Timestamp Instant occurrenceInstant, #MetaDataValue(USER_INFO) UserInfo userInfo) {
try (MdcAutoClosable mdc = new MdcAutoClosable()) {
mdcInit(event, userInfo, mdc);
// TODO: not implemented (Reporting-ETL)
LOG.info("Finished handling PackageDeleted event.");
} catch (Exception e) {
LOG.info("An Exception has been thrown : ", e);
throw e;
}
}
// TODO: not implemented (Recover and Reporting-ETL)
// #EventHandler
// void on(PackageIntegrated event, #Timestamp Instant occurrenceInstant, #MetaDataValue(USER_INFO) UserInfo userInfo) {
// try (MdcAutoClosable mdc = new MdcAutoClosable()) {
// mdcInit(event, userInfo, mdc);
// } catch (Exception e) {
// LOG.info("An Exception has been thrown : ", e);
// throw e;
// }
// }
#EventHandler
void on(DataCaptureStarted event, #Timestamp Instant occurrenceInstant, #MetaDataValue(USER_INFO) UserInfo userInfo) {
try (MdcAutoClosable mdc = new MdcAutoClosable()) {
mdcInit(event, userInfo, mdc);
RecoverPackageEditedDto editedDto = PackageEventTranslator.from(event, occurrenceInstant, userInfo);
/* Once we are ready, comment this in and make appropriate changes to RecoverPackageEventsController to
disallow duplication via the REST endpoint. (There are comments in there already. :) )
*/
recoverPackageEventsService.save(editedDto);
LOG.info("Finished handling DataCaptureStarted event.");
} catch (Exception e) {
LOG.info("An Exception has been thrown : ", e);
throw e;
}
}
#EventHandler
void on(DataCaptureEnded event, #Timestamp Instant occurrenceInstant, #MetaDataValue(USER_INFO) UserInfo userInfo) {
try (MdcAutoClosable mdc = new MdcAutoClosable()) {
mdcInit(event, userInfo, mdc);
RecoverPackageEditedDto editedDto = PackageEventTranslator.from(event, occurrenceInstant, userInfo);
/* Once we are ready, comment this in and make appropriate changes to RecoverPackageEventsController to
disallow duplication via the REST endpoint. (There are comments in there already. :) )
*/
recoverPackageEventsService.update(event.getPackageId(), editedDto);
LOG.info("Finished handling DataCaptureEnded event.");
} catch (Exception e) {
LOG.info("An Exception has been thrown : ", e);
throw e;
}
}
#Override public Integer getBatchSize() {
return batchSize;
}
#Override public Integer getMaxThreads() {
return maxThreads;
}
private void mdcInit(PackageEvent event, UserInfo userInfo, MdcAutoClosable mdc) {
mdc.put("PackageId", event.getPackageId());
mdc.put("UserId", userInfo.getUserId());
LOG.info("Handling package record event: {}", event);
}
}
Here is the logs for today 2023/01/27...
.
.
.
2023-01-27 17:19:32.924 DEBUG 8 --- [MessageBroker-4] i.a.a.message.command.CommandCache : Checking timed out commands
2023-01-27 17:19:37.924 DEBUG 8 --- [MessageBroker-4] i.a.axonserver.message.query.QueryCache : Checking timed out queries
2023-01-27 17:19:37.924 DEBUG 8 --- [MessageBroker-3] i.a.a.message.command.CommandCache : Checking timed out commands
2023-01-27 17:19:40.299 DEBUG 8 --- [ool-5-thread-16] i.a.axonserver.grpc.PlatformService : Registered client : ClientComponent{client='reporting-etl-client', component='reporting-etl', context='default'}
2023-01-27 17:19:40.299 INFO 8 --- [ool-5-thread-16] i.a.a.logging.TopologyEventsLogger : Application connected: reporting-etl, clientId = reporting-etl-client, context = default
2023-01-27 17:19:40.299 DEBUG 8 --- [ool-5-thread-16] i.a.a.c.version.ClientVersionsCache : Version update received from client reporting-etl-client.default to version 4.4.
2023-01-27 17:19:40.332 INFO 8 --- [ool-5-thread-15] i.a.a.message.event.EventDispatcher : Starting tracking event processor for : - 209301
2023-01-27 17:19:42.925 DEBUG 8 --- [MessageBroker-7] i.a.axonserver.message.query.QueryCache : Checking timed out queries
2023-01-27 17:19:42.925 DEBUG 8 --- [MessageBroker-3] i.a.a.message.command.CommandCache : Checking timed out commands
.
.
.
2023-01-27 18:56:08.163 DEBUG 8 --- [MessageBroker-1] i.a.a.message.command.CommandCache : Checking timed out commands
2023-01-27 18:56:08.163 DEBUG 8 --- [MessageBroker-7] i.a.axonserver.message.query.QueryCache : Checking timed out queries
2023-01-27 18:56:09.242 DEBUG 8 --- [pool-5-thread-9] i.a.a.message.command.CommandDispatcher : Dispatch com.fedeee.pkg.api.commands.StartDataCapture to: recover-api-client.default
2023-01-27 18:56:09.257 DEBUG 8 --- [ool-5-thread-10] i.a.a.message.command.CommandDispatcher : Sending response to: io.axoniq.axonserver.message.command.CommandInformation#17b317ff
2023-01-27 18:56:09.294 DEBUG 8 --- [st-dispatcher-2] i.a.a.grpc.GrpcQueryDispatcherListener : Send request io.axoniq.axonserver.grpc.SerializedQuery#158b1b9a, with priority: 0
2023-01-27 18:56:09.294 DEBUG 8 --- [st-dispatcher-2] i.a.a.grpc.GrpcQueryDispatcherListener : Remaining time for message: 72152808-ca89-4565-82dd-2675e52686e2 - 3600000ms
2023-01-27 18:56:09.300 DEBUG 8 --- [pool-5-thread-5] i.a.axonserver.message.query.QueryCache : Remove messageId 72152808-ca89-4565-82dd-2675e52686e2
2023-01-27 18:56:09.300 DEBUG 8 --- [pool-5-thread-5] i.a.a.message.query.QueryDispatcher : No (more) information for 72152808-ca89-4565-82dd-2675e52686e2 on completed
2023-01-27 18:56:09.300 DEBUG 8 --- [st-dispatcher-2] i.a.a.grpc.GrpcQueryDispatcherListener : Send request io.axoniq.axonserver.grpc.SerializedQuery#6e93a34b, with priority: 0
2023-01-27 18:56:09.301 DEBUG 8 --- [st-dispatcher-2] i.a.a.grpc.GrpcQueryDispatcherListener : Remaining time for message: 53aa1974-4012-452a-b451-2957003e4b9f - 3599999ms
2023-01-27 18:56:09.306 DEBUG 8 --- [pool-5-thread-4] i.a.axonserver.message.query.QueryCache : Remove messageId 53aa1974-4012-452a-b451-2957003e4b9f
2023-01-27 18:56:09.306 DEBUG 8 --- [pool-5-thread-4] i.a.a.message.query.QueryDispatcher : No (more) information for 53aa1974-4012-452a-b451-2957003e4b9f on completed
2023-01-27 18:56:09.319 DEBUG 8 --- [ool-5-thread-13] i.a.a.m.q.s.handler.DirectUpdateHandler : SubscriptionQueryResponse for subscription Id 55748e24-e26f-4863-a5d0-a4eeff43da69 send to client.
2023-01-27 18:56:10.509 DEBUG 8 --- [st-dispatcher-2] i.a.a.grpc.GrpcQueryDispatcherListener : Send request io.axoniq.axonserver.grpc.SerializedQuery#fd8d154, with priority: 0
2023-01-27 18:56:10.510 DEBUG 8 --- [st-dispatcher-2] i.a.a.grpc.GrpcQueryDispatcherListener : Remaining time for message: d2d91224-557f-4735-933b-e4195e7e42f9 - 3599999ms
2023-01-27 18:56:10.514 DEBUG 8 --- [ool-5-thread-15] i.a.axonserver.message.query.QueryCache : Remove messageId d2d91224-557f-4735-933b-e4195e7e42f9
2023-01-27 18:56:10.514 DEBUG 8 --- [ool-5-thread-15] i.a.a.message.query.QueryDispatcher : No (more) information for d2d91224-557f-4735-933b-e4195e7e42f9 on completed
2023-01-27 18:56:13.163 DEBUG 8 --- [MessageBroker-2] i.a.a.message.command.CommandCache : Checking timed out commands
2023-01-27 18:56:13.163 DEBUG 8 --- [MessageBroker-5] i.a.axonserver.message.query.QueryCache : Checking timed out queries
.
.
.
As you might be running into known bugs, it's better to use 4.6 of server and framework, that said, it should likely work since the server API is pretty stable.
Could you also share the com.fedeee.reporting.axon.events.EventHandlerProjector class? Has that class #EventHandler annotated methods? Are there more classes with #EventHandler annotated methods?
I assume you are using Spring Boot and the Axon Framework starter, is did indeed the case?

Run Java with a main in a WebSphere project

Very new to WebSphere as well as packaging Java.
I need to take a Java project that we've been running from the command line as an executable Jar and make it run from WebSphere (since the admin user has been getting auto-logged out at midnight).
I've looked at creating a WAR file, but the ant examples I've looked at invoked a lot of WEB-INF dependencies ... but this project doesn't have that. It has a main entry point in the code.
EARs seem to require EJBs, which I don't think this project uses. Seeing as EJBs have been on their way out for a while I'm not as up to speed on them.
My questions are: What is the simplest way to put my executable JAR into WebSphere?
Bonus points: Do EAR files require EJBs in the project? If so, how do I know if this project invokes them?
The simple answer is to create a war application with a #WebListener:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
#WebListener
public class ServletInitializer implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println(toString() + " contextInitialized started");
String[] args = new String[] {};
MainClass.main(args);
System.out.println(toString() + " contextInitialized finished");
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Replace MainClass.main(args); with your application call (and add any JAR dependencies into WEB-INF/lib).
The thing I don't like about the above is that it's not great to perform intense work during startup. This may make problem determination harder and certain capabilities (e.g. runtime diagnostic trace modification) are unavailable during startup.
You could create a WAS-specific solution by using AdminClient to subscribe to the Server MBean's Stateful notifications.
Otherwise, a standardized way would be to have an EJB #Startup bean which uses the TimerService to start work after some delay which is empirically determined to be an average application server startup time. For example:
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;
#Singleton
#Startup
public class DeferredInitializer {
public static final int DELAY = Integer.getInteger("DeferredInitializer.DELAY", 60000);
#Resource
TimerService timerService;
#PostConstruct
private void init() throws Throwable {
System.out.println(toString() + " init entry");
TimerConfig timerConfig = new TimerConfig();
timerConfig.setPersistent(false);
timerService.createSingleActionTimer(DELAY, timerConfig);
Calendar c = new GregorianCalendar();
c.add(Calendar.MILLISECOND, DELAY);
System.out.println(toString() + " timer estimated to pop in (" + DELAY + "ms) ~# " + c.getTime());
System.out.println(toString() + " init exit");
}
#Timeout
public void timeout(Timer timer) {
System.out.println(toString() + " timeout entry");
String[] args = new String[] {};
MainClass.main(args);
System.out.println(toString() + " timeout exit");
}
}
Specify the delay with the generic JVM argument -DDeferredInitializer.DELAY=X (X in milliseconds).

Grails, Can not make spring-security event notification to work

I try to log logins and logouts using the event handling of spring-security but nothing happens.
I enabled event handling in Aplication.groovy:
grails.plugin.springsecurity.useSecurityEventListener = true
and registered the bean in resources.groovy:
import grails.databinding.converters.ValueConverter
import com.torntrading.utils.DatabaseMessageSource
import org.springframework.web.servlet.i18n.SessionLocaleResolver
import com.myproj.AuthenticationSuccessEventListener
beans = {
authenticationSuccessEventListener(AuthenticationSuccessEventListener)
}
And the event class in folder "Utility Classes":
package com.myproj
import org.springframework.context.ApplicationListener
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent
/**
*
* #author Lars
*/
class AuthenticationSuccessEventListener implements
ApplicationListener<InteractiveAuthenticationSuccessEvent> {
#Override
public void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
println(springSecurityService.getPrincipal().username + "***** LOGGED IN ! ******" + new Date())
}
}
The text is never printed so I assume that the event is not fired.
What's wrong with my code?
Using version: spring-security-core:3.1.1'

Running cucumber-groovy features against a spring boot api

I've been attempting to get cucumber-groovy working with spring-boot, but it's not been going well. I get the error org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8080/applicants": Connection refused; nested exception is java.net.ConnectException: Connection refused which seems to indicate that it's hitting the endpoint, but that the service isn't running.
I've read that I need to have a cucumber.xml file, but my project is not using any xml config, it's all annotations, so instead I've got this:
package support
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan(basePackages = "com.base.package")
public class CucumberConfiguration {}
I've added it to the World, but this seems to be the wrong way of doing things (i.e. I don't know how to add an annotation on groovy step defs).
package support
import com.thing.app.Application
import org.junit.runner.RunWith
import org.springframework.boot.test.SpringApplicationContextLoader
import org.springframework.boot.test.WebIntegrationTest
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
import org.springframework.test.context.web.WebAppConfiguration
import static cucumber.api.groovy.Hooks.*
//#RunWith(SpringJUnit4ClassRunner)
//#ContextConfiguration(classes = Application, loader = SpringApplicationContextLoader)
//#WebAppConfiguration
//#WebIntegrationTest
#ContextConfiguration(classes = CucumberConfiguration)
public class AbstractTest {
}
World() {
new AbstractTest()
}
Before() {}
After() {}
I left in my other annotations to kind of show what I've done so far. None of it has worked.
I've also tried setting up an AbstractDefs class as seen here https://github.com/jakehschwartz/spring-boot-cucumber-example/tree/master/src/test/java/demo, but that also hasn't worked, mostly because I'm not using the cucumber-java style of things, but instead the cucumber-groovy style, which doesn't use step definition classes.
Edit: Just discovered I was doing things wrong by having an env.groovy, I'm used to the ruby cucumber, so I'm having trouble finding all the little problems. Still am having the same issue though, I don't know how to execute in a Spring context.
You can instantiate Spring test context with io.cucumber.spring.SpringFactory and register adapter in World to allow groovy script has access to Spring beans:
env.groovy:
#ContextConfiguration(classes = TestConfiguration, loader = SpringBootContextLoader)
class CucumberContextConfiguration {
}
//adapter bypassing World properties to Spring context
class SpringFactoryWorldAdapter {
private final SpringFactory factory;
SpringFactoryWorldAdapter(SpringFactory factory) {
this.factory = factory;
}
#Override
Object getProperty(String s) {
return factory.testContextManager.getContext().getBean(s);
}
}
def factory; //Keep state to prevent repeated context initialization
World { args ->
if (factory == null) {
factory = new SpringFactory()
factory.addClass(CucumberContextConfiguration)
factory.start()
}
new SpringFactoryWorldAdapter(factory)
}

Use of resource-manager specific transaction demarcation API in EJB 3.x

Accordinong to EJB 3.0 specification: While an instance is in a transaction, the instance must not attempt to use the resource-manager specific transaction demarcation API (e.g. it must not invoke the
commit or rollback method on the java.sql.Connection interface or on the
javax.jms.Session interface) In 13.3.3 of Specification.
I tried one example - where in BEAN managed transaction I included java.sql.Connection.commit() - created Stateless bean in NetBeans as EE5, deployed on Glassfish 3.1 and container did not complain? Bean method updates the database without any errors in Glassfish log. Is this expected behavior?
Also, there is no such restriction on using java.sql.Connection.commit() for beans with container transaction managed transactions mentioned in specification.
Thanks
Branislav
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package ejb;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.*;
import javax.persistence.Transient;
import javax.sql.DataSource;
import javax.transaction.*;
/**
*
* #author bane
*/
#Stateless
#TransactionManagement(TransactionManagementType.BEAN)
public class MySession implements MySessionRemote {
#Resource(name = "SAMPLE")
private DataSource SAMPLE;
//
#Resource UserTransaction utx;
//gore je novi kod
#Override
public String getResult() {
return "This is my Session Bean";
}
public void doSomething() {
try {
Connection conn = SAMPLE.getConnection();
Statement stmt = conn.createStatement();
String q = "select * from BOOK";
String up = "update BOOK set PRICE = PRICE + 1";
utx.begin();
int num = stmt.executeUpdate(up);
System.out.println("num: "+num);
ResultSet rs = stmt.executeQuery(q);
//is conn.commit() legal?
conn.commit();
String name = null;
int price = 0;
while (rs.next()) {
name = rs.getString(2);
price = rs.getInt(3);
System.err.println(name+" , "+price);
}
utx.commit();
} catch (SQLException ex) {
Logger.getLogger(MySession.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {
Logger.getLogger(MySession.class.getName()).log(Level.SEVERE, null, ex);
}
}
// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Business Method")
}

Resources