How to launch CommandLineRunner from Spring Controller - java

I have a main Spring Boot application in the top-level package that I launch, with different controllers in the children packages:
i.e.
ca.example.batch.MainBatchApplication
ca.example.batch.job1.Job1Controller (/batch/startJob1)
ca.example.batch.job2.Job2Controller (/batch/startJob2)
I am able to start the Spring Batches by going to the URL: http://localhost:8080/batch/startJob1 or http://localhost:8080/batch/startJob2.
However, in another package I have:
ca.example.batch.job3.Job3Controller
ca.example.batch.job3.Job3Application
... which is not a Spring Batch, but a Spring CommandLineRunner. I want to know if there is a way to launch MainBatchApplication without starting that CommandLineRunner automatically, but run it through the controller, i.e. http://localhost:8080/batch/startJob3.
The controller code I am looking at is:
package ca.example.batch.job3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class Job3Controller {
#RequestMapping("/batch/startJob3")
public String handle() throws Exception {
Job3Application app = new Job3Application();
Logger logger = LoggerFactory.getLogger(this.getClass());
logger.info("app: " + app);
String args = "";
app.run(args);
return "COMPLETE";
}
}
Job3Application is:
package ca.example.batch.job3;
import static java.lang.System.exit;
import java.util.List;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.Banner;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Import;
import ca.example.batch.common.CommonLibraryReference;
import ca.example.batch.common.domain.WasHost;
import ca.example.batch.common.svc.WasHostService;
#SpringBootApplication
#Import(CommonLibraryReference.class)
public class Job3Application implements CommandLineRunner {
private final Logger logger = LoggerFactory.getLogger(Job3Application.class);
#Autowired
public DataSource dataSource;
#Autowired
public WasHostService wasHostService;
public Job3Application() {
}
public static void main(String[] args) throws Exception {
new SpringApplicationBuilder(Job3Application.class)
.web(WebApplicationType.NONE)
.bannerMode(Banner.Mode.OFF)
.run(args);
}
#Override
public void run(String... strings) throws Exception {
logger.info("Loading data...");
logger.info("wasHostService: " + wasHostService);
List<WasHost> hostList = wasHostService.findAll();
if (!hostList.isEmpty()) {
for (WasHost host : hostList) {
logger.info("hostname: " + host.getHostname());
}
} else {
logger.info("No hosts found in database. Aborting data collection.");
exit(0);
}
}
}
The error I get in the log is:
""2018-07-07 12:56:09 [http-nio-9191-exec-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
""2018-07-07 12:56:09 [http-nio-9191-exec-1] INFO c.e.b.job3.Job3Controller - app: ca.example.batch.job3.Job3Application#472d7ac
""2018-07-07 12:56:09 [http-nio-9191-exec-1] INFO c.e.b.job3.Job3Application - Loading data...
""2018-07-07 12:56:09 [http-nio-9191-exec-1] INFO c.e.b.job3.Job3Application - wasHostService: null
""2018-07-07 12:56:09 [http-nio-9191-exec-1] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
"java.lang.NullPointerException: null
at ca.example.batch.job3.Job3Application.run(Job3Application.java:47)
at ca.example.batch.job3.Job3Controller.handle(Job3Controller.java:21)
... when I launch the controller request.
If this isn't the right way, please advise.
Basically, what I am trying to do is launch a main() from within a controller but use the MainBatchApplication runtime to run it (if that makes sense?). When the program is done, it send the return code back to the controller and shows in the browser.
Thank you,
Joey

ca.example.batch.MainBatchApplication is the main appliction you start.
So it scans all Components in package ca.example.batch. That means it should detect ca.example.batch.job3.Job3Application so you should be able to #Autowireit in the Job3Controller
this should work:
#Controller
public class Job3Controller {
private final Job3Application job3Application;
public Job3Controller (Job3Application job3Application){
this.job3Application = job3Application;
}
#RequestMapping("/batch/startJob3")
public String handle() throws Exception {
String[] args = ...
this.job3Application.run(args);
return "COMPLETE";
}
....
}

Related

issue with #Aspectj logging if #EnableTransactionManagement added in sprig boot project

I tried to use #Aspect for logging all requests and responses the code is running fine and successful with a simple spring boot project with a common configuration and not have any init methods or DB call.
The below code is not working that includes init configuration and DB call for required data used #EnableTransactionManagement its getting Error while use #Aspect while running my application
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
public class MyContextClass implements ApplicationListener<ContextRefreshedEvent>{
#Autowire
private MyServiceRepository myServiceRepo;
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// Added Db call
CommonUtils.setYears(myServiceRepo.getTotalYears());
}
}
#Aspect logging code
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
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 org.springframework.util.StopWatch;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
#Aspect
#Component
public class LoggingAspect {
private final Logger log = LoggerFactory.getLogger(this.getClass());
#Autowired
private HttpServletRequest request;
#Autowired
private HttpServletResponse response;
#Pointcut("within(#org.springframework.stereotype.Repository *)"
+ " || within(#org.springframework.stereotype.Service *)"
+ " || within(#org.springframework.web.bind.annotation.RestController *)")
public void springBeanPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the
// advices.
log.info("springBeanPointcut");
}
/**
* Pointcut that matches all Spring beans in the application's main packages.
*/
#Pointcut("within(com.test.mypackage..*)")
public void applicationPackagePointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the
// advices.
log.info("applicationPackagePointcut");
}
#Around("applicationPackagePointcut() && springBeanPointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String className = methodSignature.getDeclaringType().getSimpleName();
String methodName = methodSignature.getName();
String methodParameterNames = methodSignature.getMethod().toString();
if (request ! = null) {
log.info(request.getRequestURL());
log.info(request.getMethod());
}
if (response != null) {
log.info(response.getRequestURL());
log.info(response.getStatus());
}
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
Object result = joinPoint.proceed();
stopWatch.stop();
}
this code build success. but when I run the application below error display the error in setYears
2021-05-07 20:14:58 [restartedMain] ERROR o.s.boot.SpringApplication-[SpringApplication.java:856]-Application run failed
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
at org.springframework.web.context.support.WebApplicationContextUtils.currentRequestAttributes(WebApplicationContextUtils.java:313)
at org.springframework.web.context.support.WebApplicationContextUtils.access$400(WebApplicationContextUtils.java:66)
at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:329)
at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:324)
at org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler.invoke(AutowireUtils.java:292)
at com.sun.proxy.$Proxy120.getRequestURL(Unknown Source)
at com.opl.ans.config.utils.LoggingAspect.logAround(LoggingAspect.java:137)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
Is it the right way to do it? Are there any suggestions? Please help.
Based on the error stack the issue is that the request instance is invalid. I would guess that the request instance autowired to the Aspect could be stale or rather not assosicated with the current thread. This means that request instance is not null and the check within logAround() method gives unexepected results.
RequestContextHolder.getRequestAttributes() would return null if no request attributes are currently bound to the thread. Modifying the
if (request ! = null) { ..} check with if (RequestContextHolder.getRequestAttributes() ! = null) {..} should fix the issue.
Also spring boot provides out of the box solutions to what you are currently attempting through AOP . Do check them out as well.
HTTP Tracing
Spring MVC Metrics

Illegal argument exception for Optaplanner project, solver config does not exist as a classpath resource in the class loader

I am getting an error when running my SpringBoot application in my solver class. I am trying to create the solver factory from an xml resource contained in the resources folder exactly like the employee rostering example for OptaPlanner but I am getting an Illegal argument exception that I can't figure out why. I tried moving the xml file into the same folder as the solver class but the same error appears. I don't know why the exception is being thrown when I am following the example code that OptaPlanner has for employee rostering ?
Below is my code for my solver class:
package com.schedule.demo.solver;
import com.schedule.demo.domain.Roster;
import com.schedule.demo.service.RosterService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.api.solver.SolverFactory;
import org.optaplanner.core.impl.score.director.ScoreDirector;
import org.optaplanner.core.impl.score.director.ScoreDirectorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.ApplicationScope;
#ApplicationScope
#Component
public class ScheduleSolverManager implements ApplicationRunner {
public static final String SOLVER_CONFIG = "com/schedule/demo/service/solver/scheduleSolverConfig.xml";
protected final transient Logger logger = LoggerFactory.getLogger(getClass());
private SolverFactory<Roster> rosterSolverFactory;
private ScoreDirectorFactory<Roster> rosterScoreDirectorFactory;
private ThreadPoolTaskExecutor taskExecutor;
private ConcurrentMap<Integer, Solver<Roster>> deptIdToSolverMap = new ConcurrentHashMap<>();
private RosterService rosterService;
public ScheduleSolverManager(ThreadPoolTaskExecutor taskExecutor, RosterService rosterService){
this.taskExecutor = taskExecutor;
this.rosterService = rosterService;
}
#Override
public void run(ApplicationArguments args) throws Exception {
setupRosterSolverFactory();
}
private void setupRosterSolverFactory() {
rosterSolverFactory = SolverFactory.createFromXmlResource("com/schedule/demo/service/solver/scheduleSolverConfig.xml", ScheduleSolverManager.class.getClassLoader());
rosterScoreDirectorFactory = rosterSolverFactory.buildSolver().getScoreDirectorFactory();
}
public CountDownLatch solve(Integer deptID){
final CountDownLatch solvingEndedLatch = new CountDownLatch(1);
try{
taskExecutor.execute(()->{
Solver<Roster> rosterSolver = rosterSolverFactory.buildSolver();
deptIdToSolverMap.put(deptID, rosterSolver);
rosterSolver.addEventListener(event -> {
if(event.isEveryProblemFactChangeProcessed()){
logger.info("New best solution found for deptId ({}).", deptID);
Roster newRoster = event.getNewBestSolution();
rosterService.updateShiftsOfRoster(newRoster);
}
});
Roster roster = rosterService.buildRoster(deptID);
try {
rosterSolver.solve(roster);
solvingEndedLatch.countDown();
} finally {
deptIdToSolverMap.remove(deptID);
}
});
} catch (Throwable e) {
logger.error("Error solving for deptId (" + deptID + ").", e);
}
return solvingEndedLatch;
}
public Roster getRoster(final Integer deptId){
Solver<Roster> rosterSolver = deptIdToSolverMap.get(deptId);
return rosterSolver == null ? null : rosterSolver.getBestSolution();
}
public ScoreDirector<Roster> getScoreDirector() {
return rosterScoreDirectorFactory.buildScoreDirector();
}
}
The error when run is as follows:
Caused by: java.lang.IllegalArgumentException: The solverConfigResource (com/schedule/demo/service/solver/scheduleSolverConfig.xml) does not exist as a classpath resource in the classLoader (org.springframework.boot.devtools.restart.classloader.RestartClassLoader#2302b8ed).
Use the optaplanner-spring-boot-starter. It simplifies Spring integration greatly.
Guide: https://github.com/spring-guides/getting-started-guides/pull/126
Video: https://www.youtube.com/watch?v=U2N02ReT9CI
If you don't want to use the starter, this code might fix it: SolverFactory.createFromXmlResource("com/schedule/demo/service/solver/scheduleSolverConfig.xml", Roster.class.getClassLoader()); (uses the classloader of Roster).
You have to place the solver config XML under src/main/resources in order to be able to load it as a classpath resource.
So, if you load it using the resource name com/schedule/demo/service/solver/scheduleSolverConfig.xml, then the file has to be located at
src/main/resources/com/schedule/demo/service/solver/scheduleSolverConfig.xml

java.lang.NoClassDefFoundError: org/omg/CORBA/COMM_FAILURE on client while creating simple spring boor rmi app

I am creating spring boot applicating using RmiServiceExporter on server and RmiProxyFactoryBean on client.When i start server everything seems ok, i get
[main] o.s.remoting.rmi.RmiServiceExporter: Binding service 'ServerServiceIF' to RMI registry: RegistryImpl[UnicastServerRef [liveRef: [endpoint:[localhost:1099](local),objID:[0:0:0, 0]]]]
Then i start my client which is also spring boot app and my service interface on client is connecting to the adress on localhost.
rmi://localhost:1099/ServerServiceIF
But when i try to call method of this interface i get
Exception in thread "main" java.lang.NoClassDefFoundError: org/omg/CORBA/COMM_FAILURE
at org.springframework.remoting.rmi.RmiClientInterceptorUtils.isCorbaConnectFailure(RmiClientInterceptorUtils.java:187)
at org.springframework.remoting.rmi.RmiClientInterceptorUtils.isConnectFailure(RmiClientInterceptorUtils.java:174)
at org.springframework.remoting.rmi.RmiClientInterceptor.isConnectFailure(RmiClientInterceptor.java:283)
at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:349)
at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:260)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy38.auth(Unknown Source)
at com.cw.client.ClientApplication.main(ClientApplication.java:29)
Caused by: java.lang.ClassNotFoundException: org.omg.CORBA.COMM_FAILURE
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
... 9 more
Here are my server and client:
ServerApplication.java
package com.cw.server;
import com.cw.appif.ServerServiceIF;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.remoting.rmi.RmiServiceExporter;
#SpringBootApplication
public class ServerApplication {
#Bean
ServerServiceIF serverServiceIF() {
return new ServerService();
}
#Bean
RmiServiceExporter exporter(ServerServiceIF implementation) {
// Expose a service via RMI. Remote object URL is:
// rmi://<HOST>:<PORT>/<SERVICE_NAME>
// 1099 is the default port
Class<ServerServiceIF> serviceInterface = ServerServiceIF.class;
RmiServiceExporter exporter = new RmiServiceExporter();
exporter.setServiceInterface(serviceInterface);
exporter.setService(implementation);
exporter.setServiceName(serviceInterface.getSimpleName());
exporter.setRegistryPort(1099);
return exporter;
}
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
ClientApplication.java
package com.cw.client;
import com.cw.appif.ServerServiceIF;
import com.cw.exceptions.AuthException;
import com.cw.models.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
#SpringBootApplication
public class ClientApplication {
private static User user;
#Bean
RmiProxyFactoryBean service() {
RmiProxyFactoryBean rmiProxyFactory = new RmiProxyFactoryBean();
rmiProxyFactory.setServiceUrl("rmi://localhost:1099/ServerServiceIF");
rmiProxyFactory.setServiceInterface(ServerServiceIF.class);
return rmiProxyFactory;
}
public static void main(String[] args) {
try {
ServerServiceIF service = SpringApplication.run(ClientApplication.class, args).
getBean(ServerServiceIF.class);
user = new User("Denis","1234","e#mail.co");
service.auth(user);
System.out.println("User authed");
} catch (AuthException e) {
e.printStackTrace();
}
}
}
My server service interface and implementation on server:
package com.cw.appif;
import com.cw.exceptions.AuthException;
import com.cw.models.User;
public interface ServerServiceIF{
boolean auth(User user) throws AuthException;
}
package com.cw.server;
import com.cw.appif.ServerServiceIF;
import com.cw.exceptions.AuthException;
import com.cw.models.User;
import java.util.List;
public class ServerService implements ServerServiceIF{
static List<User> clients;
#Override
public boolean auth(User user) throws AuthException {
clients.add(user);
System.out.println("hi");
return true;
}
}
Heres my thoughts:
1)Maybe its because interface which im using is exactly the same on client and server, but client cant find class, because path is different?
2)When im debugging my client service->h->advised->targetSource ->targetClass is null. Is it ok? I will upload screenshots of my project structure and this variable in debug below.
server structure
client structure
debugging client
Found the problem. After adding corba to classpath, I found out that class User has to be Serializable. Adding implements Serializable and serialVersionUID fixed the problem and now everything is working.

AttributeNotFoundException through JMX in Startup bean on Wildfly

Hello everyone!
I'm trying to load wildfly server's system properties through JMX in Startup bean's #PostConstruct method. It works fine on the already started server instance when deployment starts, but fails while starting with server instance bootstrapping.
Wildfly 11.0.0.CR1
Startup bean code:
package ru.wildfly.test.ejb.wildflyconsulregistrar.startup;
import ru.wildfly.test.ejb.wildflyconsulregistrar.api.ConsulRegistrar;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;
#Startup
#Singleton
public class WildflyConsulRegistrarStartupBean {
#Inject
private ConsulRegistrar consulRegistrar;
#PostConstruct
public void initialize() {
registerServices();
}
private void registerServices() {
consulRegistrar.registerService("WildflyTestCluster");
}
.............
}
ConsulRegistrar code:
package ru.wildfly.test.ejb.wildflyconsulregistrar.impl;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.agent.model.NewService;
import ru.test.ejb.wildflyconsulregistrar.api.ConsulRegistrar;
import ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.api.CurrentServerNodeSettings;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
#Dependent
public class ConsulRegistrarImpl implements ConsulRegistrar {
...............
#Inject
private CurrentServerNodeSettings currentServerNodeSettings;
.............
#Override
public void registerService(String serviceName) {
String currentNodeName = currentServerNodeSettings.getCurrentNodeName();
........................
}
.......................
}
CurrentServerNodeSettings code:
package ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.impl;
import ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.api.CurrentServerNodeSettings;
import javax.enterprise.context.Dependent;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
#Dependent
public class CurrentServerNodeSettingsWildflyImpl implements CurrentServerNodeSettings {
....................
#Override
public String getCurrentNodeName() {
String currentNodeName = getPlatformMBeanServerAttributeValue(String.class, "jboss.as:system-property=server.name", "value");
return currentNodeName;
}
private <T> T getPlatformMBeanServerAttributeValue(Class<T> valueType, String objectName, String attributeName) {
T attributeValue = null;
try {
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
Object attributeObject = mBeanServer.getAttribute(new ObjectName(objectName), attributeName);
attributeValue = attributeObject != null ? (valueType.cast(attributeObject)) : null;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
return attributeValue;
}
}
Error message:
Caused by: java.lang.IllegalStateException:
javax.management.AttributeNotFoundException:
"WFLYCTL0216: Management resource '[(\"system-property\" => \"server.name\")]' not found"
at ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.impl.CurrentServerNodeSettingsWildflyImpl
.getPlatformMBeanServerAttributeValue(CurrentServerNodeSettingsWildflyImpl.java:41)
I have found the same issue on jboss forum https://developer.jboss.org/message/971717#971717 , but it was unanswered.
Any suggestions?
This is a dependency problem during startup, i.e. the server name is set after your #PostConstruct method gets executed. Try to load the server name lazy when it is accessed from the application for the first time.
In Wildfly there is no generic way to enforce the sequence of deployments from the application despite the definition of module dependencies. But this won't help in your case.

How to use #Startup Annotation for Service that Pushes Data to Websocket?

This is the Java EE7 #Startup annotation for reference. I am using the latest GlassFish server and IntelliJ to run the server.
I need to instantiate this service so that it can send packets of data periodically to a websocket for processing, but the fact that I use
session.getBasicRemote().sendObject(message);
in the end forces me to throw IOException and EncodeException.
This is bad as #Startup or #Singleton disallows usage of Exceptions when instantiating:
war exploded: java.io.IOException: com.sun.enterprise.admin.remote.RemoteFailureException: Error occurred during deployment: Exception while deploying the app [keyBoard_war_exploded] : The lifecycle method [printSchedule] must not throw a checked exception.
Here is my code:
package site.xxxx.models;
import site.xxxx.message.Message;
import site.xxxx.message.TextMessage;
import site.xxxx.modules.Packet;
import site.xxxx.websocket.MainServerEndpoint;
import javax.annotation.PostConstruct;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.json.Json;
import javax.json.JsonObject;
import javax.websocket.EncodeException;
import javax.websocket.Session;
import java.io.IOException;
import java.util.Set;
#Startup
#Singleton
public class Service {
private static Service service;
Set<Session> peers = MainServerEndpoint.peers;
#PostConstruct
public void mainLoop() throws IOException, EncodeException, InterruptedException {
sendSpamPacket();
}
private void sendSpamPacket() throws IOException, EncodeException {
JsonObject ret = Json.createObjectBuilder()
.add("type", "textMessage")
.add("text", "ayyyy")
.build();
Packet packet = new Packet(new TextMessage(ret));
MainServerEndpoint.sendPacket(packet);
//results in calling session.getBasicRemote().sendObject(message);
}
}

Categories

Resources