views:

168

answers:

3

Hi,

I'm wondering if there's a way for a Java class to figure out if it is being used within an applet?

That is, I have a library (a .jar file) that can be used by 3rd-party applications and applets. It does work within applets, but I'd like to do some things differently, depending on whether or not the library is used in an applet - like show applet-applicable errors, avoid local file I/O, etc.

It would be nice if, say, Applet.getAppletContext() was static so that I could call it (and get NULL or not NULL) even if I don't have an applet instance, but alas, it isn't. Is there any other way?

+1  A: 

According to the Java Security Overview Whitepaper (Page 14 paragraph 2)

Java applets and Java™ Web Start applications are automatically run with a SecurityManager installed. However, local applications executed via the java command are by default not run with a SecurityManager installed.

That should mean that a call to System.getSecurityManager() will return non-null in an applet and will return null when not in an applet. Exceptions are possible, for example a security manager can be specified from the command line when running the program.

boolean insideApplet()
{
  return null != System.getSecurityManager();
}
torak
There are various reasons to set security managers in non-applets... so that isn't going to work very well unfortunately.
TofuBeer
Still, that's a start. Perhaps I could get SeurityManager and if it is null, then it's definitely not an applet, if it isn't null, I'll do, say, checkAccept("example.com", 80) or something like that, with example.com being actual example.com, so that applet can't come from there and will be prohibited to communicate with that server.
7macaw
Still not a reliable way to do it. For example when I mark student assignments I lock down their applications pretty tightly so they don't mess with the marking machine. There are many reasons to install your own security manager (another example I have is for making sure that applications cannot call System.exit).
TofuBeer
+1  A: 

Probably the safest way is to have the user tell you if it is in an applet (just add a "boolean" variable to the appropriate constructor(s) and/or method(s).

Of course you want something more automatic to avoid that, but, as far as I know, there is no sure fire way of knowing how a program is being run that works across VMs. I would probably start by looking at the security manager like torak suggested in his/her answer, but rather than just look for null I'd check what type it is. I looked around a bit but did not find out if there is any sort of "standard" name for the security manager class that applets use.

In the end, the safest way will be to get the user of your library to decide, as they will have the information that is needed.

TofuBeer
It may be necessary at some point to enforce some restrictions for applets, so I'd need to have something automatic... Oh actually, I can probably demand to pass me the Applet instance (or null) and validate that (like see if there's a valid context returned by Applet.getAppletContext()). Thank you for the idea!
7macaw
+1  A: 

An alternative to detecting whether it's running as an applet or not is to use fallback methods if a security exception occurs. This will be advantageous when used in another environment eg a servlet container with a security context.

Example:

try {
    File file = new File("c:\\test.txt");
    System.out.println("Exists? " + file.exists());
} catch (java.security.AccessControlException e) {
    // fallback
}
Pool
You want to catch `SecurityException` really. Can also call the security manager directly to check if a given context has a particular permission.
Tom Hawtin - tackline