2011-02-01 33 views
9

Tôi ngạc nhiên và kinh dị, tôi vừa gặp phải dòng System.exit(1); trong thư viện mà tôi sử dụng. Tôi đang lên kế hoạch liên lạc với các tác giả của thư viện và hỏi điều gì mang lại, nhưng trong khi đó có cách nào để ngăn thư viện giết mã của tôi (và tệ hơn, giết chết đơn đăng ký sử dụng mã số của tôi)?Bắt một hướng dẫn thoát bằng thư viện

Có lẽ bằng cách nào đó buộc thư viện phải ném một số SecurityException, mà tôi thấy rằng exit(int) có thể bị ném?

Trả lời

13

Chỉ có một cách tôi biết và đó là mã số SecurityManager không cho phép sử dụng System.exit.

public class MySecurityMgr extends SecurityManager { 
    ... 

    @Override 
    public void checkExit(int status) { 
      throw new RuntimeException(Integer.toString(status)); 
    } 
} 
4

Có, bạn có thể cài đặt một SecurityManager đó sẽ ghi đè checkExit.

Tôi thấy điều này đặc biệt hữu ích cho việc bỏ mã để đảm bảo rằng mã thử nghiệm không thoát với 0, cho thấy thành công giả mạo trước khi các thử nghiệm có cơ hội chạy đến khi hoàn thành.

Điều này sẽ không giúp ích nếu số SecurityException kết thúc bằng cách giết chết một số chuỗi chủ yếu cần thiết trong thời gian dài.

4

Tôi nghĩ rằng lựa chọn duy nhất của bạn (viết tắt của tác giả bằng khăn ướt cho đến khi anh ấy viết lại thứ chết tiệt) sẽ thay đổi mã byte của thư viện.

Cách tiếp cận khá là sử dụng AspectJ với thời gian tải dệt khi bạn tải thư viện, tùy chọn xấu xí là sử dụng công cụ như asm để xóa hoặc thay đổi cuộc gọi phương thức.

Dưới đây là một khía cạnh AspectJ mà làm lệch các cuộc gọi đến System.exit():

public aspect SystemExitEvader{ 

    pointcut systemExitCall() : call(* java.lang.System.exit(*)); 

    void around() : systemExitCall(){ 
     System.out.println("Call to System.exit() attempted"); 
     // note: there is no call to proceed() 
    } 

} 

OK, tôi đã nhìn thấy những câu trả lời khác về SecurityManagers và tôi đồng ý rằng có thể là con đường để đi, nhưng tôi sẽ để lại câu trả lời của tôi ở đây như một sự thay thế.

3

có trình quản lý bảo mật có thể thực hiện thủ thuật

// install security manager to avoid System.exit() call from lib 
SecurityManager  previousSecurityManager = System.getSecurityManager(); 
final SecurityManager securityManager   = new SecurityManager() { 
    @Override public void checkPermission(final Permission permission) { 
     if (permission.getName() != null && permission.getName().startsWith("exitVM")) { 
     throw new SecurityException(); 
     } 
    } 
    }; 
System.setSecurityManager(securityManager); 

try { 
    // Call here your lib code 
} catch (SecurityException e) { 
    // Say hi to your favorite creator of closed source software that includes System.exit() in his code. 
} finally { 
    System.setSecurityManager(previousSecurityManager); 
} 
Các vấn đề liên quan