JBoss return org.jboss.remoting.ProtocolException: Too many channels open - jboss

My program encountered a error:
"org.jboss.remoting3.ProtocolException: Too many channels open"
I have search from internet for some solutions to fix this error.Unfortunately, the suggestions from others is not working for me.
Below is the Code on how I call the jndi remote and the properties that I have used.
public static void createUser(String loginID) throws Exception {
Hashtable props = new Hashtable();
try {
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
props.put(Context.PROVIDER_URL, "remote://" + localhost:4447);
props.put("jboss.naming.client.ejb.context", "true");
props.put(Context.SECURITY_PRINCIPAL, "userJBoss");
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
context = new InitialContext(props);
context.lookup("ejb:/createUserOperation/CreateUserGenerator!password.api.CreateUserService");
.....
......
LOGGER.info("DONE");
} catch (Exception e) {
LOGGER.error("ERROR");
} finally {
context.close();
}
}
Due to some certain reason I am not able to show all the content of the method.
The "createUser" will be call everytime when there is a needed of create new user. It will be call up to hundred or thousand time.
I did always close the connection when every time it finish execute the method.
Let say I have call the method for 100 times, some of the users will be created successfully whereas some of the users will be failed.
Error below will prompt to me:
2014-12-04 17:23:23,026 - ERROR [Remoting "config-based-naming-client-endpoint" task-4] (org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver- Line:134) - Failed to open channel for context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext#bbaebd6, receiver=Remoting connection EJB receiver [connection=Remoting connection <78e43506>,channel=jboss.ejb,nodename=webdev01]} org.jboss.remoting3.ProtocolException: Too many channels open
Once the error occurred, it required me to restart my jboss.And it comes again after sometimes.
Appreciate it if anyone wound able to help on my problem faced.
Thanks

You are using mixture of context properties.
This should be enough
final Properties ejbProperties = new Properties();
ejbProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
ejbProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
ejbProperties.put("remote.connections", "1");
ejbProperties.put("remote.connection.1.host", "localhost");
ejbProperties.put("remote.connection.1.port", "4447");
ejbProperties.put("remote.connection.1.username", "ejbuser");
ejbProperties.put("remote.connection.1.password", "ejbuser123!");
final EJBClientConfiguration ejbClientConfiguration = new PropertiesBasedEJBClientConfiguration(ejbProperties);
final ConfigBasedEJBClientContextSelector selector = new ConfigBasedEJBClientContextSelector(ejbClientConfiguration);
EJBClientContext.setSelector(selector);
final Context context = new InitialContext(ejbProperties);
// lookup
Foo proxy = context.lookup("ejb:/createUserOperation/CreateUserGenerator!password.api.CreateUserService");
when using org.jboss.ejb.client.naming it creates EJBClientContext object.
When closing context you are closing InitialContext not EJBClientContext
to close EJBClientContext:
EJBClientContext.getCurrent().close();

There is a known JBoss bug (EAP 6, AS 7) whereby opening and closing too many InitialContext instances too quickly causes the following error:
ERROR: Failed to open channel for context EJBReceiverContext
Instead of:
final Properties properties = ...
final Context context = new InitialContext( properties );
Try caching the context for a set of properties instead:
private Map<Integer, InitialContext> initialContexts = new HashMap<>();
final Context context = getInitialContext(properties);
private InitialContext getInitialContext(final Properties properties) throws Exception {
final Integer hash = properties.hashCode();
InitialContext result = initialContexts.get(hash);
if (result == null) {
result = new InitialContext(properties);
initialContexts.put(hash, result);
}
return result;
}
Remember to call close() when the context is no longer necessary.

Related

Is RESTEasy RegisterBuiltin.register necessary when using ClientResponse<T>

I am developing a REST client using JBOSS app server and RESTEasy 2.3.6. I've included the following line at the beginning of my code:
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
Here's the rest of the snippet:
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(host, port, AuthScope.ANY_REALM), new UsernamePasswordCredentials(userid,password));
ClientExecutor executor = createAuthenticatingExecutor(httpclient, host, port);
String uriTemplate = "http://myhost:8080/webapp/rest/MySearch";
ClientRequest request = new ClientRequest(uriTemplate, executor);
request.accept("application/json").queryParameter("query", searchArg);
ClientResponse<SearchResponse> response = null;
List<MyClass> values = null;
try
{
response = request.get(SearchResponse.class);
if (response.getResponseStatus().getStatusCode() != 200)
{
throw new Exception("REST GET failed");
}
SearchResponse searchResp = response.getEntity();
values = searchResp.getValue();
}
catch (ClientResponseFailure e)
{
log.error("REST call failed", e);
}
finally
{
response.releaseConnection();
}
private ClientExecutor createAuthenticatingExecutor(DefaultHttpClient client, String server, int port)
{
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
HttpHost targetHost = new HttpHost(server, port);
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
// Create ClientExecutor.
ApacheHttpClient4Executor executor = new ApacheHttpClient4Executor(client, localContext);
return executor;
}
The above is a fairly simple client that employs the ClientRequest/ClientResponse<T> technique. This is documented here. The above code does work (only left out some trivial variable declarations like host and port). It is unclear to me from the JBOSS documentation as to whether I need to run RegisterBuiltin.register first. If I remove the line completely - my code still functions. Do I really need to include the register method call given the approach I have taken? The Docs say I need to run this once per VM. Secondly, if I am required to call it, is it safe to call more than one time in the same VM?
NOTE: I do understand there are newer versions of RESTEasy for JBOSS, we are not there yet.

ExecuteReader requires an open connection

I am getting the error: "ExecuteReader requires an open connection" and I know the fix is to add a connection.Open() / connection.Close(). My question pertaining to this error is more for me to understand exactly what happen under the hood.
I am currently using the "USING" statement which I expect it to open and close/dispose the connection for me. So I guess I don't understand why it didn't work as expected and I needed to explicitly code the connection.Open() / connection.Close() myself to fix the issue. I did some research and found people experienced similar issue because they were using static connection. In my case, I am creating a new instance of the connection... hence, it bothers me and hoping to get to the bottom of this instead of just fix it and move on. Thank you in advance.
Here is the code:
try
{
using (SqlConnection connection = new SqlConnection(myConnStr))
using (SqlCommand command = new SqlCommand("mySPname", connection))
{
command.CommandType = CommandType.StoredProcedure;
//add some parameters
SqlParameter retParam = command.Parameters.Add("#RetVal", SqlDbType.VarChar);
retParam.Direction = ParameterDirection.ReturnValue;
/////////////////////////////////////////////////
// fix - add this line of code: connection.Open();
/////////////////////////////////////////////////
using(SqlDataReader dr = command.ExecuteReader())
{
int success = (int)retParam.Value;
// manually close the connection here if manually open it. Code: connection.Close();
return Convert.ToBoolean(success);
}
}
}
catch (Exception ex)
{
throw;
}
Using does not open any connections, it only disposes of any allocated memory after calling End Using.
For the SqlConnection, you have to explicitly open it inside the using block, you just don't need to close it though.
I also notice that you are missing a set of brackets {} around the using SqlConnection. Maybe that's the issue? It should be like this:
try
{
using (SqlConnection connection = new SqlConnection(myConnStr))
{
connection.Open();
using (SqlCommand command = new SqlCommand("InsertProcessedPnLFile", connection))
{
command.CommandType = CommandType.StoredProcedure;
//add some parameters
SqlParameter retParam = command.Parameters.Add("#RetVal", SqlDbType.VarChar);
retParam.Direction = ParameterDirection.ReturnValue;
/////////////////////////////////////////////////
// fix - add this line of code: connection.Open();
/////////////////////////////////////////////////
using(SqlDataReader dr = command.ExecuteReader())
{
int success = (int)retParam.Value;
// manually close the connection here if manually open it. Code: connection.Close();
return Convert.ToBoolean(success);
}
}
}
}

org.apache.http.NoHttpResponseException: XX.XX.XX.XX:443 failed to respond

Currently I am using Apache http components client V4.3.5. In my case, I can upload small file(1kb), but it is not working on large file(100kb) when I run the code and get the exception "org.apache.http.NoHttpResponseException: 192.168.128.109:443 failed to respond". Can anyone take a look at my code and let me know what causes my issue?
Here is my code:
public static void main(String[] args) throws IOException,
KeyStoreException {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(
null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.disableContentCompression();
builder.setSSLSocketFactory(sslsf);
SocketConfig config = SocketConfig.custom().setSoKeepAlive(true).setSoTimeout(300000).build();
builder.setDefaultSocketConfig(config);
CloseableHttpClient httpclient = builder.build();
HttpPost httppost = new HttpPost("https://192.168.128.109/upload");
String encodedAuthorization = DatatypeConverter
.printBase64Binary("admin:itronitr".getBytes());
httppost.setHeader("Authorization", "Basic " + encodedAuthorization);
FileBody bin = new FileBody(new File("c:\\test.txt"));
String boundary = "hK1oPL5_XSfbm6lkCNlKI63rltrew5Bqik0ul";
HttpEntity reqEntity = MultipartEntityBuilder.create()
.setBoundary(boundary).addPart("upfile", bin).build();
httppost.setEntity(reqEntity);
System.out.println(httppost.getEntity().getContentLength());
System.out
.println(httppost.getEntity().getContentType().toString());
CloseableHttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println(response.getStatusLine());
String content = EntityUtils.toString(resEntity);
System.out.println(content);
} catch (Exception exc) {
exc.printStackTrace();
}
}
Thanks,
Bill
Finally I fix the issue and it is caused by buffer size. By default, buffer size of httpclient is 8k. So I change it to 4k and my code works well.
Here is the code that changes buffer size:
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setBufferSize(4128)
.build();
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultConnectionConfig(connectionConfig)
.build();
This is what worked for me; may or may not work for you!!
I recently encountered the same issue and tried all the suggestions whatever I was able to find on internet i.e upgrading httpClient to latest version and adding a re-try handler ; but none fixed it for me.
I already had a re-try handler built in my code and was running on the latest Apache client, but it was still failing with the exception Caused by: org.apache.http.NoHttpResponseException: xxxxx:443 failed to respond
So, took me almost 2 days to debug this issue and find the root cause (at-least in my case)
There seems to be a bug in older Java versions up to Java 11.0.3 included that prevents Apache HTTP Client from sending payloads bigger than 16368 bytes caused by https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8214339.
I was running on java 11.0.2 and when I upgraded to 11.0.10, it worked for me and I was able to send the bigger payload without any code changes
I also faced the similar problem. I went through many blogs and forums and tried various things but none worked for me. So, I tried a workaround. I added retry handler as below. And it worked for me:
HttpClientBuilder.create()
.setDefaultCredentialsProvider(provider)
.setRetryHandler(new DefaultHttpRequestRetryHandler() {
#Override
public boolean retryRequest(final IOException exception, final int executionCount, final HttpContext context) {
if (exception instanceof NoHttpResponseException) {
return true;
}
return super.retryRequest(exception, executionCount, context);
}
})
.build();
Although it is not a correct fix and just a workaround but it is working for me for now. I'll stick to this solution till I won't get any permanent solution. Sharing it here in case someone might get benefit from it.

Delete all messages in queue Websphere 8.5 SIB via JMX

I want to delete all the messages in a queue configured in Websphere 8.5 SIB. Below are two approaches I tried, but none of them seem to be working and each throws a different exception. Can someone please advise on what is the correct way to achieve this.
Approach 1
MBeanServerConnection connection = getServerConnection();
connection.invoke(new ObjectName("WebSphere:*,type=SIBQueuePoint,name=jms.queue.MY_QUEUE"), "deleteAllQueuedMessages", null, null);
This approach throws the below exception.
javax.management.InstanceNotFoundException: WebSphere:type=SIBQueuePoint,name=jms.queue.MY_QUEUE
Approach 2
MBeanServerConnection connection = getServerConnection();
ObjectName objQueue = new ObjectName(WAS85_RESOURCE_URL + ",type=SIBQueuePoint");
Set<ObjectName> objNames = connection.queryNames(objQueue, null);
for(ObjectName objName: objNames) {
String qName = connection.getAttribute(objName,"identifier").toString();
if(qName.equals("jms.queue.MY_QUEUE")) {
connection.invoke(objName, "deleteAllQueuedMessages", null, null);
}
}
This approach throws the below exception.
javax.management.ReflectionException: Target method not found: com.ibm.ws.sib.admin.impl.JsQueuePoint.deleteAllQueuedMessages
Figured out the issue.
The 2nd approach works. The issue was with my invocation of the deleteAllQueuedMessages message. The method takes a boolean argument which indicates the messages should be moved to the Exception Destination. I was not passing this argument !!!
I corrected the implementation as below and it works now.
connection.invoke(objName, "deleteAllQueuedMessages", new Object[]{false}, new String[]{"java.lang.Boolean"});
A better way to delete all Messages is something like that:
String queryString = "WebSphere:*,type=JMSAdministration";
ObjectName queryServer = new ObjectName(queryString);
String serverStr = "";
Set pet = aClient.queryNames(queryServer, null);
Iterator itsServer = pet.iterator();
if (itsServer.hasNext())
serverStr = itsServer.next().toString();
ObjectName obj = new ObjectName(serverStr);
Object param[] = { "jms/messageQueue","jms/messageCF" };
String signature[] = { "java.lang.String","java.lang.String" };
aClient.invoke(obj, "clear", param, signature);
Using MBean JMSAdministration is better because you can set Query exacly.

quickfix SocketInitiator has no response and no exception

I'm trying to connect to a ForexTrading broker FIX API and do some trading.
I tried my best to read through the Quickfix for .net. and almost understand the process of how the quickfix works. However, when I try to initiate the socketinitiator, I failed to do that and there are no complaints and exceptions from VS 2012. It is simply stuck there.
Here's my code:
private void iFind_ItemClick(object sender, ItemClickEventArgs e)
{
try
{
QuickFix.SessionSettings settings = new QuickFix.SessionSettings("C:\\Users\\Administrator\\Documents\\My Box Files(shewenhao#hotmail.com)\\Work With Mr.Liu\\ForexAutoTradingSystem\\ForexAutoTradingSystem\\integralfix.cfg");
IntegralFixAPI integralFixAPIApplication = new IntegralFixAPI();
QuickFix.IMessageStoreFactory storeFactory = new QuickFix.FileStoreFactory(settings);
QuickFix.ILogFactory logFactory = new QuickFix.ScreenLogFactory(settings);
QuickFix.Transport.SocketInitiator initiator = new QuickFix.Transport.SocketInitiator(
integralFixAPIApplication, storeFactory, settings, logFactory);
MessageBox.Show(settings.ToString());
integralFixAPIApplication.MyInitiator = initiator;
initiator.Start();
while (true)
{
Thread.Sleep(200);
MessageBox.Show("true");
}
//initiator.Stop();
}
catch (System.Exception systeme)
{
Console.WriteLine(systeme.Message);
Console.WriteLine(systeme.StackTrace);
}
}
You may notice that I have a MessageBox right below the SocketInitiator and it pops up before this QuickFix.Transport.SocketInitiator line. I do not get it that why I failed at this point. On the page of quickfix .Net http://quickfixn.org/tutorial/creating-an-application, it says that you simply need to replace the threadedacceptor with the socketinitiator. However, I can not pass through this initiation line.