Apache camel remote EJB call is failing through JBOSS EAP 6.4 - java

EJB call is successfull, if it is deployed in the local machine. When if it is called by the remote jboss machine, below exception is thrown
Exchange-exception :java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:, moduleName:ejbmavendemo-0.0.1-SNAPSHOT, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext#43a094bf
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:747)
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116)
Configuration used in the camel-context.xml is as below
click on this link to view the xml details
Not sure, what is missing. Please advice

It can have several issues :
connection: Connection broken
security : user/pass invalid
EJB missing: connected, but ejb is not there
SSL
The EJBClientContext will keep all available receiver in a Map where the servers name is the key. If there is more than one server with the same name these entries will be lost.
If it is inside of a server instance this instance will be preferred and all other instances with the same server name are hidden.
In this case no EJB will be accessible which is only available on such server.
check the outbound-connection
check the user and password at destination server (NOTE: need to be EAP application user, not management user)
check the secret value at target server
check that there are no extra spaces left after the specifying a property in jboss-ejb-client.properties file.
enable org.jboss.ejb.client and org.jboss.remoting for TRACE logging to see detailed messages for the invocation at client side.
JBoss maintains a persistent connection to the other server, so when the client sees this message it means there is no connection to a server that has the ejb you are trying to call, so a message will be logged when the connection fails to the other server.

Related

Accessing remote ejb from classic websphere application with websphere liberty application

I need some help using remote ejb calls. There is the following setup:
Background:
A JavaEE web application (naming it app1) is hosted on an oldschool WAS8 application server. The application provides at least one (knowen) remote ejb for application to application communication.
An other JavaEE web application (naming it app2) is hosted on a websphere liberty server. (We are currently migrate this application from WAS8 to websphere liberty.) This application (app2) now has to access the remote ejb provided by app1.
Problems:
The old implementation of the remote ejb call did not perfom with websphere liberty. I did a lot of research and was able to migrate the remote ejb call. That looks like this:
try {
// Holds the server address
String server = "server.address:port";
// Building JNDI address:
// E.g. corbaname:iiop:server:port/java:global/app1/ejb-module/BeanImpl!qualified.name.of.RemoteBean
StringBuilder address = new StringBuilder("corbaname:iiop:") // Protocol
.append(server) // Server address
.append("/") // Separator
.append("java:") // EJB context
.append("global/") // Globales Repository
.append("app1/") // Applikation
.append("ejb-module/") // module
.append("BeanImpl!") // Bean
.append("qualified.name.of.RemoteBean"); // Remote Interface
// Performing jndi lookup (shadowed remote ejb call by context (liberty server))
Object o = InitialContext.doLookup(address.toString());
// Casting requested object
service = (qualified.name.of.RemoteBean) PortableRemoteObject.narrow(o,
qualified.name.of.RemoteBean.class);
} catch (NamingException e) {
// Catching naming errors
log.warn("Cannot read app1 URL from JNDI: {}.", e.getMessage());
log.error("Exeption: ", e);
} catch (SystemException e) {
// Catching any other error
log.warn("Cannot connect to app1: {}", e.getMessage());
log.error("Exeption: ", e);
}
This code compiles and is executable w/o any naming exception.
I am still not able to successfully request any remote ejb object. On every request, a org.omg.CORBA.OBJ_ADAPTER exception occures with the following stacktrace (error message: org.omg.CORBA.OBJ_ADAPTER: : vmcid: 0x4942f000 minor code: 0xb81 completed: No):
Exeption: org.omg.CORBA.OBJ_ADAPTER:
at org.apache.yoko.orb.OB.Util.unmarshalSystemException(Util.java:165)
at org.apache.yoko.orb.OB.GIOPConnection.processReply(GIOPConnection.java:543)
at org.apache.yoko.orb.OB.GIOPConnection.processMessage(GIOPConnection.java:365)
at org.apache.yoko.orb.OB.GIOPConnectionThreaded.execReceive(GIOPConnectionThreaded.java:429)
at org.apache.yoko.orb.OB.GIOPConnectionThreaded.access$200(GIOPConnectionThreaded.java:42)
at org.apache.yoko.orb.OB.GIOPConnectionThreaded$Receiver.run(GIOPConnectionThreaded.java:68)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
I have no idea what is happening there. I guess that the requesting VM (Oracle Java 8) is not able to read the object from the response (sent from IBM J9 VM with Java 6)
Infrastructure information:
The WAS8 is running with the IBM J9 VM with java version 1.6.0 on a linux server, hosted in my companies intranet. The WAS8 is version 8.0.0.15 ND.
The websphere liberty is running with the Java HotSpot(TM) 64-Bit Server VM with java version 1.8.0_172-b11 on a windows 10 machine, connected via VPN to the same network zone like the WAS8 application server. Liberty is version 18.0.0.2
Question:
Is the JNDI address correct? The binding of the remote ejb is the following (from server startup log):
[1/11/19 13:26:21:230 CET] 00000008 EJBContainerI I CNTR0167I: The server is binding the qualified.name.of.RemoteBeaninterface of the BeanImplenterprise bean in the ejb-module.jar module of the app1 application. The binding location is: BeanImpl
[1/11/19 13:26:21:246 CET] 00000008 AbstractEJBRu I CNTR0167I: The server is binding the qualified.name.of.RemoteBeaninterface of the BeanImplenterprise bean in the ejb-module.jar module of the app1 application. The binding location is: java:global/app1/ejb-module/BeanImpl!qualified.name.of.RemoteBeaninterface
Is it possible to call a remote ejb from an other jvm with a different vendor an a different version in general?
Is there any documentation about WAS8 concerning it's NameService?
A similar thread in DeveloperWorks discusses the issue of a Liberty client invoking an EJB in tWAS. At the time, there was question on whether Liberty had this functionality. RFE 32815 has since been implemented. And Liberty doc shows examples of EJB lookups (see links given below.)
In any case, based on the stacktrace you posted, it appears the CORBA.OBJ_ADAPTER is being thrown on the tWAS server and the client is processing that exc from within a reply message from the server. Trace from the server may be necessary. I would also run dumpnamespace on your tWAS server in order to see the topology-based ejb object you're trying to look up and try using that rather than the java:global name.
As to your specific questions:
A1. While the "java:global" indirect name may be valid, most lookups I see into tWAS namespace employ topology-based qualified names (e.g. cell//node/...)
A2. In general, yes, interoperability between different CORBA/Naming versions and vendors should exist.
A3. See links listed below.
If none of the following doc helps, it would be best to open a ticket with IBM support so we can more easily exchange logs etc and tap the various Liberty, tWAS Naming/EJB experts.
Doc Links:
Using enterprise JavaBeans with remote interfaces on Liberty
TroubleShooting: JNDI and naming problems
Example: Looking up an EJB home or business interface with JNDI
Namespace logical view

CONNECTION_REFUSED from Apache 2.2 server ( the channel to weblogic 10.3.6 server)

I built a web-service application using Jdeveloper 11.1.1.7 and deployed on weblogic 10.3.6 on physical server let us call it back-end server.
I do not want to give client direct access to back-end server so I make use of Apache 2.2 to be in the middle of client and back-end server. Apache 2.2 is configured on different physical server let us call it middle server.
I defined application's context root (which deployed in back-end server) on middle server in Apache httpd.conf file.
I shared WSDL file location to client ( WSDL URL which referring to the middle server domain name). The external client can access the URL thorug browser where he/she can see the WSDL content
But when the client trying send requests to middle server URL it get rejected with the following error:
[error] [client -clinet public IP goes here-] ap_proxy: trying POST /[application context root goes
here] at backend host '[back-end server local IP]/[port goes here]; got exception 'CONNECTION_REFUSED
[os error=0, line 1602 of URL.cpp]: apr_socket_connect call failed with error=730061, host=[back-end
server local IP], port=[port goes here]'
This error from middle server Apache error log file. No logs from back-end server
What is done so far:
I check the if I can access the middle server as external user using the telnet command. telnet IP port. It is working and the middle server is listening.
I also checked for all ports. between external client and middle server, between middle server and back-end server also using telnet. All ports working.
In this answer : ssl - Apache 2 with Weblogic Plug-in Redirection, original location still requested to backend - Server Fault
they are suggestion to increase the Accept Backlog value from weblogic server tuning . I did that in back-end server but still the issue is not resolved.
Problem resolved
I need to enable (WebLogic Plug-In Enabled) option from weblogic server where the application is deployed
from Domain Structure (Left Panel in admin console) - > Environment - > Servers -> (select the server where you deploy your application on it) - > General tab (from server setting)-> Advance - > (tic the option) WebLogic Plug-In Enabled
Then restarted the server.
By this your are telling the server you will get indirect request through proxy server or load balancer for example
You can do this on many level like cluster or server based on your needs check this site for more information
Understanding the use of “WebLogic Plugin Enabled”

WebService test from within Weblogic server (12c)

I have deployed a sample webservice application to remote weblogic server (12C) which has a datasource that accesses a remote database server.
The deployment was successful.
The data source was tested OK from within the Weblogic Server.
But when I am trying to test the webservice (which uses this datasource) I am getting the following error
inside weblogic
When I am testing the same webservice from standalone url (webservice test client - see image) I am getting the following error for the same method. The User name and passowrd for base authentication is correct. Though I am not very sure what/why the base authentication is required, since the data-source has it all. Please advise how to test a webservice that is acessing a remote database through a data source. Link to an example using remote weblogic server and remote database server will also be a great help.
! [In webservice test client]

How to pass user defined username from IBM Websphere Application server to AS400 MQ server for authentication?

I am having an issue with connecting AS400 MQ Local Queue, its rejecting with code JMSWMQ2013.
My appserver has a username as mquser#mydomain.com but in AS400 I am not able to give the specified username in MQ Object Authority.
Is there any way to connect to the queue defined in AS400 machine from Websphere Appserver on windows machine?
Below is the error i am facing while connecting:
FFDC Exception:com.ibm.msg.client.jms.DetailedJMSSecurityException SourceId:com.ibm.ejs.jms.JMSManagedQueueConnection.createConnection ProbeId:116 Reporter:com.ibm.ejs.jms.JMSManagedQueueConnection#db6f33e4
com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'TESTQMGR' with connection mode 'Client' and host name 'AS400T(1416)'.
Please check if the supplied username and password are correct on the QueueManager to which you are connecting.
Root cause:
JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:204)
Maybe you need to define separate J2C authentication alias and map it to the connection factory. What does it mean that My appserver has a username as mquser#mydomain.com?
Check this page 2035 MQRC_NOT_AUTHORIZED Connecting to WebSphere MQ for more details:
The two most likely reasons why the connection is refused by MQ are as follows:
1. The user identifier passed across the client connection from the application
server to MQ is not known on the server where the MQ queue manager is running,
is not authorised to connect to MQ, or is longer than 12 characters and has
been truncated.
For queue managers running on Windows, the following error might be seen in
the MQ error logs for this scenario:
AMQ8075: Authorization failed because the SID for entity 'wasuser'
cannot be obtained.
For UNIX no entry in the MQ error logs would be seen by default.
See technote MQS_REPORT_NOAUTH environment variable can be used
to better diagnose return code 2035 for details of enabling error log
entries on all platforms.
2. The user identifier passed across the client connection from the
application server to MQ is a member of the 'mqm' group on the server
hosting the MQ queue manager, and a Channel Authentication Record (CHLAUTH)
exists that blocks administrative access to the queue manager.
WebSphere MQ configures a CHLAUTH record by default in WebSphere MQ
Version 7.1 and later that blocks all MQ admins from connecting
as a client to the queue manager.
The following error in the MQ error logs would be seen for
this scenario: AMQ9777: Channel was blocked
You indicate in a later comment that you are using MQ V7.0 on AS/400.
Your question details that you have a user ID mquser#mydomain.com which will not be recognised by the AS/400 O/S.
Therefore you are looking for a way to assign a user ID for the connection which you are making from the App Server on Windows so that it can run using a recognised user ID on the AS/400 queue manager.
Since you are pre-V7.1, you cannot use CHLAUTH rules, so your choices are
Write a security exit to do it (or buy/download one)
Give this connection its own channel and set the MCAUSER on the SVRCONN to something that is known and recognised by the AS/400 O/S. In this case, please also make sure you have some form of authentication, e.g. SSL/TLS so that no-one else can use this channel.
Yes, Username and password can be passed with setStringProperty on MQQueueConnectionFactory
MQQueueConnectionFactory mqConFactory = new MQQueueConnectionFactory();
mqConFactory.setStringProperty(WMQConstants.USERID, "username");
mqConFactory.setStringProperty(WMQConstants.PASSWORD, "password");
//other configs
mqConFactory.setHostName("MQ_HOST");
mqConFactory.setChannel("MQ_CHANNEL");//communications link
mqConFactory.setPort("MQ_PORT");
mqConFactory.setQueueManager("MQ_MANAGER");//service provider
mqConFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
Needed imports:
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.msg.client.wmq.WMQConstants;
Dependency jars:
compile('com.ibm.mq:com.ibm.mq.allclient:9.0.5.0')
Part of code took from this page

Java resolve dns via proxy when using custom ProxySelector

I'm in need to develop a java library which allows a traffic to be directed via proxy only for specified hosts.
The library is almost ready and working, but there is problem with resolving dns addresses via proxy.
In short words I extended CustomProxySelector class which has following logic:
public class CustomProxySelector extends ProxySelector {
public List<Proxy> select(URI uri) {
if (customProxyDefinedFor(uri)) {
return getCustomProxyFor(uri);
} else {
// use direct connection
}
}
}
All works fine if local dns can resolve host given as "uri" parameter (for example if I want stackoverflow.com to go via proxy it will work because my local dns can resolve stackoverflow.com).
The problem comes when there is a host which is not known to my local dns. For example the dns behind proxy knows how to resolve address like "host1.private.dmz" because this is special host only known behind proxy (the proxy acts really as reverse proxy here). JVM seems to first try to resolve "host1.private.dmz" to ip, and when it fails it ends with folowing stacktrace:
Caused by: java.net.UnknownHostException: host1.private.dmz
at java.net.InetAddress.getAllByName0(InetAddress.java:1259)
at java.net.InetAddress.getAllByName(InetAddress.java:1171)
at java.net.InetAddress.getAllByName(InetAddress.java:1105)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:247)
(...)
Because it fails to resolve the ip, my Custom ProxySelector is never used. Is there any option to force java not to resolve ip via localdns but via proxy?
If I give the ip address of host1.private.dmz (for example 10.100.12.13) all works ok. The communication is directed to my Custom Proxy Selector and the traffic goes via custom proxy without problem.
I solved this issue. The important thing to fix this problem is correct understanding that the problem does not lay in jvm but in application. Jvm does not try to resolve host1.private.dmz before calling custom proxy selector, it is the application itself.
If we have a look at last line of the stacktrace you can see that exception comes from mysql jdbc driver, so it is mysql driver who trys to resolve host1.private.dmz to IP address, before actually opening connection to that host. Therefore because application does not open a connection (because exception occurs when application trys to resolve dns), no proxy selector is called ("no connection" == "no proxy selector").
What can we do in such case?
If it is you who writes the application, simply don't resolve the IP by calling InetAddress.getAllByName() and directly open connection to host domain name (host1.private.dmz). If for some reason you need an IP than handle the exception (in case of exception try to open connection without resolving the address). If still this is not acceptable for you there is one more option. You can instruct jvm to use extra DNS server which is able to resolve IP of this domain. You can do this by setting following properties:
System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun");
System.setProperty("sun.net.spi.nameservice.nameservers", "10.200.2.3,100.40.70.5);
This should set extra dns server for your application.
There can however be one more problematic situation. An attempt to resolve domain name to ip might take place before you have the chance to set up extra dns servers. For example you might be running web application on Tomcat with database connection pool configured in Tomcat's context. In such case the exception "UnknownHostException" can happen before you set up extra dnses. In such case you can run this application by "proxifying it". Strictly in java you can do this by using jProxyLoader library (http://jproxyloader.sourceforge.net) , for example by running the application with following parameters:
-Djava.system.class.loader=net.sf.jproxyloader.JProxyLoader -DjplDnsServers=10.0.1.18
Above example will set up 10.0.1.18 as extra dns server (which is able to resolve the uknown domain name) at application startup. Thanks to this extra dns will already be available when application boots up.
You understand more about this problem, by having a look at jProxyLoader troubleshooting page: http://jproxyloader.sourceforge.net/troubleshooting.html

Categories