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

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

问题描述

我一直在撕裂我的头发了好几天,现在试图弄清楚了为什么赫克这似乎从来没有工作!首先,这里是我的配置:

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的64位结果
JDK 7的x86结果
JRE 7 x86的结果
火狐86结果
轨道3薄结果送达
Java设置是这样的,下一代插件是不活跃的(但它保持某种方式重新激活本身!!!)

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:访问被拒绝(java.lang.RuntimePermissionloadLibrary.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日志时,浏览器尝试加载applet的显示(即,没有进一步的是,当小程序加载失败下载)。如果我尝试在IE9中,所有的日志在那里除了PortWriter.class获得日志...这意味着它没有被检索的某些原因。

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过程)。火狐只是不加载网页...它摊位在进度条。

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.

更新的 - 我有事情到了这种地步,如果我通过Java的安全策略文件绕过安全小程序将正常工作。不过,JNLP将无法正常工作 - 我认为这就是为什么通过applet标记运行时,通常会出现安全错误。当我直接访问JNLP文件,我得到一个错误,说明它无法找到PortWriter级。是不是有什么毛病我罐子?我注意到其他坛子里有自己的文件夹布局,这样的目录结构完全匹配的封装布局(例如,COM \\ MYNAME \\的SerialPort \\ PortWriter.jar如果包要成为com.myname.serialport.PortWriter) 。但是我的瓶子布局复制我的物理文件夹布局(如D:\\文件\\网站\\ POS \\资产\\ java的\\ PortWriter.jar)。这是什么造成的错误?我手动更改了瓶子的内容(包括清单文件)来匹配根,但也许我做错了什么。我也更新了我的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福利局,但我只是想获得一个有效的解决方案。这是我公司的POS机,我用Rails正在做。

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.

最后的文件是:

在AT /资产/ 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主%/结果本地高清
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

推荐答案

好神圣永恒的废话。当最初决定关闭下一代插件选项,在使我的小应用程序工作在Firefox的意图Java控制台,我已经无意中禁用JNLP。我只有在万不得已的努力,尝试的东西...任何发现了这一点。重新打开它后,在JNLP在IE完美运行。 Firefox是当然的,我需要用我的POS(因为一个jsprint插件)浏览器...但当然它不工作。它不会下载JNLP文件,或者如果它是什么地方出了错。它只是挂起。没有显示出来,但我的服务器日志说,所有的图像和HTML正在下载。不是JNLP或任何JAR文件虽然。因此,它可以关闭下一代插件,并有安全问题或打开它,并不能使用Firefox。有什么,而不必诉诸改变了策略文件,我可以做什么?

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

首先,确保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变量)。

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(确保有主级行后回车,如果你想在指定的JNLP主类,您应该不需要这个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文件和震动,它与同certFile中签了名。我确信到CD到同一个目录中,winjcom是如此,这将是在.jar文件的根目录。与同certFile中我也参加了由winjcom和作者提供的jcomport.jar文件重新签了字。话虽这么说,所有的.jar文件都被同certFile中签署。


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小程序将数据写入到串行端口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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