2011-11-03 64 views
3

我一直在撕掉我的頭髮幾天,現在試圖找出爲什麼這似乎從來沒有工作!首先,這裏是我的配置:試圖從Java Applet將數據寫入串行端口?

的Windows 7 64位系統
JDK 7的x86
JRE 7條86
火狐86
的Rails 3薄擔任
Java設置是這樣的: 「下一代插件」 ISN 't主動(但它不斷重新啓動本身不知何故!!!)

起初我試過RXTX,但我一直在得到「沒有找到類」的錯誤。我現在轉向winjcom。我現在得到的錯誤是這樣的:java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "loadLibrary.winjcom")

我也注意到我的服務器日誌因我使用的瀏覽器而異。如果我使用Firefox,當瀏覽器嘗試加載小程序時,不會顯示任何GET日誌(即,當小程序加載失敗時,沒有進一步下載)。如果我在IE9中嘗試,除了「PortWriter.class」GET日誌之外,所有日誌都在那裏......這意味着它由於某種原因沒有被檢索到。

當我避免使用JNLP時,我得到了安全警告彈出窗口,並且沒有任何錯誤......當然,當我運行「發送」方法時出現安全訪問錯誤。但是,當我使用JNLP時,IE加載它並且仍然給出錯誤...但是當我關閉時崩潰(我必須結束iexplorer進程)。 Firefox只是不加載頁面......它停在進度條上。

更新 - 我有事情要做,如果我通過java的安全策略文件繞過安全,小程序將起作用。但是,JNLP不起作用 - 我認爲這就是爲什麼通常在通過applet標籤運行時發生安全錯誤的原因。當我直接訪問JNLP文件時,出現錯誤,指出找不到「PortWriter」類。我的jar有什麼問題嗎?我注意到其他jar文件夾的佈局使得目錄結構完全匹配它們的包佈局(例如,如果包爲com.myname.serialport.PortWriter,則爲「com \ myname \ serialport \ PortWriter.jar」) 。然而,我的jar版面複製我的物理文件夾佈局(例如,「D:\ Files \ Websites \ pos \ assets \ java \ PortWriter.jar」)。這是什麼導致錯誤?我手動更改了jar內容(包括清單文件)以匹配根目錄,但也許我做了錯誤的事情。我也在這個問題中更新了我的JNLP佈局,以說明JaNeLa驗證的最新變化。

這是我的java文件:

import com.engidea.comm.CommPort; 
import com.engidea.comm.CommPortIdentifier; 
import com.engidea.comm.SerialPort; 
import com.engidea.comm.SerialPortEvent; 
import com.engidea.comm.SerialPortEventListener; 
import com.engidea.win32jcom.WinjcomIdentifier; 
import java.io.*; 
import java.util.Iterator; 
import java.util.List; 
import java.applet.*; 
import java.security.*; 

/* 
    WinJcom is a native interface to serial ports in java. 
    Copyright 2007 by Damiano Bolla, [email protected] 

    This library is free software; you can redistribute it and/or 
    modify it under the terms of the GNU Library General Public 
    License as published by the Free Software Foundation; either 
    version 2 of the License, or (at your option) any later version. 
    This can be used with commercial products and you are not obliged 
    to share your work with anybody. 

    This library is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
    Library General Public License for more details. 

    You should have received a copy of the GNU Library General Public 
    License along with this library; if not, write to the Free 
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
*/ 

/** 
* Simple class that can list system ports and allow IO 
*/ 
public class PortWriter extends Applet 
    { 

    private CommPortIdentifier portIdentifier; 
    private SerialPort serport; 

    public void init() {System.out.println("Booting...");} 
    @SuppressWarnings("unchecked") 
    public void Sends(String port, String message) throws Exception 
    { 

    final String com_port = port; 
    final String send_message = message; 

    AccessController.doPrivileged(new PrivilegedAction() { 
    public Object run() { 

     System.out.println("Begin..."); 
     portIdentifier = new WinjcomIdentifier(0); 
     System.out.println("Selecting Port..."); 
     selectComport(com_port); 
     new Thread(new PortReader()).start(); 
     System.out.println("Sending..."); 
     typeSendBytes(send_message); 

    return true;} 
    }); 
    } 

    private void typeSendBytes(String message) 
    { 
    try 
     { 
     System.out.println("Trying To Send..."); 
     BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
     String aStr = ""; 
     while (aStr != null) 
     { 
     aStr = message + "\r\n"; 
     // WARNING: be careful, you shoulod select the encoding ! 
     // This will timeout if you have FLOW CONTROL and theline is stuck ! 
     byte []buf = aStr.getBytes(); 
     serport.write(buf,0,buf.length); 
     } 
     } 
    catch (Exception exc) 
     { 
     exc.printStackTrace(); 
     } 
    } 

    private SerialPort openPort (String portName) 
    { 
    try 
     { 
     CommPort aPort = portIdentifier.getCommPort(portName); 
     aPort.open(); 
     return (SerialPort)aPort; 
     } 
    catch (Exception exc) 
     { 
     System.out.println("exc="+exc); 
     exc.printStackTrace(); 
     } 

    return null; 
    } 

    private void selectComport (String portName) 
    { 
    try 
     { 
     serport = openPort(portName); 
     serport.setSerialPortParams(9600,8, SerialPort.STOPBITS_2, SerialPort.PARITY_NONE); 
     serport.enableReceiveTimeout(20000); 
     serport.setEventListener(new EventListener()); 

     serport.notifyOnDSR(true); 
     serport.notifyOnCarrierDetect(true); 
     serport.notifyOnCTS(true); 
     } 
    catch (IOException exc) 
     { 
     System.out.println("Exc="+exc); 
     exc.printStackTrace(); 
     } 
    } 


private final class EventListener implements SerialPortEventListener 
    { 
    public void serialEvent(SerialPortEvent ev) 
    { 
    System.out.println("Got event="+ev); 
    } 
    } 


private final class PortReader implements Runnable 
    { 
    public void run() 
    { 
    try 
     { 
     // This will timeout if nothing is received in the specified time. 
     byte []buff = new byte[1]; 
     while ( serport.read(buff,0,buff.length) > 0) 
     { 
     // NOTE: you should be checking the encoding ! 
     System.out.print(new String(buff)); 
     } 
     } 
    catch (Exception exc) 
     { 
     exc.printStackTrace(); 
     } 
    } 
    } 


} 

...和我的JNLP文件:

<?xml version="1.0" encoding="utf-8"?> 
<jnlp codebase="http://localhost/assets/" href="PortWriter.jnlp"> 
    <information> 
     <title>RS232 Communication Applet</title> 
     <vendor>My Company</vendor> 
     <description>RS232 Applet for communicating with POS Display Pole</description> 
     <offline-allowed /> 
    </information> 
    <security> 
    <all-permissions/> 
    </security> 
    <update check="background" /> 
    <resources> 
    <jar href="PortWriter.jar" part="com" main="true" /> 
    <jar href="winjcom.jar" part="com" /> 
    <nativelib href="jcomport.jar" part="com" /> 
    </resources> 
    <applet-desc 
     name="RS232 Communication Applet" 
     main-class="PortWriter" 
     width="1" height="1" /> 
</jnlp> 

...和我的HTML:

<applet id="SerialPort" width="1" height="1" codebase="/assets/" code="PortWriter.class" archive="PortWriter.jar"> 
     <param name="jnlp_href" value="PortWriter.jnlp" /> 
    </applet> 

我如何讓這些東西起作用?我是一個Java新手,但我只想得到一個可行的解決方案。這是我在Rails中製作的公司的POS。

最後的文件是:

在服務器的/資產/ JAVA /:
1)jcomport.jar(未簽名...)
2)PortWriter.class(和所有相關的類文件)
3)PortWriter.jar
4)PortWriter。JNLP

在本地HD在%Java主%/
1)/lib/ext/jcomport.jar(未簽名)
2)/bin/winjcom.dll

+0

JNLP無效。嘗試使用[JaNeLA]驗證它(http://pscode.org/janela/)。 –

+0

我做了,最終得出了我答案中指定的佈局......雖然這不一定是問題。 – JakeTheSnake

回答

2

好神聖的永恆廢話。在最初決定關閉Java控制檯中的「下一代插件」選項時,我打算讓我的小程序在Firefox中工作,但我無意中禁用了JNLP。我只是通過最後的手段努力「嘗試......任何事情」才發現了這一點。重啓後,jnlp可以在IE中完美運行。 Firefox當然是我需要用於我的POS的瀏覽器(因爲有一個jsprint插件)......但當然它不起作用。它不會下載JNLP文件,或者如果是的話,出現問題。它只是掛起。什麼都沒有顯示,但我的服務器日誌說所有的圖像和HTML正在下載。不是jnlp或任何jar文件。因此,要麼關閉下一代插件,並存在安全問題或打開它,無法使用Firefox。有什麼我可以做,而不必訴諸於改變政策文件?

FWIW,我會將此標記爲解決方案,並在其他地方啓動一個關於我最新問題的新線程。這裏的一切讓這該死的東西的工作(除了在Firefox)最需要更新的內容:


首先,確保PATH和CLASSPATH環境變量在Windows中設置。 PATH應該是C:\Program Files (x86)\Java\jdk1.7.0_01\bin(如果您有不同的版本,請更改爲您自己的jdk目錄)。 CLASSPATH應該是你創建Java類的地方。我的是D:\Files\Java\Classes。如果不設置PATH變量,則不能從任何目錄運行'java','javac'或'jarsigner'。你必須在jdk的bin目錄下。爲您的用戶帳戶設置這些變量...不是系統(因爲可能已經有像這樣命名的env變量)。


接下來,簽署您的小程序,創建密鑰庫:

keytool -genkey -dname "cn=My Company, ou=Whatever, o=My Company, c=CA" -alias mycompany -keystore "D:\Files\Java\Certificates\certfile" -storepass MY_PASSWORD -validity 180 

檢查在線教程,以確保你知道上述論點是。


.bat文件我做了很容易從java文件創建必要的.jar文件和簽名。只是做一個快捷方式或運行.bat文件,而不必手動每次你做出改變的java文件

@echo off 

set certificate_password=MY_PASSWORD 
set certificate_alias=myalias 
set package=mycompany 
set class_file=PortWriter 
rem class_path is where my .java file resides (...\java\Classes\mycompany\PortWriter.java) 
set class_path=D:\Files\Java\Classes 
set certificate_loc=D:\Files\Java\Certificates\certfile 
rem final_loc is the assets folder where the .jar file will reside 
set final_loc=D:\Files\Websites\pos\app\assets\java 

cd "%class_path%" 
rem Change to "D:" otherwise Windows won't *actually* change directories from C: to D: 
D: 

javac -Xlint:unchecked "%package%\%class_file%.java" 
pause 
jar cfm "%final_loc%\%class_file%.jar" "%package%\Mainfest.txt" "%package%\*.class" 
pause 
del "%package%\*.class" 
jarsigner -keystore "%certificate_loc%" -storepass %certificate_password% "%final_loc%\%class_file%.jar" %certificate_alias% 
pause 

Mainfest.txt時間這樣做的(確保有一個回車如果你想在你的JNLP中指定主類,那麼你不應該需要這個Manifest.txt文件。): Main-Class:mycompany。PortWriter


Java文件:

package mycompany; 

import com.engidea.comm.CommPort; 
import com.engidea.comm.CommPortIdentifier; 
import com.engidea.comm.SerialPort; 
import com.engidea.comm.SerialPortEvent; 
import com.engidea.comm.SerialPortEventListener; 
import com.engidea.win32jcom.WinjcomIdentifier; 
import java.io.*; 
import java.util.Iterator; 
import java.util.List; 
import java.applet.*; 
import java.security.*; 

/* 
    WinJcom is a native interface to serial ports in java. 
    Copyright 2007 by Damiano Bolla, [email protected] 

    This library is free software; you can redistribute it and/or 
    modify it under the terms of the GNU Library General Public 
    License as published by the Free Software Foundation; either 
    version 2 of the License, or (at your option) any later version. 
    This can be used with commercial products and you are not obliged 
    to share your work with anybody. 

    This library is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
    Library General Public License for more details. 

    You should have received a copy of the GNU Library General Public 
    License along with this library; if not, write to the Free 
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
*/ 

/** 
* Simple class that can list system ports and allow IO 
*/ 
public class PortWriter extends Applet { 

    private CommPortIdentifier portIdentifier; 
    private SerialPort serport; 

    public static void main(String[] args) {} 
    public void init() { 
    System.out.println("Booting RS232 Java Applet..."); 
    } 

    public void Sends(String port, String message) { 

    final String com_port = port; 
    final String send_message = message; 

    AccessController.doPrivileged(new PrivilegedAction<Object>() { 
     public Object run() { 

     try { 
      portIdentifier = new WinjcomIdentifier(0); 
      try { 
      selectComport(com_port); 
      new Thread(new PortReader()).start(); 
      try { 
       System.out.println(com_port + ": " + send_message); 
       typeSendBytes(send_message); 
      } catch (Exception e) { 
       System.out.println("Couldn't send data to " + com_port); 
      } 
      } catch (IOException e) { 
      System.out.println("Couldn't connect to " + com_port); 
      } 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
     return null; 
     } 
    }); 
    } 

    private void typeSendBytes(String message) { 
    try { 
     BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
     String aStr = ""; 
     if (aStr != null) { 
     aStr = message + "\r\n"; 
     // WARNING: be careful, you shoulod select the encoding ! 
     // This will timeout if you have FLOW CONTROL and theline is stuck ! 
     byte []buf = aStr.getBytes(); 
     serport.write(buf,0,buf.length); 
     } 
    } catch (Exception exc) { 
     exc.printStackTrace(); 
    } 
    } 

    private SerialPort openPort (String portName) throws IOException { 
    try { 
     CommPort aPort = portIdentifier.getCommPort(portName); 
     aPort.open(); 
     return (SerialPort)aPort; 
    } 
    catch (Exception exc) { 
     //System.out.println("exc="+exc); 
     //exc.printStackTrace(); 
     throw exc; 
    } 
    } 

    private void selectComport (String portName) throws IOException { 

    try { 
     serport = openPort(portName); 
     serport.setSerialPortParams(9600,8, SerialPort.STOPBITS_2, SerialPort.PARITY_NONE); 
     serport.enableReceiveTimeout(20000); 
     serport.setEventListener(new EventListener()); 

     serport.notifyOnDSR(true); 
     serport.notifyOnCarrierDetect(true); 
     serport.notifyOnCTS(true); 
    } catch (IOException exc) { 
     //System.out.println("Exc="+exc); 
     //exc.printStackTrace(); 
     throw exc; 
    } 

    } 


private final class EventListener implements SerialPortEventListener 
    { 
    public void serialEvent(SerialPortEvent ev) 
    { 
    System.out.println("Got event="+ev); 
    } 
    } 


private final class PortReader implements Runnable 
    { 
    public void run() 
    { 
    try 
     { 
     // This will timeout if nothing is received in the specified time. 
     byte []buff = new byte[1]; 
     while ( serport.read(buff,0,buff.length) > 0) 
     { 
     // NOTE: you should be checking the encoding ! 
     System.out.print(new String(buff)); 
     } 
     } 
    catch (Exception exc) 
     { 
     exc.printStackTrace(); 
     } 
    } 
    } 


} 

JNLP文件:

<?xml version="1.0" encoding="utf-8"?> 
<jnlp> 
    <information> 
     <title>RS232 Communication Applet</title> 
     <vendor>My Company</vendor> 
     <description>RS232 Applet for communicating with POS Display Pole</description> 
     <offline-allowed /> 
    </information> 
    <security> 
    <all-permissions/> 
    </security> 
    <resources> 
    <j2se version="1.7.0+" /> 
    <jar href="PortWriter.jar" part="com" main="true" /> 
    <jar href="jcomport.jar" part="com" /> 
    <nativelib href="winjcom.jar" part="com" /> 
    </resources> 
    <applet-desc 
     name="RS232 Communication Applet" 
     main-class="mycompany.PortWriter" 
     width="1" height="1" /> 
</jnlp> 

HTML:

<applet id="SerialPort" width="1" height="1" codebase="/assets/"> 
    <param name="jnlp_href" value="PortWriter.jnlp"> 
</applet> 

我已經採取了winjcom.dll文件和「震撼」它,並用相同的certfile簽名。我一定要cd到winjcom所在的同一個目錄,以便它將位於.jar文件的根目錄下。我還使用了winjcom作者提供的jcomport.jar文件,並使用相同的certfile對其進行了重新簽名。也就是說,所有的.jar文件都由相同的certfile簽名。

我希望這能幫助那些和我一樣麻煩的人。

0

爲了使用Java的包(推薦)的地方PortWriter.java內部的java/X/Y/Z 和具有第一行:

x.y.z.PortWriter 

package x.y.z; 

如類名到處使用

在服務器上,我只希望有一個PortWriter類的jar。 你可以在不使用DLL的情況下添加一些Test.java來查看它是否有效。

+0

這沒有任何幫助:(它仍然沒有找到類,我從資產文件夾除了新的jar文件除去所有文件...我改變了我的JNLP只引用該jar,並刪除了'檔案'屬性從我的小程序標記。它只是告訴我它找不到!它仍然是在jar中的文件夾目錄模仿我的本地文件系統順便說一句。我已經嘗試在'javac'中設置類路徑選項,但是當我去到'jar'(沒有類路徑選項),它以上述方式創建子目錄。 – JakeTheSnake

+0

附錄:添加Windows環境變量「PATH」(到java目錄)和「CLASSPATH」(到我的類的主目錄,包目錄)創建我正在尋找的jar結構仍然沒有去尋找類,但:\ – JakeTheSnake

+0

另外,我已經注意到,它不會找到類,因爲它試圖直接下載類文件...它不是通過j看的ar文件來查找它們(我查看了我的服務器日誌)。 – JakeTheSnake