EJB lookup fails during startup but is fine when the call is made after the server is started - jboss7.x

I am using Jboss EAP 7.1. And i managed to deploy a stateless EJBbean successfully. I am also able to access the deploy EJB after the server is started successfully.
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
jndiProperties.put("jboss.naming.client.ejb.context", true);
Context context;
try {
context = new InitialContext(jndiProperties);
String appName = "";
if ("FlowControllerBean/remote".equalsIgnoreCase(jndiName)) {
appName = "";
} else {
appName = "upm-0.1";
}
final String distinctName = "";
String beanName = "";
final String viewClassName = FlowController.class.getName();
System.out.println(
"ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
if ("".equalsIgnoreCase(interfacename)) {
context = new InitialContext();
return context.lookup(jndiName);
} else {
beanName = jndiName.substring(0, jndiName.indexOf("/"));
return context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!"
+ interfacename);
}
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
But my real problem comes when i want to access the same EJB during server start up itself. One of my method inside a service bean calls this EJB Bean during server start up itself. But it fails with the message
"EJBCLIENT000079: Unable to discover destination for request for EJB
StatelessEJBLocator for "/ejb-remote-server/FlowControllerBean", view
is interface com.hexaware.framework.flowcontroller.FlowController,
affinity is None".
Before the lookup is executed the actual EJB beans are deployed. Please find below the logs from server before the lookup is made during start up.
14:36:25,971 INFO [org.jboss.weld.deployer] (MSC service thread 1-4)
WFLYWELD0003: Processing weld deployment ejb-remote-server.jar
14:36:26,373 INFO [org.jboss.as.ejb3.deployment] (MSC service thread
1-4) WFLYEJB0473: JNDI bindings for session bean named
'FlowControllerBean' in deployment unit 'deployment
"ejb-remote-server.jar"' are as follows:
java:global/ejb-remote-server/FlowControllerBean!com.hexaware.framework.flowcontroller.FlowController
java:app/ejb-remote-server/FlowControllerBean!com.hexaware.framework.flowcontroller.FlowController
java:module/FlowControllerBean!com.hexaware.framework.flowcontroller.FlowController
java:jboss/exported/ejb-remote-server/FlowControllerBean!com.hexaware.framework.flowcontroller.FlowController
java:global/ejb-remote-server/FlowControllerBean
java:app/ejb-remote-server/FlowControllerBean
java:module/FlowControllerBean
[org.apache.cxf.endpoint.ServerImpl] (MSC service thread 1-4) Setting
the server's publish address to be
http://localhost:8080/ejb-remote-server/EventManagerService
14:36:29,409 INFO [org.jboss.ws.cxf.deployment] (MSC service thread
1-4) JBWS024074: WSDL published to:
file:/D:/Magesh/Softwares/Jboss-eap-7.1/standalone/data/wsdl/ejb-remote-server.jar/EventManagerServiceService.wsdl
14:36:29,643 INFO [org.jboss.as.webservices] (MSC service thread 1-4)
WFLYWS0003: Starting service
jboss.ws.endpoint."ejb-remote-server.jar".EventStatusService
14:36:29,650 INFO [org.jboss.as.webservices] (MSC service thread 1-2)
WFLYWS0003: Starting service
jboss.ws.endpoint."ejb-remote-server.jar".EventManagerService
14:36:30,197 INFO [org.wildfly.extension.undertow] (ServerService
Thread Pool -- 72) WFLYUT0021: Registered web context: '/ejb-remote-server' for server 'default-server'
But the same code works if i call it after the server is started completely.
Below is my property file which i have used for connecting from the client to my remote server.Both server and client are in same Jboss server instance in my local machine.
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port = 8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
Note: Look up is successful during start up or any other time. But when i try to call a method in the bean the error message is encountered. But same bean method call works after server start up

Related

spring-data-geode and spring-boot-starter-webflux application run failed

I have a webflux project and I am adding apache geode. In my build.gradle I have:
implementation 'org.springframework.data:spring-data-geode:2.2.4.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-webflux:2.2.4.RELEASE'
Once adding the spring-data-geode implementation the application crashes with:
2020-01-28T16:29:51,965 INFO [main] org.eclip.jetty.util.log.Log 169 initialized: Logging initialized #4337ms to org.eclipse.jetty.util.log.Slf4jLog
2020-01-28T16:29:52,050 WARN [main] org.sprin.conte.suppo.AbstractApplicationContext 558 refresh: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start reactive web server; nested exception is java.lang.NoClassDefFoundError: org/eclipse/jetty/servlet/ServletHolder
2020-01-28T16:29:52,064 INFO [main] org.sprin.boot.autoc.loggi.ConditionEvaluationReportLoggingListener 136 logMessage:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-01-28T16:29:52,072 ERROR [main] org.sprin.boot.SpringApplication 826 reportFailure: Application run failed
org.springframework.context.ApplicationContextException: Unable to start reactive web server; nested exception is java.lang.NoClassDefFoundError: org/eclipse/jetty/servlet/ServletHolder
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.onRefresh(ReactiveWebServerApplicationContext.java:81)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544)
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
The trouble is, if I add
spring.main.web-application-type=none or spring.main.web-application-type=reactive to my application.properties then that interferes with the #ClientCacheApplication(name = "Web", locators = #Locator(host="1.2.3.4", port=10334), logLevel = "debug", subscriptionEnabled = true) annotation and the application does not connect to the geode locator, nor then run the #EnableClusterDefinedRegions which causes problems defining simple regions that I want to pick up from the server.
UPDATE To add spring-boot-starter-web to build.gradle and make the spring boot application type NONE as below appears to fix the instant problem, but...
SpringApplication app = new SpringApplication(Web.class);
app.setWebApplicationType(WebApplicationType.NONE);
SpringApplication.run(Web.class, args);
... but then the webflux mapping cannot find the #Bean websocket handler:
2020-01-28T16:54:26,236 DEBUG [http-nio-8082-exec-2] org.sprin.web.servl.handl.AbstractHandlerMapping 412 getHandler: Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2020-01-28T16:54:26,246 DEBUG [http-nio-8082-exec-2] org.sprin.web.servl.resou.ResourceHttpRequestHandler 454 handleRequest: Resource not found
2020-01-28T16:54:26,246 DEBUG [http-nio-8082-exec-2] org.sprin.web.servl.FrameworkServlet 1131 logResult: Completed 404 NOT_FOUND
and this causes the website to error:
The console log says
WebSocket connection to 'ws://localhost:8082/ws/data' failed: Error during WebSocket handshake: Unexpected response code: 404
The problems with regions was because the classes using the regions defined by #EnableClusterDefinedRegions were (a) instantiated by new command rather than Spring #Autowired; and (b) in another package not seen by the Spring Boot #ComponentScan. Once these were fixed then the regions were auto-defined and handled using #Resource annotation.
#Resource(name = "Example") private Region<Object, Object> example
Also the main program was given
SpringApplication app = new SpringApplication(Web.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
SpringApplication.run(Web.class, args);
The other problem was fixed by getting the correct dependencies in the build.gradle and then annotating endpoints for rSocket / webSocket with:
#MessageMapping(value = "helloWorld")
public Flux<String> getFluxSocket() {
log.traceEntry();
log.info("In hello world");
return Flux.just("{\"Hello\":\"World\"}");
}
or
#GetMapping(value = "/helloWorld", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> getRestSocket() {
log.traceEntry();
return Flux.just("Hello World");
}
for HTTP endpoints.

How to init " AWSPricing client " by AWSPricingClientBuilder the latest version sdk?

My task is to get aws procuct pricing data, so I do the things as follows:
set the Environment Variables(AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY)
fill the pom.xml(in Eclipse) with the code:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-pricing</artifactId>
<version>1.11.513</version>
</dependency>
then I code the test method like the code:
public static void testDescribeServices() {
System.out.println("\n\n begin ....");
AWSPricing client = AWSPricingClientBuilder.standard().withRegion("us-east-1").build();
System.out.println("step 0001");
DescribeServicesRequest servicesRequest = new DescribeServicesRequest();
servicesRequest.setServiceCode("AmazonEC2");
DescribeServicesResult result = client.describeServices(servicesRequest);
List<Service> serviceList = result.getServices();
}
run the method testDescribeServices(), the message on the console is like this: (I was disappointed)
begin ....
17:08:21.166 [main] DEBUG com.amazonaws.AmazonWebServiceClient - Internal logging successfully configured to commons logger: true
17:08:21.831 [main] DEBUG com.amazonaws.monitoring.CsmConfigurationProviderChain - Unable to load configuration from com.amazonaws.monitoring.EnvironmentVariableCsmConfigurationProvider#130d63be: Unable to load Client Side Monitoring configurations from environment variables!
17:08:21.831 [main] DEBUG com.amazonaws.monitoring.CsmConfigurationProviderChain - Unable to load configuration from com.amazonaws.monitoring.SystemPropertyCsmConfigurationProvider#42a48628: Unable to load Client Side Monitoring configurations from system properties variables!
17:08:21.831 [java-sdk-http-connection-reaper] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Closing connections idle longer than 60000 MILLISECONDS
17:08:21.839 [main] DEBUG com.amazonaws.monitoring.CsmConfigurationProviderChain - Unable to load configuration from com.amazonaws.monitoring.ProfileCsmConfigurationProvider#689604d9: The 'default' profile does not define all the required properties!
Exception in thread "main" java.lang.NoSuchMethodError: com.amazonaws.client.AwsSyncClientParams.getAdvancedConfig()Lcom/amazonaws/client/builder/AdvancedConfig;
at com.amazonaws.services.pricing.AWSPricingClient.<init>(AWSPricingClient.java:158)
at com.amazonaws.services.pricing.AWSPricingClient.<init>(AWSPricingClient.java:142)
at com.amazonaws.services.pricing.AWSPricingClientBuilder.build(AWSPricingClientBuilder.java:61)
at com.amazonaws.services.pricing.AWSPricingClientBuilder.build(AWSPricingClientBuilder.java:27)
at com.amazonaws.client.builder.AwsSyncClientBuilder.build(AwsSyncClientBuilder.java:46)
at com.yunion.apps.metadata.TestAWSDemoAPI.testDescribeServices(TestAWSDemoAPI.java:31)
at com.yunion.apps.metadata.TestAWSDemoAPI.main(TestAWSDemoAPI.java:26)
after trying some setting , I make some progress, and the new method is :
public static void testDescribeServices(String accessKey, String secretKey) {
BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(basicAWSCredentials);
AWSPricingClientBuilder builder = AWSPricingClientBuilder.standard();
builder.setCredentials(credentialsProvider);
builder.withRegion("us-east-1");
CsmConfigurationProvider csmConfigurationProvider = new EnvironmentVariableCsmConfigurationProvider();
builder.setClientSideMonitoringConfigurationProvider(csmConfigurationProvider);
System.out.println("step 0001");
AWSPricing awsPricing = builder.build();
System.out.println("step 0002");
DescribeServicesRequest servicesRequest = new DescribeServicesRequest();
servicesRequest.setServiceCode("AmazonEC2");
System.out.println("step 0003");
DescribeServicesResult result = awsPricing.describeServices(servicesRequest);
System.out.println("\n\n step 0004");
List<Service> serviceList = result.getServices();
System.out.println("\n\n step 0005");
}
However, the result is
Exception in thread "main" com.amazonaws.services.pricing.model.AWSPricingException: User: arn:aws:iam::285906155448:user/dev1 is not authorized to perform: pricing:DescribeServices **(Service: AWSPricing; Status Code: 400; Error Code: AccessDeniedException; Request ID: 13155463-4198-11e9-8f92-f1f731c320f2)**

Quartz scheduled jobs could not access datasource in Websphere

I am developing a web app where batch programs need to run for specific times. I used Quartz library to schedule the jobs. The web app is deployed on Websphere 8.5.5 and its working fine, accessing the tables through datasources (Datasource given in code is java:comp/env/jdbc/db_datasource). The job is also triggered at the mentioned times.
I am getting an error when the scheduled job makes a DB connection through the datasource and the error is:
javax.naming.ConfigurationException: A JNDI operation on a "java:" name cannot be completed because the server runtime is not able to associate the operation's thread with any J2EE application component. This condition can occur when the JNDI client using the "java:" name is not executed on the thread of a server application request. Make sure that a J2EE application does not execute JNDI operations on "java:" names within static code blocks or in threads created by that J2EE application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on "java:" names. [Root exception is javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".]
at com.ibm.ws.naming.java.javaURLContextImpl.throwExceptionIfDefaultJavaNS(javaURLContextImpl.java:522)
at com.ibm.ws.naming.java.javaURLContextImpl.throwConfigurationExceptionWithDefaultJavaNS(javaURLContextImpl.java:552)
at com.ibm.ws.naming.java.javaURLContextImpl.lookupExt(javaURLContextImpl.java:481)
at com.ibm.ws.naming.java.javaURLContextRoot.lookupExt(javaURLContextRoot.java:485)
at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:370)
I understand from the error message is that the job is running outside the J2ee container and so the datasource is not available for the Job to make the connection, which I cannot agree as the Quartz is implemented as the ServletContextListener and the same is mentioned in web.xml.
Web.xml
<listener>
<listener-class>com.ehacampaign.helper.EHAJobSchedulerListener</listener-class>
</listener>
EHAJobSchedulerListener.java
public class EHAJobSchedulerListener implements ServletContextListener {..}
As you can see the code, the class is registered in the web and I do not understand why it cannot use the datasource in the J2EE container.
Questions are:
Why servlet registered class cannot access the datasource in J2EE
container?
If datasource in container cannot be used, then how to make a
connection to the DB while executing the job?
NOTE: I have the same setup in JBoss AS 7.1 and the jobs are running smoothly accessing the datasource configured in JBoss AS 7.1. I have to develop this in Websphere as the customer demands it.
UPDATED
I have attached the modified quartz property file. Even after adding the workmanagerthread, I am getting the same error.
org.quartz.threadPool.threadCount=1
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
org.quartz.threadExecutor.class=org.quartz.commonj.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=wm/default
In order to perform JNDI lookups in WebSpehre, your code must be running on a managed thread. In order to have Quartz run on one of WebSphere's managed threads, you must set the following 2 properties in your quartz.properties (as Alasdair mentioned in the comments):
org.quartz.threadExecutor.class=org.quartz.commonj.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=wm/default
The name for org.quartz.threadExecutor.workManagerName can be the JNDI name of any Work Manager that you have configured in WebSphere. I recommend simply using wm/default because it is in your configuration by default.
With all the help provided by aguibert and Alasdair and reference from here, I am able to fix the issue.
The Quartz property file is:
org.quartz.threadPool.threadCount=1
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
org.quartz.threadExecutor.class=org.quartz.commonj.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=wm/default
The database connection or JNDI lookup should happen within the empty constructor of the JOB Implemented class. For ex,
public class ContractIdFromPartyServiceJob implements Job {
private DataSource ds;
public ContractIdFromPartyServiceJob() {
try {
Logger.info("Gets the data source");
Context context = new InitialContext();
ds = (DataSource) context.lookup(ApplicationConstants.RESOURCE_REFERENCE_JDBC);
} catch (RException e) {
e.printStackTrace();
}
}
#Override
public void execute(JobExecutionContext arg0) throws JobExecutionException
{
EHAMarsDAO marsDao = new EHAMarsDAO();
Connection con = getConnection();
try {
marsDao.callDBMethod(con);
} finally {
con.close();
}
}
public Connection getConnection() throws RACVException
{
Connection con = null;
try {
con = ds.getConnection();
con.setAutoCommit(false);
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
} catch (SQLException e) {
throw new RException(Constants.ERROR_CODE_002, Constants.E012_DB_CONNECTION_ERROR, e);
}
return con;
}
}

Drools 6.1.0 DefaultFactHandle NotSerializable exception

We are running drools 6.1.0 on Weblogic 12.1.2 as a stateless EJB 3.0 Bean. The bean returns the following exception when there is more load on the server during the initialization process when it is creating new instances in the pool.
EJB Exception: : java.lang.RuntimeException: java.io.NotSerializableException: org.drools.core.common.DefaultFactHandle
at org.drools.core.util.ClassUtils.deepClone(ClassUtils.java:514)
at org.drools.core.definitions.impl.KnowledgePackageImpl.deepCloneIfAlreadyInUse(Kn owledgePackageImpl.java:770)
at org.drools.core.definitions.impl.KnowledgePackageImpl.deepCloneIfAlreadyInUse(KnowledgePackageImpl.java:66)
at org.drools.core.impl.KnowledgeBaseImpl.addPackages(KnowledgeBaseImpl.java:722)
at org.drools.core.impl.KnowledgeBaseImpl.addKnowledgePackages(KnowledgeBaseImpl.java:266)
at org.drools.compiler.kie.builder.impl.KieContainerImpl.createKieBase(KieContainerImpl.java:412)
at org.drools.compiler.kie.builder.impl.KieContainerImpl.getKieBase(KieContainerImpl.java:346)
at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:498)
at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:443)
at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:425)
The code we have to initialize a new stateful session is as below:
protected KieSession kieSession= null;
protected ReleaseId releaseId = null; //fetched by logic to identify the release id>
if(kieSession != null){
kieSession.dispose();
kieSession = null;
}
KieServices kServices = KieServices.Factory.get();
KieContainer container = kServices.newKieContainer(this.releaseId);
kieSession = container.newKieSession();
This is happening in the constructor of the Stateless Bean.
Could you help us with any suggestions on resolving this issue?

Sending Text Message using JMS on glassfish server

I am testing JMS with glassfish server so for that i want to send simple text message on glassfish server queue. I have tried with ActiveMQ and that is going fine but i unable to understand what can i put in configuration jndi.properties file and which jar is needed for glassfish server. Please give me some idea to implement this.
thanks in advance
Since you're using Glassfish, the easiest way is to write simple application (EJB) that will perform the task. You have to define in GF:
ConnectionFactory (Resources -> JMS Resources -> Connection Factory),
let's give it JNDI name jms/ConnectionFactory
Message queue (Resources -> JMS Resources -> Destination Resources),
let's give it JNDI name jms/myQueue
Next step is to use these in some EJB that you need to write. It's not hard: firstly, you have to inject:
#Resource(mappedName="jms/ConnectionFactory")
private ConnectionFactory cf;
#Resource(mappedName="jms/myQueue")
private Queue messageQueue;
and then use it like this:
..
javax.jms.Connection conn = null;
javax.jms.Session s = null;
javax.jms.MessageProducer mp = null
try {
conn = cf.createConnection();
s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
mp = s.createProducer(messageQueue);
javax.jms.TextMessage msg = s.createTextMessage();
msg.setStringProperty("your-key", "your-value");
msg.setText("Your text message");
mp.send(msg);
}
catch(JMSException ex) {
// exception handling
}
finally {
try {
// close Connection, Session and MessageProducer
} catch (JMSException ex) {
//exception handling
}
}
Regarding configuration, you don't need any external JAR, everything that is needed is shipped. If you don't want to write EJB, but regular Java (standalone) application, then you'll have to include jms.jar and imq.jar.