Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

EJB / Thread / URLConnection

34 views
Skip to first unread message

Ashish

unread,
Apr 30, 2002, 11:21:27 AM4/30/02
to

All,

I have an EJB that needs to talk to an outside vendor using http. I could not find
an elegant way to specify the timeout in the HttpURLConnection and thus I ended up
implementing this using threads.
I was wondering if this approach has some issues (since threads usage is not exactly
recommended with EJBs).

Here is the code snippet
URLConnectionThread uct = new URLConnection(host, inMesg)
uct.start();
uct.join(timeout)
if (uct.isAlive == true) uct.interrupt.

URLConnectionThread class opens the connection and get the input/output stream.

I know that this timeout issue is fixed in JDK 1.4 but we can not afford to upgrade
at this time.

Thanks,

Slava Imeshev

unread,
Apr 30, 2002, 3:20:24 PM4/30/02
to
Hi Ashish,

Generally EJBs are not allowed to use blocking IO. The only way
to handle this kind of situation is creating a startup class that deals
with this issues. Having threads in EJBs is not a good idea by any
means.

Regards,

Slava Imeshev

"Ashish" <ash_c...@hotmail.com> wrote in message
news:3cceb677$1...@newsgroups2.bea.com...

Bob Lee

unread,
Apr 30, 2002, 3:39:41 PM4/30/02
to
You could use this instead: http://jakarta.apache.org/commons/httpclient/.

Bob

"Ashish" <ash_c...@hotmail.com> wrote in message
news:3cceb677$1...@newsgroups2.bea.com...
>

Ashish

unread,
Apr 30, 2002, 5:38:59 PM4/30/02
to

Bob,
I couldn't get the jakarta httpclient to work. Firstly, it doesn't have the HTTPUrlConnection.
If I use the HTTPClient.HTTPConnection class, I'm able to write but not read from
the port.
Did you manage to get it working correctly. I'll appreciate if you could share some
sample code.
Thanks,

Ashish.

Bob Lee

unread,
Apr 30, 2002, 5:53:19 PM4/30/02
to
I've never used in myself. The one time I ran into this problem, I just made
a direct socket connection.

Bob


"Ashish" <ash_c...@hotmail.com> wrote in message

news:3ccf0ef3$1...@newsgroups2.bea.com...

d...@dima.dhs.org

unread,
Apr 30, 2002, 6:06:18 PM4/30/02
to
Just use a different HTTP client implementation -
http://www.innovation.ch/java/HTTPClient/ for example :

HTTPConnection conn = new HTTPConnection("someserver", port);
conn.setTimeout(...);
HTTPResponse res = conn.Get("/...");
InputStream in = res.getInputStream();
...

This hack also works, if you want to keep using java.net APIs:
http://www.logicamente.com/sockets.html

Ashish <ash_c...@hotmail.com> wrote:

> All,

> Thanks,

--
Dimitri

Ashish

unread,
May 1, 2002, 11:21:40 AM5/1/02
to

I tried using the http://www.logicamente.com/sockets.html but it didn't work for me.
The timeout parameter I specify is completely ignored.
Did you get it to work ?

Appreciate your help.
Ashish.


<d...@dima.dhs.org> wrote:
>Just use a different HTTP client implementation -
>http://www.innovation.ch/java/HTTPClient/ for example :
>
>HTTPConnection conn = new HTTPConnection("someserver", port);
>conn.setTimeout(...);
>HTTPResponse res = conn.Get("/...");
>InputStream in = res.getInputStream();

>....

d...@dima.dhs.org

unread,
May 1, 2002, 4:14:31 PM5/1/02
to
You need to update HttpClientTimeout (see below) for 1.3 and use it
like this:

URL url = new URL(null, "http://...", new HttpTimeoutHandler(timeout));
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
...

(you will also need to modify weblogic.policy to allow your code to specify
handler).


--- HttpClientTimeout.java ---

import sun.net.www.http.HttpClient;
import java.net.*;
import java.io.*;

import sun.net.www.MessageHeader ;
import sun.net.ProgressEntry ;


public class HttpClientTimeout extends HttpClient
{
public HttpClientTimeout(URL url, String proxy, int proxyPort) throws IOException
{
super(url, proxy, proxyPort);
}

public HttpClientTimeout(URL url) throws IOException
{
super(url, null, -1);
}

private int timeout = -1;

public void SetTimeout(int i) throws SocketException {
timeout = i;
serverSocket.setSoTimeout(i);
}

public boolean parseHTTP(MessageHeader header, ProgressEntry entry)
throws java.io.IOException
{
if( this.timeout != -1 ) {
try {
serverSocket.setSoTimeout(this.timeout) ;
} catch( SocketException e ) {
throw new java.io.IOException("unable to set socket timeout!") ;
}
}
return super.parseHTTP(header, entry) ;
}


/* This class has no public constructor for HTTP. This method is used to
* get an HttpClient to the specifed URL. If there's currently an
* active HttpClient to that server/port, you'll get that one.
*
* no longer syncrhonized -- it slows things down too much
* synchronize at a higher level
*/
public static HttpClientTimeout GetNew(URL url)
throws IOException {
/* see if one's already around */
HttpClientTimeout ret = (HttpClientTimeout) kac.get(url);
if (ret == null) {
ret = new HttpClientTimeout (url); // CTOR called openServer()
} else {
ret.url = url;
}
// don't know if we're keeping alive until we parse the headers
// for now, keepingAlive is false
return ret;
}

public void Close() throws IOException
{
serverSocket.close();
}

public Socket GetSocket()
{
return serverSocket;
}
}
--------------------------

Ashish <ash_c...@hotmail.com> wrote:

> Appreciate your help.
> Ashish.

--
Dimitri

Ashish

unread,
May 1, 2002, 6:07:25 PM5/1/02
to

Thanks for your help.
I'm still having problems though. I changed the code to look like your sample code.
It compiles and runs okay but the timeout thing does not take affect.
Do I need to alter the classpath or something ? In my test code, I'm not even running
under weblogic. It's a standalone client trying to connect to a url. (though it has
weblogic.jar in front of the classpath).


<d...@dima.dhs.org> wrote:
>You need to update HttpClientTimeout (see below) for 1.3 and use it
>like this:
>
>URL url = new URL(null, "http://...", new HttpTimeoutHandler(timeout));
>HttpURLConnection conn = (HttpURLConnection)url.openConnection();

>....

d...@dima.dhs.org

unread,
May 1, 2002, 6:22:40 PM5/1/02
to
Hrm. I use this hack for quite a while and it works perfectly. Of course it works
only with Sun's JVM ;-)

Here is the test error:

java.io.InterruptedIOException: Read timed out
at java.net.SocketInputStream.socketRead(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:86)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:186)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:225)
at java.io.BufferedInputStream.read(BufferedInputStream.java:280)
at java.io.FilterInputStream.read(FilterInputStream.java:114)
at java.io.PushbackInputStream.read(PushbackInputStream.java:164)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:649)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:613)
at HttpClientTimeout.parseHTTP(HttpClientTimeout.java:39)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:621)
at HttpClientTimeout.parseHTTP(HttpClientTimeout.java:39)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:506)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:230)
at TestTimeout.main(TestTimeout.java:9)

And here are all .java files (for 1.3) :

TestTimeout.java

import java.io.*;
import java.net.*;

public class TestTimeout {
public static void main(String[] args) {
try {
URL url = new URL(null, "http://www.cnn.com", new HttpTimeoutHandler(10));
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
System.out.println(conn.getResponseCode());
} catch(Throwable t) {
t.printStackTrace();
}
}
}

HttpClientTimeout.java

import sun.net.www.MessageHeader ;
import sun.net.ProgressEntry ;

HttpTimeoutFactory.java

import java.net.*;

public class HttpTimeoutFactory implements URLStreamHandlerFactory
{
int fiTimeoutVal;
public HttpTimeoutFactory(int iT) { fiTimeoutVal = iT; }
public URLStreamHandler createURLStreamHandler(String str)
{
return new HttpTimeoutHandler(fiTimeoutVal);
}

}

HttpTimeoutHandler.java

import java.net.*;
import java.io.IOException;

public class HttpTimeoutHandler extends sun.net.www.protocol.http.Handler
{
int fiTimeoutVal;
HttpURLConnectionTimeout fHUCT;
public HttpTimeoutHandler(int iT) { fiTimeoutVal = iT; }

protected java.net.URLConnection openConnection(URL u) throws IOException {
return fHUCT = new HttpURLConnectionTimeout(u, this, fiTimeoutVal);
}

String GetProxy() { return proxy; } // breaking encapsulation
int GetProxyPort() { return proxyPort; } // breaking encapsulation

public void Close() throws Exception
{
fHUCT.Close();
}

public Socket GetSocket()
{
return fHUCT.GetSocket();
}
}

HttpURLConnectionTimeout.java

import java.net.*;
import java.io.*;
import sun.net.www.http.HttpClient;

public class HttpURLConnectionTimeout extends sun.net.www.protocol.http.HttpURLConnection
{
int fiTimeoutVal;
HttpTimeoutHandler fHandler;
HttpClientTimeout fClient;
public HttpURLConnectionTimeout(URL u, HttpTimeoutHandler handler, int iTimeout) throws IOException
{
super(u, handler);
fiTimeoutVal = iTimeout;
}

public HttpURLConnectionTimeout(URL u, String host, int port) throws IOException
{
super(u, host, port);
}

public void connect() throws IOException {
if (connected) {
return;
}
try {
if ("http".equals(url.getProtocol()) /* && !failedOnce <- PRIVATE */ ) {
// for safety's sake, as reported by KLGroup
synchronized (url)
{
http = HttpClientTimeout.GetNew(url);
}
fClient = (HttpClientTimeout)http;
((HttpClientTimeout)http).SetTimeout(fiTimeoutVal);
} else {
// make sure to construct new connection if first
// attempt failed
http = new HttpClientTimeout(url, fHandler.GetProxy(), fHandler.GetProxyPort());
}
ps = (PrintStream)http.getOutputStream();
} catch (IOException e) {
throw e; }
// this was missing from the original version
connected = true;
}

/**
* Create a new HttpClient object, bypassing the cache of
* HTTP client objects/connections.
*
* @param url the URL being accessed
*/
protected HttpClient getNewClient (URL url)
throws IOException {
HttpClientTimeout client = new HttpClientTimeout (url, (String)null, -1);
try {
client.SetTimeout(fiTimeoutVal);
} catch (Exception e)
{ System.out.println("Unable to set timeout value"); }
return (HttpClient)client;
}

/**
* opens a stream allowing redirects only to the same host.
*/
public static InputStream openConnectionCheckRedirects(URLConnection c)
throws IOException
{
boolean redir;
int redirects = 0;
InputStream in = null;

do {
if (c instanceof HttpURLConnectionTimeout) {
((HttpURLConnectionTimeout) c).setInstanceFollowRedirects(false);
}

// We want to open the input stream before
// getting headers, because getHeaderField()
// et al swallow IOExceptions.
in = c.getInputStream();
redir = false;

if (c instanceof HttpURLConnectionTimeout) {
HttpURLConnectionTimeout http = (HttpURLConnectionTimeout) c;
int stat = http.getResponseCode();
if (stat >= 300 && stat <= 305 &&
stat != HttpURLConnection.HTTP_NOT_MODIFIED) {
URL base = http.getURL();
String loc = http.getHeaderField("Location");
URL target = null;
if (loc != null) {
target = new URL(base, loc);
}
http.disconnect();
if (target == null
|| !base.getProtocol().equals(target.getProtocol())
|| base.getPort() != target.getPort()
|| !HostsEquals(base, target)
|| redirects >= 5)
{
throw new SecurityException("illegal URL redirect");
}
redir = true;
c = target.openConnection();
redirects++;
}
}
} while (redir);
return in;
}

// Same as java.net.URL.hostsEqual


static boolean HostsEquals(URL u1, URL u2)
{
final String h1 = u1.getHost();
final String h2 = u2.getHost();

if (h1 == null) {
return h2 == null;
} else if (h2 == null) {
return false;
} else if (h1.equalsIgnoreCase(h2)) {
return true;
}
// Have to resolve addresses before comparing, otherwise
// names like tachyon and tachyon.eng would compare different
final boolean result[] = {false};

java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
try {
InetAddress a1 = InetAddress.getByName(h1);
InetAddress a2 = InetAddress.getByName(h2);
result[0] = a1.equals(a2);
} catch(UnknownHostException e) {
} catch(SecurityException e) {
}
return null;
}
});

return result[0];
}

void Close() throws Exception
{
fClient.Close();
}

Socket GetSocket()
{
return fClient.GetSocket();
}
}

Ashish <ash_c...@hotmail.com> wrote:

--
Dimitri

Ravi Mathur

unread,
May 6, 2002, 6:08:38 PM5/6/02
to

Hi Ashish,

We have the same problem. Could you please tell what we need to do with jdk 1.4 to
resolve this issue.

Thanks,
-Ravi Mathur

0 new messages