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
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!!!)
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")
.
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.
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 - 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.
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();
}
}
}
}
...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>
...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>
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.
Final files are:
On server at /assets/java/:
1) jcomport.jar (not signed...)
2) PortWriter.class (and all associated class files)
3) PortWriter.jar
4) PortWriter.jnlp
On local hd at %java home%/
1) /lib/ext/jcomport.jar (not signed)
2) /bin/winjcom.dll