3

I have a TrirdParty API that contains a CLass [let's say A]. It has a bizarre static block similar to the following:

class A
{
    static
    {
        try
        {
            System.loadLibrary("libraryName");
        }
        catch(UnsatisfiedLinkError ue)
        {
            System.exit(0);
        }
    }

    //other stuff
}

I want to prevent the call to System.exit() with a overridden SecurityManager. However I want to override the SecurityManager just before this static block is executed and right after that I want to restore the original security manager.

I know how to replace/override/restore SecurityManager.

My problem is how do I determine when the static block will be called [basically when the class will be loaded] so that just before that I will use my own SecurityManager to prevent the System.exit() and after that restore the original SecurityManager.

Please note that it is important to override the security manager only for the time duration when the static block is executed.

EDIT:

Changing the source is not an option for licensing reasons.

Swaranga Sarma
  • 13,055
  • 19
  • 60
  • 93

2 Answers2

1

why can't you just replace the static{} block with the one you need by using some bytecode crunching library, like Javassist?

Anton Arhipov
  • 6,479
  • 1
  • 35
  • 43
  • I cannot edit the source of the library for licensing reasons. :( – Swaranga Sarma Apr 05 '11 at 22:17
  • Bytecode access doesn't work at the source level. However, if this code loads before yours (re: discussion above), then it won't help. – jdigital Apr 05 '11 at 22:27
  • it is always possible to intercept the class loading process with -javaagent or bootstrap classloader.. Then you're not editing the source code but transforming the code on the fly :) sure thing, if the license doesn't allow you to patch the binary classes in runtime then it is another story... – Anton Arhipov Apr 05 '11 at 22:56
0

I think that you are basically stuffed.

Yes, it is (in theory at least) possible to block the call System.exit() via a security manager. But what happens then?

  1. Static initializer in class attempts to call System.exit().
  2. SecurityManager says no you can't and throws SecurityException
  3. Static initialization of the class fails with uncaught exception
  4. Initialization of the class you were originally trying to initialize (implicitly) fails.

You can in theory catch the exception. But that doesn't get you very far, because the JVM will only attempt to perform static initialization once. If that fails, and you try again, the JVM will simply throw ClassNotFoundError (I think), repeating the original exception as the cause.

The only way to get the class initialization to happen again is to throw away the classloader that loaded the offending classes in the first place, create a new one, and start loading again. And then you are back to the original problem.

Bottom line: if you really can't change the code, you are stuffed.


Even if you could make this work, it sounds like a poor solution / non-solution to your problem. The LinkageError exception means that the library has failed to load a native library, and that the corresponding native method calls into the library will fail with an Error. At best you'll end up with a library where some bits work and others don't.

You should focus on obtaining the right native library for your platform and/or configuring the JVM so that it can find it. Or finding a better alternative to the 3rd-party library that isn't encumbered with intrusive license enforcement crap.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • @Stephen...my application is a lot more than just that library...while it would be nice to have the features of that library in my application, I can still ship my application without it. My Solution- "include the library and write code to be prepared for the worst". I wanted to prevent the System.exit() via my SecurityManager and continue running my application. Only the library specific features will be blocked [via some boolean value that will be set when I catch a SecurityException from my SecurityManager]. So, I am back to the same problem that "How do I detect the time of ClassLoading"? – Swaranga Sarma Apr 06 '11 at 05:32