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.
Related
The project is written using Play framework and Scala language.
I have implemented compile time dependency.
I have followed this example from Play:
https://github.com/playframework/play-scala-compile-di-example
Looking at the MyApplicationLoader.scala:
import play.api._
import play.api.routing.Router
class MyApplicationLoader extends ApplicationLoader {
private var components: MyComponents = _
def load(context: ApplicationLoader.Context): Application = {
components = new MyComponents(context)
components.application
}
}
class MyComponents(context: ApplicationLoader.Context)
extends BuiltInComponentsFromContext(context)
with play.filters.HttpFiltersComponents
with _root_.controllers.AssetsComponents {
lazy val homeController = new _root_.controllers.HomeController(controllerComponents)
lazy val router: Router = new _root_.router.Routes(httpErrorHandler, homeController, assets)
}
and the following line of code:
lazy val homeController = new _root_.controllers.HomeController(controllerComponents)
my understanding is that there is only one instance of HomeController created the first time HomeController is called.
And that instance lives as long as the application lives. Are these statements correct?
The HomeController in my application looks like that:
class HomeController{
val request = // some code here
val workflowExecutionResult = Workflow.execute(request)
}
So Workflow is of type object and not class.
The Workflow looks like that:
object Workflow {
def execute(request: Request) = {
val retrieveCustomersResult = RetrieveCustomers.retrieve()
// some code here
val createRequestResult = CreateRequest.create(request)
// some code here
workflowExecutionResult
}
}
So Workflow calls a few domain services and each domain service is of type object and not class.
All values inside the domain services are immutable, I am using vals everywhere.
Is this enough to ensure thread safety?
I am asking as I'm used to writing C# Web APIs where a HomeController would look like that:
class HomeControllerInSeeSharpProject{
// some code here
var request = new Request() // more code here
var workflow = new WorkflowInSeeSharpProject()
var workflowExecutionResult = workflow.execute(request)
}
and a Workflow would look like that:
public class WorkflowInSeeSharpProject {
public execute(Request request) {
var retrieveCustomers = new RetrieveCustomers()
var retrieveCustomersResult = retrieveCustomers.retrieve()
// some code here
var createRequest = new CreateRequest()
var createRequestResult = createRequest.create(request)
// some code here
return workflowExecutionResult
}
}
So in a C# project every time a HomeControllerInSeeSharpProject is called a new instance of WorkflowInSeeSharpProject is created and all the domain services
are also newed-up and then I can be sure that state cannot be shared between separate threads. So I am afraid that because my Scala Workflow
and domain services are of type object and not class that there could be a situation where two requests are sent into the HomeController
and state is shared between those two threads.
Can this be the case? Is my application not thread safe?
I have read that objects in Scala are not thread safe since there is only single instance of them. However I have also read that although
they are not thread safe using vals will make the application thread safe...
Or maybe Play itself has a way to deal with that problem?
Because your are using compile time dependency injection, you control the number of instances created, and in your case HomeController is created only once. As requests come in, this single instance will be shared between threads so indeed you have to make sure it is thread-safe. All the dependencies of HomeController will also need to be thread-safe, thus object Workflow has to be thread-safe. Currently, Workflow is not publicly exposing any shared state, so it is thread-safe. In general, val definitions within object are thread-safe.
In effect HomeController is behaving like a singleton and avoiding singletons could be safer. For example, by default Play Framework uses Guice dependency injection which creates a new controller instance per request as long as it is not a #Singleton. One motivation is there is less state to worry about regarding concurrency protection as suggested by Nio's answer:
In general, it is probably best to not use #Singleton unless you have
a fair understanding of immutability and thread-safety. If you think
you have a use case for Singleton though just make sure you are
protecting any shared state.
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 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!
I have a task to do it in background after an HTTP Post Request,
so can I do it like this way in Java7 EE. (They said that Java7 EE can use the JSE concurrencies). so here is my code:
#POST public String contactMe( #FormParam("name") String name, #FormParam("email") String email, #FormParam("website") String website, #FormParam("message") String message) {
System.out.println("you have sent name " + name + " email " + email + " website " + website + " message " + message);
/*methode Timer*/
Timer timer = new Timer();
MyTimerTask myTimerTask=new MyTimerTask();
timer.schedule(myTimerTask,10000);
//I have to do something n back ground that take 10 seconds at least
return "<h1>DONE</h1>";
}
I am confused may be there is a better way to handle these kind of problem in the Enterprise World, because memory managing is different than desktop apps.
Thanks in advance.
Finally, I have got the answer and I am happy with JEE7 Multithreading tools:
#Stateless
public class ReportBean {
#Resource
private ManagedThreadFactory threadFactory;
public void runReports() {
Thread thread = threadFactory.newThread(new Runnable());
thread.start();
}
I've used this bean in my work...
The Java EE7 offer a new way to make the using of JAVA SE Managed by the Web Container and not by the JVM.
What is the purpose of your timer?
Your code receives some GET info, then waits 10 seconds and then starts performing the myTimerTask.
Edit:
upon inspecting your post a little further: it seems like you want to perform the task synchronously; if that is truly the case, just execute the timertask.
However your comment suggests that you wish to perform the task in the background, but then I don't understand why you seem to imply that you want to wait for 10 seconds.