只是想将数据从 Java Applet 写入串行端口? [英] Just trying to write data to a serial port from a Java Applet?

查看:25
本文介绍了只是想将数据从 Java Applet 写入串行端口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经把头发扯了好几天了,现在想弄清楚为什么这似乎永远不起作用!首先,这是我的配置:

I've been tearing my hair out for several days now trying to figure out just why the heck this never seems to work! First off, here is my config:

Windows 7 x64
JDK 7 x86
JRE 7 x86
火狐 x86
由 Thin
提供的 Rails 3Java 设置使得下一代插件"不处于活动状态(但它以某种方式不断重新激活自己!!!)

Windows 7 x64
JDK 7 x86
JRE 7 x86
Firefox x86
Rails 3 served by Thin
Java settings are such that the "next generation plugin" isn't active (but it keeps reactivating itself somehow!!!)

起初我尝试了 RXTX,但我一直收到找不到课程"的错误消息.我现在已经转向 winjcom.我现在得到的错误是:java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "loadLibrary.winjcom").

At first I tried RXTX but I kept on getting "no class found" errors. I've now moved on to winjcom. The error I'm now getting is this: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "loadLibrary.winjcom").

我还注意到我的服务器日志因我使用的浏览器而异.如果我使用 Firefox,当浏览器尝试加载小程序时,不会显示 GET 日志(即,当小程序加载失败时,不会再下载任何内容).如果我在 IE9 中尝试,除了PortWriter.class"GET 日志之外,所有日志都在那里......这意味着它由于某种原因没有被检索.

I've also noticed that my server logs vary depending on what browser I'm using. If I used Firefox, no GET logs are displayed when the browser attempts to load the applet (i.e., nothing further is downloaded when the applet load fails). If I try in IE9, all the logs are there except for the "PortWriter.class" GET log...which means it isn't being retrieved for some reason.

当我避免使用 JNLP 时,我会收到安全警告弹出窗口,并且没有任何错误……当然,运行发送"方法时出现的安全访问错误除外.然而,当我确实使用 JNLP 时,IE 加载它很好,但仍然给出错误......但是当我关闭它时崩溃(我必须结束 iexplorer 进程).Firefox 只是不加载页面...它停在进度条上.

When I avoid using JNLP I get the security warning popup and there aren't any errors...except of course for the security access error when I run the "Sends" method. However when I DO use the JNLP, IE loads it fine and still gives the error...but crashes when I close it (I have to end the iexplorer process). Firefox just doesn't load the page...it stalls at the progress bar.

UPDATE - 如果我通过 java 的安全策略文件绕过安全性,小程序将可以工作.但是,JNLP 不起作用 - 我认为这就是为什么在通过小程序标记运行时通常会发生安全错误的原因.当我直接访问 JNLP 文件时,我收到一条错误消息,指出它找不到PortWriter"类.我的罐子有问题吗?我注意到其他 jars 的文件夹布局使得目录结构完全匹配他们的包布局(例如,com\myname\serialport\PortWriter.jar",如果包是 com.myname.serialport.PortWriter).然而,我的 jar 布局复制了我的物理文件夹布局(例如,D:\Files\Websites\pos\assets\java\PortWriter.jar").这是导致错误的原因吗?我已经手动更改了 jar 内容(包括清单文件)以匹配 root,但也许我做错了什么.我还在这个问题中更新了我的 JNLP 布局,以说明我的最新更改,这些更改已由 JaNeLa 验证.

UPDATE - I have things to the point where if I bypass security through java's security policy file the applet will work. However, the JNLP won't work - which I think is why normally the security error occurs when running through the applet tag. When I access the JNLP file directly, I get an error stating it can't find the "PortWriter" class. Is there something wrong with my jar? I've noticed that other jars have their folder layouts such that the directory structure exactly matches their package layout (ex., "com\myname\serialport\PortWriter.jar" if the package were to be com.myname.serialport.PortWriter). However MY jar layout replicates my physical folder layout (ex., "D:\Files\Websites\pos\assets\java\PortWriter.jar"). Is this what's causing the error? I've manually changed the jar contents (including the manifest files) to match to root but maybe I've done something wrong. I've also updated my JNLP layout in this problem to illustrate my latest changes which were verified by JaNeLa.

这是我的 .java 文件:

This is my .java file:

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 文件:

...and my JNLP file:

<?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:

...and my 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.

How do I get this stuff to work? I'm a Java newb but I just want to get a working solution. This is for my company's POS which I'm making in Rails.

最终文件是:

在服务器上/assets/java/:
1) jcomport.jar (未签名...)
2) PortWriter.class(以及所有相关的类文件)
3) PortWriter.jar
4) PortWriter.jnlp

On server at /assets/java/:
1) jcomport.jar (not signed...)
2) PortWriter.class (and all associated class files)
3) PortWriter.jar
4) PortWriter.jnlp

在 %java home%/
1)/lib/ext/jcomport.jar (未签名)
2)/bin/winjcom.dll

On local hd at %java home%/
1) /lib/ext/jcomport.jar (not signed)
2) /bin/winjcom.dll

推荐答案

神圣的永恒废话.在最初决定关闭 Java 控制台中的下一代插件"选项以使我的小程序在 Firefox 中工作时,我无意中禁用了 JNLP.我只是通过最后的努力尝试一些东西......任何东西"才发现了这一点.重新打开后,jnlp 在 IE 中完美运行.Firefox 当然是我需要用于我的 POS 的浏览器(因为 jsprint 插件)......但它当然不起作用.它不会下载 JNLP 文件,或者如果是,则出现问题.它只是挂起.什么都没有显示,但我的服务器日志显示正在下载所有图像和 html.虽然不是 jnlp 或任何 jar 文件.所以要么关掉下一代插件出现安全问题,要么打开后无法使用火狐浏览器.我可以做些什么而不必求助于更改策略文件?

Well holy everlasting crap. Upon originally deciding to turn off the "next generation plug-in" option in the Java console with the intent of making my applet work in Firefox, I've inadvertently disabled JNLP. I only found this out by a last resort effort to "try something...ANYTHING". After turning it back on, the jnlp runs perfectly in IE. Firefox is of course the browser I need to use for my POS (because of a jsprint addon)...but of course it's not working. It won't download the JNLP file or if it is, something's going wrong. It just hangs. Nothing shows up, but my server logs say all the images and html is being downloaded. Not the jnlp or any of the jar files though. So it's either turn off the next generation plug-in and have security issues or turn it on and not be able to use Firefox. Is there ANYTHING I can do without having to resort to changing the policy file?

FWIW,我会将其标记为解决方案,并在其他地方开始一个关于我最新问题的新线程.这是使该死的东西正常工作所需的所有内容的最新内容(Firefox 除外):

FWIW, I'll mark this as the solution and start a new thread somewhere else about my latest problem. Here's the most updated contents for everything needed to get the damned thing working (except in 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 目录中.为您的用户帐户创建这些变量...而不是系统(因为可能已经有这样命名的环境变量).

First off, make sure the PATH and CLASSPATH environment variables are set in Windows. PATH should be C:\Program Files (x86)\Java\jdk1.7.0_01\bin (change to your own jdk directory if you have a different version). CLASSPATH should be wherever you make your java classes. Mine is D:\Files\Java\Classes. If you don't set the PATH variable, you can't run 'java', 'javac' or 'jarsigner' from any directory. You'd have to be in the bin directory of jdk. Make these variables for your User account...not System (as there could already be env variables named like these).

接下来,为了签署您的小程序,请创建您的密钥库:

Next, for signing your applets, create your keystore:

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

查看在线教程以确保您知道每个参数的用途.

Check online tutorials to make sure you know what each of these arguments are for.

.BAT 文件我制作的目的是从 .java 文件轻松创建必要的 .jar 文件并对其进行签名.只需创建一个快捷方式或运行 .bat 文件,而不必每次更改 .java 文件时都手动执行此操作

.BAT file I made to easily create necessary .jar file from .java file and sign it. Just make a shortcut or run the .bat file instead of having to do this by hand every time you make a change to the .java file

@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 中指定 main-class,你应该不需要这个 Manifest.txt 文件.):主类:mycompany.PortWriter


Mainfest.txt (make sure there is a carriage return after the "Main-Class" line. You shouldn't need this Manifest.txt file if you want to specify the main-class in your JNLP.): 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 文件:


JNLP File:

<?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:


HTML:

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

<小时>

我已经获取了 winjcom.dll 文件并震动"了它并使用相同的证书文件对其进行了签名.我确保 cd 到 winjcom 所在的同一目录,以便它位于 .jar 文件的根目录中.我也拿了winjcom作者提供的jcomport.jar文件,用同一个certfile重新签名.也就是说,所有 .jar 文件都由同一个证书文件签名.


I had taken the winjcom.dll file and "jarred" it and signed it with the same certfile. I made sure to cd to the same directory in which winjcom was so that it would be in the root of the .jar file. I also took the jcomport.jar file provided by the author of winjcom and re-signed it with the same certfile. That being said, all .jar files have been signed by the same certfile.

我希望这能帮助那些和我一样遇到麻烦的人.

I hope this helps out anyone who's having as much trouble as I did.

这篇关于只是想将数据从 Java Applet 写入串行端口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆