I need to automatically detect if a user requires a proxy to access the internet. Is there a way for a Java application to read the systems proxy setting?
Thanks,
Jimmy
Java SE 1.5 provides ProxySelector class to detect the proxy settings. If there is a Direct connection to Internet the Proxy type will be DIRECT else it will return the host and port.
Example below illustrates this functionality:
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URI;
import java.util.Iterator;
import java.util.List;
public class TestProxy {
public static void main(String[] args) {
try {
System.setProperty("java.net.useSystemProxies","true");
List<Proxy> l = ProxySelector.getDefault().select(
new URI("http://www.yahoo.com/"));
for (Iterator<Proxy> iter = l.iterator(); iter.hasNext(); ) {
Proxy proxy = iter.next();
System.out.println("proxy hostname : " + proxy.type());
InetSocketAddress addr = (InetSocketAddress)proxy.address();
if(addr == null) {
System.out.println("No Proxy");
} else {
System.out.println("proxy hostname : " + addr.getHostName());
System.out.println("proxy port : " + addr.getPort());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
The other, accepted, answer is undoubtedly excellent and correct but I thought I would add something here...
If you are on a machine that is configured with "auto detect proxy settings", which I believe is called PAC, the code to detect the proxy in the answer using the Java gubbins will not work (it will think it is a "direct" connection).
There is a library called proxy vole (new BSD license I think), however, that you can use instead so here's the other answer's code slightly modified to use that:
public class testProxy {
public static void main(String[] args) {
try {
System.setProperty("java.net.useSystemProxies","true");
// Use proxy vole to find the default proxy
ProxySearch ps = ProxySearch.getDefaultProxySearch();
ps.setPacCacheSettings(32, 1000*60*5);
List l = ps.getProxySelector().select(
new URI("http://www.yahoo.com/"));
//... Now just do what the original did ...
for (Iterator iter = l.iterator(); iter.hasNext(); ) {
Proxy proxy = (Proxy) iter.next();
System.out.println("proxy hostname : " + proxy.type());
InetSocketAddress addr = (InetSocketAddress)
proxy.address();
if(addr == null) {
System.out.println("No Proxy");
} else {
System.out.println("proxy hostname : " +
addr.getHostName());
System.out.println("proxy port : " +
addr.getPort());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
It needs these imports:
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URI;
import java.util.Iterator;
import java.util.List;
import com.btr.proxy.search.ProxySearch;
Oh, and there're usage examples for proxy vole here.
Related
I have the following simple websocket example:
package com.bfaconsultora.rest.europa.resources;
import java.util.HashSet;
import java.util.Set;
import javax.websocket.OnOpen;
import javax.websocket.OnMessage;
import javax.websocket.OnClose;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.DefaultValue;
#ServerEndpoint("/api/europa/qr/websocket")
public class QrWebSocket {
private Set<Session> sessions = new HashSet<>();
#OnOpen
public void onOpen (
Session session
) {
sessions.add(session);
}
#OnMessage
public void handleMessage(String message, Session session) {
try {
for (int c = 0; c < 100; c++) {
for (Session s : sessions) {
s.getBasicRemote().sendText("{\"value\" : \"" + (c + 1) + "\"}");
}
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
#OnClose
public void onClose(Session session) {
sessions.remove(session);
}
}
running on Apache Tomcat 9.
Is it possible to access header params (I need it for authentication purposes)? Could you please point me the right direction?
Thank you in advance.
Regards
It's not possible (or at last not a common practice) to read header params from a web socket. The usual way to authenticate is to send auth information in the first message, but there are other ways.
I found this reading very useful.
Regards to everyone.
I found that javamail only support socks. Is there any solution I can use to support http proxy?
public class MailConnectionTest {
public static void main(String args[]) throws MessagingException {
Properties props = MailConnectionTest.getProperties();
Session session = Session.getDefaultInstance(props, null);
String protocol = "pop3";
String host = "pop.163.com";
String username = "email username";
String password = "1Qaz2wsx3edc&";
Store store = session.getStore(protocol);
store.connect(host, username, password);
System.out.println("Success");
}
private static Properties getProperties() {
Properties props = System.getProperties();
props.put("mail.debug", "false");
// Proxy
props.put("proxySet", "true");
props.put("http.proxyHost", "proxyAdderss");
props.put("http.proxyPort", "8080");
return props;
}
}
As per the latest release of Javamail API 1.6.2 , JavaMail supports accessing mail servers through a web proxy server and also authenticating to the proxy server. Please see my code below.
import java.io.IOException;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.FlagTerm;
public class ReadMailProxy {
public static void receiveMail(String userName, String password) {
try {
String proxyIP = "124.124.124.14";
String proxyPort = "4154";
String proxyUser = "test";
String proxyPassword = "test123";
Properties prop = new Properties();
prop.setProperty("mail.imaps.proxy.host", proxyIP);
prop.setProperty("mail.imaps.proxy.port", proxyPort);
prop.setProperty("mail.imaps.proxy.user", proxyUser);
prop.setProperty("mail.imaps.proxy.password", proxyPassword);
Session eSession = Session.getInstance(prop);
Store eStore = eSession.getStore("imaps");
eStore.connect("imap.mail.yahoo.com", userName, password);
Folder eFolder = eStore.getFolder("Inbox");
eFolder.open(Folder.READ_WRITE);
Message messages[] = eFolder.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
System.out.println(messages.length);
for (int i = messages.length - 3; i < messages.length - 2; i++) {
Message message = messages[i];
System.out.println("Email Number::" + (i + 1));
System.out.println("Subject::" + message.getSubject());
System.out.println("From::" + message.getFrom()[0]);
System.out.println("Date::" + message.getSentDate());
try {
Multipart multipart = (Multipart) message.getContent();
for (int x = 0; x < multipart.getCount(); x++) {
BodyPart bodyPart = multipart.getBodyPart(x);
String disposition = bodyPart.getDisposition();
if (disposition != null && (disposition.equals(BodyPart.ATTACHMENT))) {
System.out.println("Mail have some attachment : ");
DataHandler handler = bodyPart.getDataHandler();
System.out.println("file name : " + handler.getName());
} else {
System.out.println(bodyPart.getContent());
}
}
} catch (Exception e) {
System.out.println("Content: " + message.getContent().toString());
}
message.setFlag(Flag.SEEN, true);
}
eFolder.close(true);
eStore.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
receiveMail("umesh#yahoo.com", "test123");
}
}
javamail api 1.6 supports web server proxy
set these properties
mail.protocol.proxy.host
mail.protocol.proxy.port
for smtp set as
mail.smtp.proxy.host
mail.smtp.proxy.port
See the JavaMail FAQ:
How do I configure JavaMail to work through my proxy server?
... Without such a SOCKS server, if you want to use JavaMail to access mail servers outside the firewall indirectly, you might be able to use a program such as Corkscrew or connect to tunnel TCP connections through an HTTP proxy server. JavaMail does not support direct access through an HTTP proxy web server.
The implementation only support basic authentication for web proxy. You can find the source code in com.sun.mail.util.SocketFetcher.
Since javamail support NTLM authentication already, it is not hard to support NTLM authentication for web proxy.
I'm trying to load map tiles from an internal SSL server. The SSL certificate's root of trust is not recognized by the Android system.
W/o*.o*.t*.m*.MapTileDow*(2837): IOException downloading MapTile: /8/37/4 :
javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
I'm already familiar with the problem and have solved it in the rest of the application based on this excellent SO answer. Essentially, I extended my own SSLSocketFactory and X509TrustManager which load my SSL certificate's root of trust from a .bks file bundled with the app. To create a secure connection, I call ((HttpsURLConnection) connection).setSSLSocketFactory(mySSLSocketFactory) and the certificate is verified using my classes with my root of trust.
My question is how do I do the same thing for osmdroid? I'm creating my own XYTileSource where I set the URL, file extension, size, etc. of my map tiles. I see that osmdroid creates its connections to download map tile images in MapTileDownloader. I can write my own replacement class that will address the SSL issue in the same manner, but how do I tell osmdroid to use my custom downloader instead of the default?
It turns out this is possible without changing the source of osmdroid, due to the public MapView(Context context, int tileSizePixels, ResourceProxy resourceProxy, MapTileProviderBase aTileProvider) constrtuctor.
Assuming you already have a custom class like MySSLSocketFactory (which extends javax.net.ssl.SSLSocketFactory), the basic process looks like this:
Create a drop-in replacement class for MapTileDownloader to perform the download in a way that makes use of MySSLSocketFactory. Let's call this MyTileDownloader.
Create a drop-in replacement class for MapTileProviderBasic that instantiates your custom MyTileDownloader. Let's call this MyTileProvider.
Instantiate your tile source as a new XYTileSource (no need to write a custom class).
Instantiate MyTileProvider with your tile source instance.
Instantiate MapVew with your tile provider instance.
MySSLSocketFactory is left as an exercise for the reader. See this post.
MyTileDownloader looks something like this:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.UnknownHostException;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.MapTileRequestState;
import org.osmdroid.tileprovider.modules.IFilesystemCache;
import org.osmdroid.tileprovider.modules.INetworkAvailablityCheck;
import org.osmdroid.tileprovider.modules.MapTileDownloader;
import org.osmdroid.tileprovider.modules.MapTileModuleProviderBase;
import org.osmdroid.tileprovider.tilesource.BitmapTileSourceBase.LowMemoryException;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase;
import org.osmdroid.tileprovider.util.StreamUtils;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;
/**
* A drop-in replacement for {#link MapTileDownloader}. This loads tiles from an
* HTTP or HTTPS server, making use of a custom {#link SSLSocketFactory} for SSL
* peer verification.
*/
public class MyTileDownloader extends MapTileModuleProviderBase {
private static final String TAG = "MyMapTileDownloader";
protected OnlineTileSourceBase mTileSource;
protected final IFilesystemCache mFilesystemCache;
protected final INetworkAvailablityCheck mNetworkAvailablityCheck;
protected final SSLSocketFactory mSSLSocketFactory;
public MyTileDownloader(ITileSource pTileSource,
IFilesystemCache pFilesystemCache,
INetworkAvailablityCheck pNetworkAvailablityCheck,
SSLSocketFactory pSSLSocketFactory) {
super(4, TILE_DOWNLOAD_MAXIMUM_QUEUE_SIZE);
setTileSource(pTileSource);
mFilesystemCache = pFilesystemCache;
mNetworkAvailablityCheck = pNetworkAvailablityCheck;
mSSLSocketFactory = pSSLSocketFactory;
}
public ITileSource getTileSource() {
return mTileSource;
}
#Override
public void setTileSource(final ITileSource tileSource) {
// We are only interested in OnlineTileSourceBase tile sources
if (tileSource instanceof OnlineTileSourceBase)
mTileSource = (OnlineTileSourceBase) tileSource;
else
mTileSource = null;
}
#Override
public boolean getUsesDataConnection() {
return true;
}
#Override
protected String getName() {
return "Online Tile Download Provider";
}
#Override
protected String getThreadGroupName() {
return "downloader";
}
#Override
public int getMinimumZoomLevel() {
return (mTileSource != null ? mTileSource.getMinimumZoomLevel()
: MINIMUM_ZOOMLEVEL);
}
#Override
public int getMaximumZoomLevel() {
return (mTileSource != null ? mTileSource.getMaximumZoomLevel()
: MAXIMUM_ZOOMLEVEL);
}
#Override
protected Runnable getTileLoader() {
return new TileLoader();
};
private class TileLoader extends MapTileModuleProviderBase.TileLoader {
#Override
public Drawable loadTile(final MapTileRequestState aState)
throws CantContinueException {
if (mTileSource == null)
return null;
InputStream in = null;
OutputStream out = null;
final MapTile tile = aState.getMapTile();
try {
if (mNetworkAvailablityCheck != null
&& !mNetworkAvailablityCheck.getNetworkAvailable()) {
if (DEBUGMODE)
Log.d(TAG, "Skipping " + getName()
+ " due to NetworkAvailabliltyCheck.");
return null;
}
final String tileURLString = mTileSource.getTileURLString(tile);
if (DEBUGMODE)
Log.d(TAG, "Downloading Maptile from url: " + tileURLString);
if (TextUtils.isEmpty(tileURLString))
return null;
// Create an HttpURLConnection to download the tile
URL url = new URL(tileURLString);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setConnectTimeout(30000);
connection.setReadTimeout(30000);
// Use our custom SSLSocketFactory for secure connections
if ("https".equalsIgnoreCase(url.getProtocol()))
((HttpsURLConnection) connection)
.setSSLSocketFactory(mSSLSocketFactory);
// Open the input stream
in = new BufferedInputStream(connection.getInputStream(),
StreamUtils.IO_BUFFER_SIZE);
// Check to see if we got success
if (connection.getResponseCode() != 200) {
Log.w(TAG, "Problem downloading MapTile: " + tile
+ " HTTP response: " + connection.getHeaderField(0));
return null;
}
// Read the tile into an in-memory byte array
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream,
StreamUtils.IO_BUFFER_SIZE);
StreamUtils.copy(in, out);
out.flush();
final byte[] data = dataStream.toByteArray();
final ByteArrayInputStream byteStream = new ByteArrayInputStream(
data);
// Save the data to the filesystem cache
if (mFilesystemCache != null) {
mFilesystemCache.saveFile(mTileSource, tile, byteStream);
byteStream.reset();
}
final Drawable result = mTileSource.getDrawable(byteStream);
return result;
} catch (final UnknownHostException e) {
Log.w(TAG, "UnknownHostException downloading MapTile: " + tile
+ " : " + e);
throw new CantContinueException(e);
} catch (final LowMemoryException e) {
Log.w(TAG, "LowMemoryException downloading MapTile: " + tile
+ " : " + e);
throw new CantContinueException(e);
} catch (final FileNotFoundException e) {
Log.w(TAG, "Tile not found: " + tile + " : " + e);
} catch (final IOException e) {
Log.w(TAG, "IOException downloading MapTile: " + tile + " : "
+ e);
} catch (final Throwable e) {
Log.e(TAG, "Error downloading MapTile: " + tile, e);
} finally {
StreamUtils.closeStream(in);
StreamUtils.closeStream(out);
}
return null;
}
#Override
protected void tileLoaded(final MapTileRequestState pState,
final Drawable pDrawable) {
// Don't return the tile Drawable because we'll wait for the fs
// provider to ask for it. This prevent flickering when a load
// of delayed downloads complete for tiles that we might not
// even be interested in any more.
super.tileLoaded(pState, null);
}
}
}
MyTileProvider looks something like this.
Note that you'll need a way to get access to your instance of MySSLSocketFactory inside this class. This is left as an exercise for the reader. I did this using app.getSSLSocketFactory(), where app is an instance of a custom class that extends Application, but your mileage may vary.
import javax.net.ssl.SSLSocketFactory;
import org.osmdroid.tileprovider.IMapTileProviderCallback;
import org.osmdroid.tileprovider.IRegisterReceiver;
import org.osmdroid.tileprovider.MapTileProviderArray;
import org.osmdroid.tileprovider.MapTileProviderBasic;
import org.osmdroid.tileprovider.modules.INetworkAvailablityCheck;
import org.osmdroid.tileprovider.modules.MapTileFileArchiveProvider;
import org.osmdroid.tileprovider.modules.MapTileFilesystemProvider;
import org.osmdroid.tileprovider.modules.NetworkAvailabliltyCheck;
import org.osmdroid.tileprovider.modules.TileWriter;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.util.SimpleRegisterReceiver;
import android.content.Context;
/**
* A drop-in replacement for {#link MapTileProviderBasic}. This top-level tile
* provider implements a basic tile request chain which includes a
* {#link MapTileFilesystemProvider} (a file-system cache), a
* {#link MapTileFileArchiveProvider} (archive provider), and a
* {#link MyTileDownloader} (downloads map tiles via tile source).
*/
public class MyTileProvider extends MapTileProviderArray implements
IMapTileProviderCallback {
public MyTileProvider(final Context pContext, final ITileSource pTileSource) {
this(new SimpleRegisterReceiver(pContext),
new NetworkAvailabliltyCheck(pContext), pTileSource, app
.getSSLSocketFactory());
}
protected MyTileProvider(final IRegisterReceiver pRegisterReceiver,
final INetworkAvailablityCheck aNetworkAvailablityCheck,
final ITileSource pTileSource,
final SSLSocketFactory pSSLSocketFactory) {
super(pTileSource, pRegisterReceiver);
// Look for raw tiles on the file system
final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(
pRegisterReceiver, pTileSource);
mTileProviderList.add(fileSystemProvider);
// Look for tile archives on the file system
final MapTileFileArchiveProvider archiveProvider = new MapTileFileArchiveProvider(
pRegisterReceiver, pTileSource);
mTileProviderList.add(archiveProvider);
// Look for raw tiles on the Internet
final TileWriter tileWriter = new TileWriter();
final MyTileDownloader downloaderProvider = new MyTileDownloader(
pTileSource, tileWriter, aNetworkAvailablityCheck,
pSSLSocketFactory);
mTileProviderList.add(downloaderProvider);
}
}
Finally, the instantiation looks something like this:
XYTileSource tileSource = new XYTileSource("MapQuest", null, 3, 8, 256, ".jpg",
"https://10.0.0.1/path/to/your/map/tiles/");
MapTileProviderBase tileProvider = new MyTileProvider(context, tileSource);
ResourceProxy resourceProxy = new DefaultResourceProxyImpl(context);
MapView mapView = new MapView(context, 256, resourceProxy, tileProvider);
I don't use osmdroid, but unless it has public interface to replace the downloader class(es), your best bet is to get the source and patch it to make it configurable or use your own downloader class. If MapTileDownloader implements some interface you could probably do some reflection voodoo to replace it at runtime, but that might have unknown side effects.
How do I determine whether a web proxy IP is of type HTTP or SOCKS4/5 with java?
Thank you.
As mentioned in the comments from my other answer, if you know the IP address of a proxy server and want to detect what type it is, you could try each proxy type in Java until one works.
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.List;
public class ProxyTest
{
public static void main(String... args)
throws IOException
{
InetSocketAddress proxyAddress = new InetSocketAddress("myproxyaddress", 1234);
Proxy.Type proxyType = detectProxyType(proxyAddress);
System.out.println(proxyAddress + " is a " + proxyType + " proxy.");
}
public static Proxy.Type detectProxyType(InetSocketAddress proxyAddress)
throws IOException
{
URL url = new URL("http://www.google.com");
List<Proxy.Type> proxyTypesToTry = Arrays.asList(Proxy.Type.SOCKS, Proxy.Type.HTTP);
for (Proxy.Type proxyType : proxyTypesToTry)
{
Proxy proxy = new Proxy(proxyType, proxyAddress);
//Try with SOCKS
URLConnection connection = null;
try
{
connection = url.openConnection(proxy);
//Can modify timeouts if default timeout is taking too long
//connection.setConnectTimeout(1000);
//connection.setReadTimeout(1000);
connection.getContent();
//If we get here we made a successful connection
return(proxyType);
}
catch (SocketException e) //or possibly more generic IOException?
{
//Proxy connection failed
}
}
//No proxies worked if we get here
return(null);
}
}
In this code, it first tries to connect to www.google.com using the proxy at myproxyaddress with SOCKS, and if that fails it will try using it as an HTTP proxy, returning the method that worked, or null if none worked.
If you want to determine the type of proxy being used from Java, you can use ProxySelector and Proxy.
e.g.
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URI;
import java.util.List;
public class ProxyTest
{
public static void main(String... args)
{
System.setProperty("java.net.useSystemProxies", "true");
List<Proxy> proxyList = ProxySelector.getDefault().select(URI.create("http://www.google.com"));
if (!proxyList.isEmpty())
{
Proxy proxy = proxyList.get(0);
switch (proxy.type())
{
case DIRECT:
System.out.println("Direct connection - no proxy.");
break;
case HTTP:
System.out.println("HTTP proxy: " + proxy.address());
break;
case SOCKS:
System.out.println("SOCKS proxy: " + proxy.address());
break;
}
}
}
}
We wish to buy a wild-card SSL certificate as we have a lot of sub-domains. However I don't know if Java trusts wild-card certificates. As people connect into our API via SSL it will not be sufficient for us to force all third parties we communicate with to add our SSL certificate into their local truststore.
At the moment I'm facing a dilemma to buy a wildcard certificate from a java trusted issuer or buy multiple certs one per sub-domain.
Do other languages also have a truststore? If so does anyone know if wildcard certificates work with them also.
The default implementation in Sun's JSSE doesn't support wildcard. You need to write your own X509TrustManager to handle wildcard.
However, Java supports SAN (Subject Alternative Names) since Java 5. If you have less than 20 names, you can get one certificate for all of them. It may be cheaper than a wildcard cert.
I've attempted this with java 6.
It appears to work correctly. I've succesfully read headers and body content from a file that had a wildcard SSL certificate.
package com.example.test;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class SSLTEST {
public static void main(String[] args) {
try {
URL url = new URL("https://test.example.com/robots.txt");
URLConnection connection = null;
try {
connection = url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
Map<String, List<String>> fields = connection.getHeaderFields();
Iterator<Entry<String, List<String>>> headerIterator = fields.entrySet().iterator();
System.out.println("HEADERS");
System.out.println("-------------------------------");
while (headerIterator.hasNext()){
Entry<String, List<String>> header = headerIterator.next();
System.out.println(header.getKey()+" :");
Iterator<String> valueIterator = header.getValue().iterator();
while (valueIterator.hasNext()){
System.out.println("\t"+valueIterator.next());
}
}
String inputLine;
DataInputStream input = new DataInputStream(connection.getInputStream());
System.out.println("BODY CONTENT");
System.out.println("-------------------------------");
while ((inputLine = input.readLine()) != null) {
System.out.println(inputLine);
}
} catch (MalformedURLException e) {
System.err.println(e);
} catch (IOException e) {
e.printStackTrace();
}
}
}
EDIT I've just recieved confirmation that this works on java 1.5