3

私は数日間髪を引き裂いてきましたが、なぜこれがうまくいかないように見えるのかを理解しようとしています! まず、私の設定は次のとおりです。

Windows 7 x64
JDK 7 x86
JRE 7 x86
Firefox x86
Rails 3 は、シン
Java 設定によって提供され、「次世代プラグイン」がアクティブにならないようになっています (ただし、何らかの形で再アクティブ化し続けます!!!)

最初に RXTX を試しましたが、「クラスが見つかりません」というエラーが発生し続けました。winjcomに移行しました。私が今得ているエラーはこれです: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "loadLibrary.winjcom").

また、使用しているブラウザによってサーバー ログが異なることにも気付きました。Firefox を使用していた場合、ブラウザがアプレットをロードしようとしても GET ログは表示されません (つまり、アプレットのロードに失敗すると、それ以上何もダウンロードされません)。IE9 で試してみると、「PortWriter.class」の GET ログを除くすべてのログが存在します。これは、何らかの理由で取得されていないことを意味します。

JNLP の使用を避けると、セキュリティ警告ポップアップが表示されますが、エラーはありません...もちろん、「送信」メソッドを実行したときのセキュリティ アクセス エラーを除きます。ただし、JNLPを使用すると、IEは正常にロードされ、エラーが発生します...ただし、IEを閉じるとクラッシュします(ieexplorerプロセスを終了する必要があります)。Firefox はページをロードしないだけです...進行状況バーで停止します。

アップデート- Java のセキュリティ ポリシー ファイルを介してセキュリティをバイパスすると、アプレットが機能するようになるところがあります。ただし、JNLP は機能しません。アプレット タグを実行すると、セキュリティ エラーが通常発生するのはそのためだと思います。JNLP ファイルに直接アクセスすると、「PortWriter」クラスが見つからないというエラーが表示されます。私の瓶に何か問題がありますか?他の jar のフォルダー レイアウトは、ディレクトリ構造がパッケージ レイアウトと正確に一致するようになっていることに気付きました (例: パッケージが com.myname.serialport.PortWriter の場合、"com\myname\serialport\PortWriter.jar")。 . ただし、MY 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, Jcomm@engidea.com

  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 用です。

最終的なファイルは次のとおりです。

/assets/java/ のサーバー:
1) jcomport.jar (署名されていません...)
2) PortWriter.class (および関連するすべてのクラス ファイル)
3) PortWriter.jar
4) PortWriter.jnlp

%java home%/ のローカル hd
上 1) /lib/ext/jcomport.jar (署名なし)
2) /bin/winjcom.dll

4

2 に答える 2

2

まあ聖なる永遠のがらくた。アプレットを Firefox で動作させる目的で Java コンソールの「次世代プラグイン」オプションを無効にすることを最初に決めたとき、うっかり JNLP を無効にしてしまいました。これは、「何かを試してみてください...何でも」という最後の手段でしかわかりませんでした。オンに戻すと、jnlp は IE で完全に動作します。もちろん、Firefox は私の POS に使用する必要があるブラウザです (jsprint アドオンのため)...しかし、もちろん動作しません。JNLP ファイルをダウンロードしないか、ダウンロードしている場合は何か問題があります。ハングするだけです。何も表示されませんが、私のサーバー ログには、すべての画像と html がダウンロードされていることが示されています。ただし、jnlp や jar ファイルではありません。つまり、次世代プラグインをオフにしてセキュリティ上の問題があるか、オンにして Firefox を使用できないかのどちらかです。

FWIW、これを解決策としてマークし、最新の問題について別の場所で新しいスレッドを開始します。これは、いまいましいものを機能させるために必要なすべての最新のコンテンツです (Firefox を除く):


まず、Windows で PATH および CLASSPATH 環境変数が設定されていることを確認します。PATH は次のようになりますC:\Program Files (x86)\Java\jdk1.7.0_01\bin(バージョンが異なる場合は、独自の jdk ディレクトリに変更します)。CLASSPATH は、Java クラスを作成する場所にある必要があります。私のはD:\Files\Java\Classes。PATH 変数を設定しないと、どのディレクトリからでも「java」、「javac」、または「jarsigner」を実行できません。jdk の bin ディレクトリにいる必要があります。システムではなく、ユーザー アカウント用にこれらの変数を作成します (これらのような名前の環境変数が既に存在する可能性があるため)。


次に、アプレットに署名するために、キーストアを作成します。

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

オンライン チュートリアルをチェックして、これらの各引数の目的を確認してください。


.java ファイルから必要な .jar ファイルを簡単に作成して署名するために作成した .BAT ファイル。.java ファイルに変更を加えるたびに手動で行うのではなく、ショートカットを作成するか、.bat ファイルを実行するだけです。

@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 (「Main-Class」行の後にキャリッジ リターンがあることを確認してください。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, Jcomm@engidea.com

  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 ファイルを取得して「jar」し、同じ証明書ファイルで署名しました。winjcom が .jar ファイルのルートになるように、同じディレクトリに cd したことを確認しました。また、winjcom の作成者から提供された jcomport.jar ファイルを取得し、同じ証明書ファイルで再署名しました。そうは言っても、すべての .jar ファイルは同じ証明書ファイルによって署名されています。

これが、私と同じように困っている人の助けになることを願っています。

于 2011-11-06T03:26:06.163 に答える
0

Java のパッケージ (推奨) を使用するには、PortWriter.java を java/x/y/z 内に配置し、最初の行を含めます。

package x.y.z;

どこでもクラス名として使用:

x.y.z.PortWriter

サーバーでは、PortWriter クラスの jar のみが必要です。DLL を使用せずに Test.java を追加して、それが機能することを確認できます。

于 2011-11-04T16:55:42.893 に答える