JAX-RS Client API async request - jax-rs

I am trying to use the JAX-RS Client API to request a resource through HTTP GET, by using the following code: (I used jersey-client v2.12 and also resteasy-client v3.0.8.Final to test the implementation)
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.InvocationCallback;
public class StackOverflowExample {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
client.target("http://example.com/").request().async().get(new InvocationCallback<String>() {
#Override
public void completed(String s) {
System.out.println("Async got: " + s);
}
#Override
public void failed(Throwable throwable) {
System.out.println("Async failure...");
}
});
}
}
As I expected the String is printed almost immediately. But the process keeps running about one minute, although there isn't any code that should be executed.
The JAX-RS spec just says that we should use the InvocationCallback and nothing else that matters to my issue. But even if I use a Future the same effect happens. I also tested, if this has something to do with a timeout, which was very unlikely and wrong. The debugger shows that there are some threads running namely DestroyJavaVM and jersey-client-async-executor-0 or pool-1-thread-1 in the case of resteasy.
Do you have any idea what is going wrong here?

It is allways helpful to consult the JavaDoc. Concerning my issue it says:
Clients are heavy-weight objects that manage the client-side communication infrastructure. Initialization as well as disposal of a Client instance may be a rather expensive operation. It is therefore advised to construct only a small number of Client instances in the application. Client instances must be properly closed before being disposed to avoid leaking resources.
If I close the client properly everything is working as expected.
public class StackOverflowExample {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
// request here
client.close();
}
}

Related

How to detect application pool restart of a WCF service?

In my WCF service I use a static dictionary to hold some resource intensive data. I need to clean up the resources when the application pool gets recycled. Is there any method (for example event) by which I can detect that application pool is being recycled?
if your application pool gets recycled all your static objects will be reset. you can clean all external resources (like files or ...) when creating an instance of your static dictionary. something like this:
public static partial class ProjectValues
{
public static ConcurrentDictionary<string, string> MessageDictionary { private set; get; }
static ProjectValues()
{
try
{
MessageDictionary = new ConcurrentDictionary<string, string>();
//then clear the resource here
}
catch (Exception ex)
{
return;
}
}
}
Is there any method( for example event) by which I can detect that
application pool is being recycled?
Kinda.
According to Phill Haack, IIS exposes a static method called HostingEnvironment.RegisterObject, which allows you to pass implementations of IRegisteredObject into it.
In theory, this tells IIS to call the IRegisteredObject.Stop operation before it decides to kill the w3wp.exe process your app is running in.
I say in theory because this approach is not fail-safe and there are instances where the AppDomain can go away without calling, or even to call but then shut down anyway, before you're finished doing your cleanup.

Apache cxf java client + ntlm authentication and multi user support

I am using apache cxf java client to connect my WS. I am also using NTLM for authentication.
Now problem I am facing due to credential caching. First time i tried user which does not have privileges to access WS method. when I changed the user , it is still using same user to access WS method.
I am running in tomcat, so cannot kill my JVM .. tried all possible combination on httpClientPolicy.
Any help will be appreciated.
This is NTLM specific problem. sun.net.www.protocol.https.HttpsURLConnectionImpl is getting serverAuthorization via java.net.Authenticator. requestPasswordAuthentication(). This authorization info is maintained in sun.net.www.protocol.http.AuthCacheValue.cache.
So if we override sun.net.www.protocol.http.AuthCacheValue means we can fix this issue.
AuthCacheValue.setAuthCache(new AuthCache()
{
#Override
public void remove(String arg0, AuthCacheValue arg1) { }
#Override
public void put(String arg0, AuthCacheValue arg1) { }
#Override
public AuthCacheValue get(String arg0, String arg1)
{
return null;
}
});
Reference :
http://web.archiveorange.com/archive/v/ACbGtycfTs2dqbRNpy6d
http://tigrou.nl/2011/06/11/cached-credentials-in-http-basic-authentication/
I googled and tried a lot of solutions to this problem.. apparently the simplest code that worked is as below using the JCIFS library
//Set the jcifs properties
jcifs.Config.setProperty("jcifs.smb.client.domain", "domainname");
jcifs.Config.setProperty("jcifs.netbios.wins", "xxx.xxx.xxx.xxx");
jcifs.Config.setProperty("jcifs.smb.client.soTimeout", "300000"); // 5 minutes
jcifs.Config.setProperty("jcifs.netbios.cachePolicy", "1200"); // 20 minutes
jcifs.Config.setProperty("jcifs.smb.client.username", "username");
jcifs.Config.setProperty("jcifs.smb.client.password", "password");
//Register the jcifs URL handler to enable NTLM
jcifs.Config.registerSmbURLHandler();
Apparently CXF 3.0 doesnt have a valid way of configuring the HTTP Client (4.3.x) with NTCredentials instance. Please refer to bug https://issues.apache.org/jira/browse/CXF-5671
By the way, if you have a simple message which needs to be transmitted, just use HTTP Client (I worked using 4.3.4.. not sure of the earlier versions) with NTCredentials Instance. That too did the magic for me.. The sample is as below:
final NTCredentials ntCredentials = new NTCredentials("username", "Passworrd","destination", "domain");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, ntCredentials);
CloseableHttpClient httpclient = HttpClientBuilder.create()
.setDefaultCredentialsProvider(credsProvider)
.build();

Ninject Interceptors

I'm developing a WPF desktop application with caliburn.micro framework, and I want to configure ninject interceptors so that I can intercept method calls. I would like to do this to handle exceptions in a centralized place, so that I don't have many try-catch blocks everywhere around my code.
I haven't been able to acomplish this, because everytime I wire everything up with ninject, the system throws an exception.
So here's some code:
The AppBootstrapper configure method looks like this:
protected override void Configure()
{
_kernel = new StandardKernel(new NinjectServiceModule());
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
_kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();
_kernel.Bind<ISomeViewModel>().To<SomeViewModel>().Intercept().With<SomeInterceptor>() //this is where the exception is thrown;
_kernel.Bind<IShell>().To<ShellViewModel>();
}
Now the intercept method in my interceptor:
public void Intercept(IInvocation invocation)
{
if (invocation.Request.Method.Name == "TheMethodIWantIntercepted")
{
try
{
invocation.Proceed();
}
catch (Exception)
{
Console.WriteLine("I Handled exception");
}
}
else
{
invocation.Proceed();
}
}
The method in the view model looks like this:
public virtual void TheMethodIWantIntercepted()
{
//Some logic here
}
So that's how interceptors are supposed to work. But it doesn't work, everytime I run the program, and ninject tries to inject the instance of SomeViewModel into ISomeViewModel, the program execution fails, and this is the exception that is thrown (and the stack trace):
http://pastebin.com/qerZAjVr
Hope you can help me with this, thank you in advance.
You have to load either DynamicProxy(2)Module or LinFuModule depending on what proxy library you prefer.
Also be aware that Ninject 2.2 will create a class proxy for SomeViewModel which requires:
a parameterless constructor
virtual methods
Interface proxies don't have this restriction but this requires Ninject 3.0.0

How do I force GlassFish 2 to load EJBs on startup?

We're using EJB3 on GlassFish v2.
My application includes a GenericServlet called StartupServlet, which has an init method. java.util.TimerTask pollers started from this method cannot lookup facades from the InitialContext.
However if I make an HTTP request and do a lookup, it succeeds. Therefore I have a workaround now where my poller startup code makes an HTTP connection to a page which looks up the interfaces they need.
How can I rearrange my application so I don't need to use such a hack? If possible the solution needs to work on GFv3 as well.
Thanks in advance for your help!
On GF 2, I have a servlet that on start ensures that my timer is created. This looks up a remote session bean and calls it successfully from the init() (not actual code, distilled down to the important parts):
#EJB(name="TimerSessionRef", beanInterface=TimerSessionRemote.class)
public class StartTimers extends HttpServlet {
#Override
public void init() throws ServletException {
super.init();
try {
Context ctx = new InitialContext();
TimerSessionRemote timerSession = (TimerSessionRemote) ctx.lookup("java:comp/env/TimerSessionRef");
timerSession.createTimer();
} catch (NamingException ex) {
logger.blah();
}

How can we detect when a WCF client has disconnected?

Is there any way of finding out when a WCF client has disconnected. Currently the only approach seems to be to wait until a call on the client from the service eventually times out.
I have tried subscribing to the OperationContext.Current.Channel.Faulted event but unfortunately it is never called; my understanding was that this event should be fired when the client disappears. On the other hand, when things close down gracefully OperationContext.Current.Channel.Closed is called.
In our application we only support a single client connection at a time, hence when somebody closes and re-starts the client app it would be nice if the server could be made aware of the the disconnection, tidy up gracefully and then accept another connection.
Yes, clients will disconnect gracefully most of the time, but this can't be guaranteed. Currently the only option seems to be to poll the client and wait for a CommunicationTimeout, which is hardly ideal.
Any suggestions greatly appreciated.
Theoretically, a service need not have knowledge of client's state. But it can insist on whom to serve for by dictating the authentication needs, concurrency limitation etc.
If you intention is to make sure only one client is served at a time, you can simply opt for Single Concurrency mode.
For example.
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single)]
public class CalculatorService : ICalculatorConcurrency
This will ensure only one client request is served at a time. Following link may help you as well.
http://msdn.microsoft.com/en-us/library/ms731193.aspx
EDIT
If you think an user's action of keeping the channel open does disturb the other user's work, it may not be the usual case.
Because each user's call is considered to be a different session. By default WCF calls are considered to be instantiated per call.
If you would like to persist data between user's calls, you may opt for perSession instancing mode.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorInstance
This would make sure that each user would have an instance of the service which would not inturrupt servicing the other user.
You can set the concurrency mode accordingly i.e Multiple or Reentrant if you wish. Even if the concurrency mode is single, when a response is sent back to the user the service would be ready to serve the next user. It won't wait for the client to close the connection. User's connection would be useful only to keep the session live.
You can use IChannelInitializer and hook up Channel Close and Channel faulted events to detect graceful or abrupt closing of the client. Refer to a very nice post on this by Carlos - http://blogs.msdn.com/b/carlosfigueira/archive/2012/02/14/wcf-extensibility-initializers-instance-context-channel-call-context.aspx
You could use Callback Operations to make a call to the client to see if its still connected.
Take a look at this article on MSDN magazine
if (HttpContext.Current.Response.IsClientConnected == false
{
...
}
it can help you
I've had success using a "disconnection detector" like this:
// Code based on https://blogs.msdn.microsoft.com/carlosfigueira/2012/02/13/wcf-extensibility-initializers-instance-context-channel-call-context/
public class WcfDisconnectionDetector : IEndpointBehavior, IChannelInitializer
{
public event Action Disconnected;
public int ConnectionCount { get; set; } = 0;
public WcfDisconnectionDetector() { }
public WcfDisconnectionDetector(Action onDisconnected) => Disconnected += onDisconnected;
void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime cr)
=> cr.ChannelInitializers.Add(this);
void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher ed)
=> ed.ChannelDispatcher.ChannelInitializers.Add(this);
void IEndpointBehavior.Validate(ServiceEndpoint endpoint) { }
void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
void IChannelInitializer.Initialize(IClientChannel channel)
{
ConnectionCount++;
Trace.WriteLine($"Client {channel.SessionId} initialized");
channel.Closed += OnDisconnect;
channel.Faulted += OnDisconnect;
}
void OnDisconnect(object sender, EventArgs e)
{
ConnectionCount--;
Disconnected?.Invoke();
}
}
Install it before calling ServiceHost.Open:
var detector = new WcfDisconnectionDetector();
serviceHost.Description.Endpoints.Single().EndpointBehaviors.Add(
new WcfDisconnectionDetector(() => {/*disconnected*/}));