I want to write a web frontend that wants to "propagate" the HTTP authentication received from the browser to a JBoss AS 4.2.3 that exposes numerous #Remote interfaces.
Consider the following trivial simulation of RMI call concurrency:
Properties user1 = new Properties();
user1.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.security.jndi.JndiLoginInitialContextFactory");
user1.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming");
user1.setProperty(Context.PROVIDER_URL, "127.0.0.1:1099");
user1.setProperty(Context.SECURITY_PRINCIPAL, "user1");
user1.setProperty(Context.SECURITY_CREDENTIALS, "pass1");
Properties user2 = new Properties();
user2.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.security.jndi.JndiLoginInitialContextFactory");
user2.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming");
user2.setProperty(Context.PROVIDER_URL, "127.0.0.1:1099");
user2.setProperty(Context.SECURITY_PRINCIPAL, "user2");
user2.setProperty(Context.SECURITY_CREDENTIALS, "pass2");
InitialContext ctx1 = new InitialContext(user1);
Mine bean1 = (Mine) ctx1.lookup("myear/MyBean/remote");
InitialContext ctx2 = new InitialContext(user2);
Mine bean2 = (Mine) ctx2.lookup("myear/MyBean/remote");
System.out.println(bean1.whoami());
System.out.println(bean2.whoami());
Call uses jbossall-client 4.2.3 and goes to a JBoss AS 4.2.3.
The .whoami() method simply echoes the logged-in username. As it turns our, this results in both calls saying they are made by "user2". Presumably, the underlying connection is shared and only authenticated using the last seen properties bundle.
In short, this sucks. Some preliminary testing indicates that the same problem remains in JBoss AS 7 so no luck.
Is there any other RMI client implementation I can use or any parameter I can pass in the prop bundle to make the InitialContexts not share their login info? Alternatively, can someone point me to the code that needs to be hacked to make this possible?
UPDATE:
As per request:
public class Worker extends Thread {
private final String pass, user;
private int correct = 0;
public Worker(String user, String pass) { this.user = user; this.pass = pass; }
public void run() {
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.security.jndi.JndiLoginInitialContextFactory");
props.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming");
props.setProperty(Context.PROVIDER_URL, "127.0.0.1:1099");
props.setProperty(Context.SECURITY_PRINCIPAL, this.user);
props.setProperty(Context.SECURITY_CREDENTIALS, this.pass);
try {
InitialContext ctx = new InitialContext(props);
for(int i = 0; i < 100; i++) {
Mine bean = (Mine) ctx.lookup("myear/MyBean/remote");
if(bean.whoami().equals(this.user)) this.correct++;
Thread.sleep(2); }
ctx.close();
} catch (Exception e) { throw new RuntimeException(e); }
System.out.println("Done [id="+this.getId()+", good="+this.correct+"]");
}
}
Running with two workers yields:
public static void main(String[] args) throws Exception {
new Worker("user1", "pass1").start();
new Worker("user2", "pass2").start();
}
Done [t=9, good=0]
Done [t=10, good=100]
Running with 5 threads yields:
public static void main(String[] args) throws Exception {
new Worker("user1", "pass1").start();
new Worker("user2", "pass2").start();
new Worker("user3", "pass3").start();
new Worker("user4", "pass4").start();
new Worker("user5", "pass5").start();
}
Caused by: javax.ejb.EJBAccessException: Authentication failure
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.handleGeneralSecurityException(Ejb3AuthenticationInterceptor.java:68)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:70)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:304)
at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:809)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:608)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:406)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:173)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:163)
at org.jboss.remoting.Client.invoke(Client.java:1634)
at org.jboss.remoting.Client.invoke(Client.java:548)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:67)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:53)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:107)
at $Proxy0.whoami(Unknown Source)
at net.windwards.Worker.run(TestRMIClient.java:31)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:74)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:67)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:53)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:107)
at $Proxy0.whoami(Unknown Source)
at net.windwards.Worker.run(TestRMIClient.java:31)
Making the initial connection takes about 100 ms, so I tried the following (sleeping 10 ms between calls to get good overlap):
public static void main(String[] args) throws Exception {
new Worker("user1", "pass1").start();
Thread.sleep(200);
new Worker("user2", "pass2").start();
Thread.sleep(200);
new Worker("user3", "pass3").start();
Thread.sleep(200);
new Worker("user4", "pass4").start();
Thread.sleep(200);
new Worker("user5", "pass5").start();
}
Done [t=9, good=1]
Done [t=14, good=12]
Done [t=15, good=14]
Done [t=16, good=15]
Done [t=17, good=100]
From the docs for org.jboss.security.jndi.JndiLoginInitialContextFactory :
During the getInitialContext callback from the JNDI naming, layer security context identity is populated with the username ... and the credentials ... There is no actual authentication of this information. It is merely made available to the jboss transport layer for incorporation into subsequent invocations
in this case, by the time you get to invoke your beans, user2 is the last principal set and so is the one available to be used by the jboss transport layer.
However, from the jboss4 source, it looks like you can make the security context scoped to the thread context, in which case your threaded test should work, simply add this property:
userN.setProperty("jnp.multi-threaded", "true");
Another solution would be using org.jboss.security.jndi.LoginInitialContextFactory instead of org.jboss.security.jndi.JndiLoginInitialContextFactory, unlike JndiLoginInitialContextFactory, LoginInitialContextFactory will try to authenticate when the look up is made, not when the EJB is invoked, you could give it a try, even though in the docs, they recommend JndiLoginInitialContextFactory when it comes to EJB authorization on remote clients
The basic problem here is that you haven't close the first context before you use the second one in the same thread. I doubt that this is a fair test. It would be more interesting to actually make the two concurrent, by running them both in separate threads.
When the getInitialContext() is being called from the JNDI, the Security Layer invokes a wrapper with the credential tiles; which is factually never verified with a source, it is just type of a virtual representation of the tiles to JBOSS for subsequent calls to the same entity model.
In your case, user2 is the last one to be available to JBOSS.
Alternatively, you can also use multiple instances of JBOSS on the
same machine by using ServiceBindingManager. This could help you
keep a track of all RMI calls you make, also the properties for the
Connector Object do work because itself is a JMX Bean Object.
You can also use a threaded model which can give you additional security by
adding a property
userN.setProperty("jnp.multi-threaded", "true");
And just as a suggestion, I found online Use JndiLoginInitialContextFactory for EJB Authentication on remote clients.
Hope this helps!
Related
I want to write the testcase for the given method. But there exist a static Transport.sendEmail method.
How can I mock this method using MockitoJunitRunner.
public void sendEmail(final String message, final String contentType) {
final Session session = Session.getDefaultInstance(PROPERTIES, null);
final Multipart mpart = new MimeMultipart();
final MimeBodyPart body = new MimeBodyPart();
try {
body.setContent(message, contentType);
mpart.addBodyPart(body);
Transport.send(createMessage(session, mpart));
LOGGER.info("Email Notification Sent Successfully");
} catch (MessagingException | UnsupportedEncodingException e) {
LOGGER.error("Was not able to send mail", e);
}
So:
Transport.send(createMessage(session, mpart));
that static call means: you can't "control" it using Mockito. Plain and simple. If that call just "passes" in your unit test environment, well, then you can test it, but not verify that the call really took place. Worse, if that call throws some exception in the unit test setup, then heck, what could you do?
Options:
turn to PowerMock(ito) or JMockit, as they allow you to gain control
recommended: improve your design to be easy-to-test
That last idea comes in various flavors:
For example, you could create a minimal interface EmailSenderService that offers a void send(Message whatever) method. Next: you create one implementation of that interface that simply invokes that static method. Now your code that actually has to send that message ... simply gets passed in an instance of EmailSenderService. And within your unit tests, you can now #Mock that interface, and you gain control over it.
Alternatively, you simply deprecate that static method (maybe the whole class), and you design a new "real" EmailSenderService that doesn't rely on static methods.
I have code in a standalone application that invokes an Acumatica action to generate reports; I am running into timeouts on large documents while the action completes.
What is the best method to handle these timeouts? I need to wait for the action to complete in order to retrieve the files I've generated.
Standalone application code:
public SalesOrder GenerateAcumaticaLabels(string orderNbr, string reportType)
{
SalesOrder salesOrder = null;
using (ISoapClientProvider clientProvider = soapClientFactory.Create())
{
try
{
SalesOrder salesOrderToFind = new SalesOrder
{
OrderType = new StringSearch { Value = orderNbr.Split(OrderSeparator.SalesOrder).First() },
OrderNbr = new StringSearch { Value = orderNbr.Split(OrderSeparator.SalesOrder).Last() },
ReturnBehavior = ReturnBehavior.OnlySpecified,
};
salesOrder = clientProvider.Client.Get(salesOrderToFind) as SalesOrder;
InvokeResult invokeResult = new InvokeResult();
invokeResult = clientProvider.Client.Invoke(salesOrder, new exportSFPReport());
ProcessResult processResult = clientProvider.Client.GetProcessStatus(invokeResult);
//Wait for the update to complete before we attempt to retrieve the files
while (processResult.Status == ProcessStatus.InProcess)
{
Thread.Sleep(1000); //pause for 1 second
processResult = clientProvider.Client.GetProcessStatus(invokeResult);
}
}
And the action in Acumatica:
public PXAction<SOOrder> ExportSFPReport;
[PXButton]
[PXUIField(DisplayName = "Generate Robot SFP PDF")]
protected IEnumerable exportSFPReport(PXAdapter adapter)
{
//Report Paramenters
Dictionary<String, String> parameters = new Dictionary<String, String>();
parameters["SOOrder.OrderType"] = Base.Document.Current.OrderType;
parameters["SOOrder.OrderNbr"] = Base.Document.Current.OrderNbr;
IEnumerable reportFileInfo = ExportReport(adapter, "IN619217", parameters);
exportTrayLabelReport(adapter, "SFP");
return reportFileInfo;
}
The problem here is that your action is synchronous, so it is trying to complete within the Invoke call (which is not a good thing for long processes). You have to explicitly make your operation long-running by using PXLongOperation.StartOperation inside your handler, and then your client code should work properly, as it already handles the waiting and checking.
I believe the reason why you encounter time-out is because there is no TCP communication between the time you sent the request and receive the response. With TCP KeepAlive flag set to true, the client will periodically ping the server to reset the time-out period.
That would be the best way. However Acumatica connections are rather high level so I don't think you'll be able to easily access that flag. What I would try first in a scenario that doesn't involve external application is to wrap your action event-handler code in a PXLongOperation block which has to do something similar to keep connection alive under the hood:
PXLongOperation.StartOperation(this or Base, delegate
{
your code here
});
When I do encounter time-outs in Acumatica that can't be solved with PXLongOperation I go for the simplest method which is increasing IIS timeout in Web.Config file. I'm not sure if your use case with external application will go well with async PXLongOperation. The handler would return prematurely and the client could not be able to retrieve the async payload.
So you might have to increase time-out instead. As far as I know there's no real practical drawback to doing this unless your website is under threat of DOS attacks.
You can locate and edit the Web.Config file of your Acumatica instance using inetmgr program if you are self-hosting Acumatica. Otherwise talk to your SAAS contact to see if that's an option.
I'm pretty sure you are hitting IIS time-out. A tell-tale sign would be lost connection after exactly 5 minutes which is the default 300 seconds value. You can edit Web.Config file to increase executionTimeout value. It's not a bad idea to increase maxRequestLength too if you are requesting large amount of data from Acumatica API as this is also a common cause of failure that you miss in testing and occurs in real-life scenarios:
<httpRuntime executionTimeout="300" requestValidationMode="2.0" maxRequestLength="1048576" />
I created a Spring Boot (1.4.2) REST application. One of the #RestController methods needs to invoke a 3rd party API REST operation (RestOp1) which returns, say between 100-250 records. For each of those records returned by RestOp1, within the same method, another REST operation of the same 3rd party API (RestOp2) must be invoked. My first attempt involved using a Controller class level ExecutorService based on a Fixed Thread Pool of size 100, and a Callable returning a record corresponding to the response of RestOp2:
// Executor thread pool - declared and initialized at class level
ExecutorService executor = Executors.newFixedThreadPool(100);
// Get records from RestOp1
ResponseEntity<RestOp1ResObj[]> restOp1ResObjList
= this.restTemplate.exchange(url1, HttpMethod.GET, httpEntity, RestOp1ResObj[].class);
RestOp1ResObj[] records = restOp1ResObjList.getBody();
// Instantiate a list of futures (to call RestOp2 for each record)
List<Future<RestOp2ResObj>> futureList = new ArrayList<>();
// Iterate through the array of records and call RestOp2 in a concurrent manner, using Callables.
for (int count=0; count<records.length; count++) {
Future<RestOp2ResObj> future = this.executorService.submit(new Callable<RestOp2ResObj>() {
#Override
public RestOp2ResObj call() throws Exception {
return this.restTemplate.exchange(url2, HttpMethod.GET, httpEntity, RestOp2Obj.class);
}
};
futureList.add(future);
});
// Iterate list of futures and fetch response from RestOp2 for each
// record. Build a final response and send back to the client.
for (int count=0; count<futureList.size(); count++) {
RestOp2ResObj response = futureList.get(count).get();
// use above response to build a final response for all the records.
}
The performance of the above code is abysmal to say the least. The response time for a RestOp1 call (invoked only once) is around 2.5 seconds and that for a RestOp2 call (invoked for each record) is about 1.5 seconds. But the code execution time is between 20-30 seconds, as opposed to an expected range of 5-6 seconds! Am I missing something fundamental here?
Is the service you are calling fast enough to handle that many requests per second?
There is an async version of RestService is available called AsyncRestService. Why are you not using that?
I would probably go like this:
AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(new ConcurrentTaskExecutor(Executors.newFixedThreadPool(100)));
asyncRestTemplate.exchange("http://www.example.com/myurl", HttpMethod.GET, new HttpEntity<>("message"), String.class)
.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
#Override
public void onSuccess(ResponseEntity<String> result) {
//TODO: Add real response handling
System.out.println(result);
}
#Override
public void onFailure(Throwable ex) {
//TODO: Add real logging solution
ex.printStackTrace();
}
});
Your question involves two parts :
multiple API callbacks asynchronously
handle timeouts (fallback)
both parts are related as you've to handle the timeout of each call.
you may consider use Spring Cloud (based on spring boot) and use some out of the box solution based on OSS Netflix stacks.
The first (timeouts) on should be a circuit breaker hystrix based on feign client
The second (multiple requests) this is an architecture issue, using native Executors isn't a good idea as it will not scale and has a huge maintenance costs. You may relay on Spring Asynchrounous Methods you'll have better results and fully spring compliant.
Hope this will help.
experts
I'm running into a trouble when access the home page in my MVC 5 web site, please see the exception details below.
MVC 5.2.2
EntityFramework 6.1.1
Visual Studio 2013
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryGetFieldOrPropertyValue(MemberExpression me, Object instance, Object& memberValue)
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryEvaluatePath(Expression expression, ConstantExpression& constantExpression)
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.EvaluateParameter(Object[] arguments)
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassc.<GetResultsAsync>b__a()
at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteInTransactionAsync>d__3d`1.MoveNext()
The code is quite simple, it query data asynchronously from the data context shared in the current OwinContext, it works well as usual, but accidentally, it fail because of the error previously.
public class TalentsService : ServiceBase
{
public async Task<List<TalentSummaryViewModel>> GetSlotlightTalents()
{
var talents = await DbContext.Talents.Where(t => t.IsSpotlight && IsAuthenticated).ToListAsync();
return talents.Select(t => WrapModel(t)).ToList();
}
}
public abstract class ServiceBase
{
private ApplicationDbContext _dbContext;
public ApplicationDbContext DbContext
{
get
{
return _dbContext ?? HttpContext.Current.GetOwinContext().Get<ApplicationDbContext>();
}
private set
{
_dbContext = value;
}
}
public bool IsAuthenticated
{
get
{
return HttpContext.Current.Request.IsAuthenticated;
}
}
}
Is that multi-thread related? I can't figure out what could be the root cause, any clue would be appreciated, thanks in advance.
Thanks Chris Pratt for the response which led me to double check my code, the root cause is that:
The HttpContext.Current is null in some scenario which I'm not aware of, then the call to this property IsAuthenticated failed, so I would have to store the IsAuthenticated value in a local variable, now I could repro this issue easily when use the LoadTest tool to launch lots of request, but still not clear why does the context get lost accidentally, probably somebody else have more knowledge on this.
I had the same error after the 1st HTTP request to my Web API which was reproducible only if the IIS application was recycled. Apparently after restarting IIS the first incoming request was initiating data retrieval via IQueryable with inline ClientID parameter extracted from:
(HttpContext.Current.User as ClaimsPrincipal).Claims collection in asynchronous fashion.
So by the time the I/O operation was completed -- the HttpRequest context did not exist...
Copying Http Claim value into separate variable and using this variable when contructing IQueryable solved the problem:
var claims = (HttpContext.Current.User as ClaimsPrincipal).Claims;
I'm working on CXF client services but load test (1000 concurrent users) leads to lot's of locked threads and JVM crash. The threads seems to be locked on the Jaxb class AccessorInjector :
com/sun/xml/bind/v2/runtime/reflect/opt/AccessorInjector#341F3D78/341F3D84
My client is a singleton which is called by a servlet. The client calls the webservice like that :
HttpServlet :
SRecherche srech = SRecherche .getInstance();
String reponse = srech.recherche(parametres, retour);
Client Service :
public static SRecherche getInstance() {
synchronized (SRecherche .class) {
if (instance == null) {
instance = new SRecherche();
}
}
return instance;
}
.
.
.
.
public String recherche(String parametres, String retour[]) {
SampleSOAPService sampleSOAPService = new SampleSOAPService(ClassLoader.getSystemResource("service.wsdl"));
SampleSOAP s = sampleSOAPService .getService();
((BindingProvider) s).getRequestContext().put("thread.local.request.context", "true");
// set the username and password
((BindingProvider) s).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username);
((BindingProvider) s).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
//set timeout to be longer
Client client = ClientProxy.getClient(s);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(timeout);
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setReceiveTimeout(timeout);
httpClientPolicy.setConnection(ConnectionType.CLOSE);
http.setClient(httpClientPolicy);
.
.
.
s.callService(...);
.
.
}
I'm working on weblogic 9.2/Java 5.0/CXF 2.5
Do you have any idea about how lot's of simultaneous call of that client may lead to locked threads ?
JDK Version :
J2RE 5.0 IBM J9 2.3 AIX ppc-32 build j9vmap3223-20081129
JVM Parameters :
-Xjcl:jclscar_23
-Dcom.ibm.oti.vm.bootstrap.library.path=/usr/java5/jre/bin
-Dsun.boot.library.path=/usr/java5/jre/bin
-Djava.library.path=/usr/java5/jre/bin:/usr/java5/jre/bin:/usr/java5/jre/bin/classic:/usr/java5/jre/bin:/exec/products/weblogic/v9.2/bea/patch_weblogic921/profiles/default/native:/exec/products/weblogic/v9.2/server/native/aix/ppc:/usr/java5/jre/bin/j9vm:/usr/lib
-Djava.home=/usr/java5/jre
-Djava.ext.dirs=/usr/java5/jre/lib/ext
-Duser.dir=/exec/products/weblogic/v9.2/user_projects/domains/rforce
_j2se_j9=70912 0xF12ACF08
vfprintf 0x300017A4
-Xms2048m
-Xmx2048m
-Dcom.sun.xml.namespace.QName.useCompatibleSerialVersionUID=1.0
-da
-Dplatform.home=/exec/products/weblogic/v9.2
-Dwls.home=/exec/products/weblogic/v9.2/server
-Dwli.home=/exec/products/weblogic/v9.2/integration
-Dweblogic.management.discover=true
-Dwlw.iterativeDev=false
-Dwlw.testConsole=false
-Dwlw.logErrorsToConsole=
-Dweblogic.ext.dirs=/exec/products/weblogic/v9.2/bea/patch_weblogic921/profiles/default/sysext_manifest_classpath
-Dcom.wily.introscope.agentProfile=/exec/products/weblogic/introscope/wily/IntroscopeAgent_prod.profile
-javaagent:/exec/products/weblogic/introscope/wily/Agent.jar
-Dcom.wily.introscope.agent.agentName=RFORCE
-Dweblogic.Name=RForceServer
-Djava.security.policy=/exec/products/weblogic/v9.2/server/lib/weblogic.policy
-Dinvokedviajava
-Djava.class.path=/exec/products/weblogic/v9.2/server/lib/geronimo-ws-metadata_2.0_spec-1.1.3.jar:/exec/products/weblogic/v9.2/user_projects/domains/rforce/config/rforce/:/exec/products/weblogic/v9.2/user_projects/domains/rforce/config/rforce/wsdl/drakkar/:/usr/java5/lib/tools.jar:/exec/products/weblogic/v9.2/server/lib/weblogic_sp.jar:/exec/products/weblogic/v9.2/server/lib/weblogic.jar:/exec/products/weblogic/v9.2/server/lib/webservices.jar::/exec/products/weblogic/v9.2/common/eval/pointbase/lib/pbclient51.jar:/exec/products/weblogic/v9.2/server/lib/xqrl.jar::
vfprintf
_port_library 0xF12AC748
-Xdump
Thanks,
Simon
Just from a quick glance, since you are doing pretty much everything manually (i.e. handling all the connections, etc.) about the only thing I could recommend would be to start a threqad in your public String recherche(String parametres, String retour[]) implementation.
Wrap all the code you have there in an anonymous runnable or Thread instance and kick it off. The thread will handle all the processing and response to client, leaving the recherche() method free to take another call.
Just a thought.
Also in the way of FYI, the client in what you describe above would actually be the Servlet, as it is making the call to the service. Or in other words, it looks like the Servlet is the consumer and the singleton is the provider.