2011-04-17 87 views
2

我已經實現了一個具有功能的Java軟件包,用於操作通過USB連接到工作站的POS打印機和錢箱。我還實施了一個小程序來利用這個軟件包的功能,希望它能夠被POS網站調用。在瀏覽器沙箱中運行時,簽名的Java小程序是否可以訪問USB外設?

當小程序從Eclipse中運行時,一切都很順利。當小程序從瀏覽器中運行時,看起來我的程序包無法訪問通過USB連接的外圍設備。我從第三方(JavaPOS應用)的代碼說明了一個錯誤:

jpos.JposException:設備 通信信道不能 打開,檢查設備,然後重試。

小應用程序使用self-cert進行簽名。我會張貼一些代碼,但是錯誤是從埋在製造商特定的驅動程序中的POS打印機的使用中拋出的。

我假設問題是,從瀏覽器沙箱內,小程序無法訪問通過USB連接的外圍設備。
這可能是這種情況嗎?如果是這樣,有沒有辦法從簽名的Applet中訪問USB外設?
如果一個applet無法訪問USB外設,網站如何調用可以執行的代碼?

+0

Bozho似乎這樣認爲:http://stackoverflow.com/questions/2093707/java-applet-with-usb-access-in-windows-and-linux/2093863#2093863(我不認爲這是這個問題的重複 - 其他人可能 - 但我認爲這對你很有幫助)。 – 2011-04-17 15:24:21

+0

這個問題中的用戶聽起來像是自己寫驅動程序。我正在調用一個現有的驅動程序,所以我不相信包括USB API的.jar會對我有幫助。不過謝謝。 – tQuarella 2011-04-19 00:25:14

回答

2

在瀏覽器沙箱中運行時,簽名的java applets是否可以訪問USB外設?

爲了解決這個特定的問題(並避免以下評論中涉及的特定技術),是簽名Java小程序可以訪問USB外設。當你運行一個簽名的applet時,「沙箱」就是你能夠「突破」的能力。

但出於安全原因,只需對小程序進行簽名就不會自動授予對沙箱外項目的訪問權限。

PrivelegedAction似乎是訪問特權系統組件(如打印機)的首選方法。 Oracle在這裏提供了更多關於這些特權操作的信息:http://docs.oracle.com/javase/7/docs/api/java/security/AccessController.html

另外,當從Java瀏覽器執行類似操作時需要考慮一些因爲Java關心動作起源於何處。

public function writeFile() { 
    ... 
    FileWriter fw = new FileWriter(...); 
    ... 
} 


public void init() { 
    writeFile(); 
} 

例如,如果你使用在小程序init()方法的FileWriter類寫一個文件到文件系統(即$HOME/Desktop/text.txt),已簽名的Applet將通常允許它。將它包裝成PrivilegedAction會更好,並且首先使用AccessController.checkPermission(...)檢查許可將是理想的。

然而,當它從JavaScript(而不是由init())直接調用FileWriter被阻止:

var myapplet = document.getElementById('myapplet'); 
myapplet.writeFile(); // Blocked by Security Framework 

爲了規避這個問題,一些選擇使用PrivelegedAction,但是如果操作需要很長的時間,你會注意到它阻止了UI,這在網頁中是非常糟糕的做法(並且會導致瀏覽器死鎖)。

public void init() { 
    ... 
    AccessController.doPrivileged(new PrivilegedAction() { 
     public Object run() { 
     writeFile(); 
     return null; 
     } 
    }); 
    ... 
} 

此外,您的問題特別要求訪問USB外設,通常通過迭代人機接口設備來完成。 HID不是Java直接支持的東西(但是,在編寫這個/ JRE7時)。所以是的,一個已簽名的小程序CAN可以與您的USB外設通信,但您需要使用某種形式的Java本地接口(JNI)來正確「訪問」它們。 JNI可能是一個混亂,以支持跨平臺(即分發DLL和SO與您的JAR),所以...

大多數Java Applets做的是訪問本地安裝的打印機和使用標準的Java打印庫。這就是我們在qz-print項目中的做法,您可以在這裏查看我們的源代碼:https://github.com/qzindustries/qz-print/tree/master/qz-print/src/qz它使用由init()和布爾型標誌觸發的線程來激發所有特權函數。

2

我不確定你的問題的答案,但有一個實驗應該進一步闡明這個問題。

Applet.init()的開頭行請撥System.setSecurityManager(null)。然後嘗試連接到USB。

  • 如果Applet是可信的,調用setSecurityManager(null)會成功,並刪除SecurityManager的最後殘餘。 (是的,即使信任的applet也有一個安全管理器,它對沙盒應用程序的安全管理器的限制更少)。
  • 如果USB現在被發現,它表示可信安全管理器發生了變化。最近有一些這樣的變化。

請注意,我不建議這樣的代碼投入生產。如果您的小程序與其他小程序在相同的JRE中運行,則取消SM也可以提升其他小程序的權限。

+0

感謝您的建議。不過,在嘗試訪問外設之前調用setSecurityManager(null)時,我得到了相同的結果。 – tQuarella 2011-04-18 21:34:40

0

我收到Star Micronics團隊的反饋,他們的'... javapos驅動程序不支持Web瀏覽器打印。'

順便說一句,System.setSecurityManager(null)原來是一種很好的方式,可以消除我看到的任何與安全性有關的問題。謝謝安德魯。

1

我在使用JRE 1.6的XP和Win7 32bit上遇到了Epson TM-H6000III的類似問題。管理員可以使用該設備,但「用戶」不能。 Java控制檯報告:

Sep 23, 2011 3:38:47 PM com.xxxx.printer.epson.EpsonPrinter findPrinter 
INFO: Error opening PrinterIII: jpos.JposException: 
    Could not connect to service with logicalName = 
    PrinterIII: Exception.message=Property or stream open error. 

看來JRE安裝有權限問題。重新安裝JRE很快就清除了問題。

相關問題