I'm trying to get a program to print labels to a print attached (USB) to the server. I've been able to print to it from a batch file but for some reason the print command fails inside of coldfusion execute command. My current solution is to access the printer through Java. My problem with this solution is that I can't call any of them java methods.
The solution is based off of this answer How to print strings with line breaks in java
The following section of code appears to work fine.
var printService = createObject("java","javax.print.PrintService");
var printServiceLookup = createObject("java","javax.print.PrintServiceLookup");
var docFlavor = createObject("java","javax.print.DocFlavor");
writeDump( printService.init() );
writeOutput('<hr>');
writeDump( printServiceLookup );
writeOutput('<hr>');
writeDump( docFlavor );
The problem comes when I try to do a execute any of the methods that exist in the objects that were just created.
When I try to execute
writeDump( DocFlavor.STRING.TEXT_PLAIN );
I get:
Application Execution Exception
Error Type: java.lang.NoSuchMethodException : 0
Error Messages: No matching Constructor for javax.print.DocFlavor() found
Remember I'm trying to send a set of ZPL print commands to a printer attached to the computer. If been able to successfully do this through sockets but also need to be able to do it through a locally connected printer. So alternate solutions are acceptable provided they work with Railo & Windows.
Updated: 4/3/2013
var printer = javacast("null","");
var printers = printServiceLookup.lookupPrintServices( javacast("null",""), javacast("null","") );
for( var i=1; i le ArrayLen( printers ); i++ ) {
if( printers[i].getName() eq printername ) {
printer = printers[i];
break;
}
}
if( i gt ArrayLen( printer ) ) {
throw('Printer #printername# was not found');
}
var Job = printer.createPrintJob();
var LabelCmdbytes = javaCast( "byte[]", javaCast( "String", LabelCmd ).getBytes() );
var Labeldoc = Doc.init( LabelCmdbytes, printer.getSupportedDocFlavors()[1].AUTOSENSE, javacast("null","" ) );
Job.print( Labeldoc, javacast("null","")
This solution works but I don't think that printer.getSupportedDocFlavors()[1].AUTOSENSE is the best solution to the DocFlavor value.
The environment is Windows 7 with Railo 4.1.x
Actually DocFlavor.STRING is a nested class. So you need to use $ to grab a reference to it:
StringFlavor = createObject("java","javax.print.DocFlavor$STRING");
Then you can access the public field:
writeDump( StringFlavor.TEXT_PLAIN );
Side note, printService.init() should not work. PrintService is an interface and cannot be instantiated. So calling init() should throw an error.
Related
I have a setup where I execute jython scripts from a Java application. The java application feed the jython script with variables, coming from the command line, so that a user can write the following code in it's jython script:
print("Hello, %s" % foobar)
And will call the java program with this:
$ java -jar myengine.jar script.py --foobar=baz
Hello, baz
My java application parse the command-line, and create a variable of that name with the given value to give to the jython scripting environment to consume. All is well so far.
My issue is that when the user does not provide the foobar command-line parameter, I'd like to be able to easily provide a fallback in my script. For now, the user needs to write that sort of code to handle the situation where the foobar parameter is missing from the command-line:
try: foobar
except NameError: foobar = "some default value"
But this is cumbersome, especially if the number of parameters is growing. Is there a way to handle that better from the script user point of view?
I was thinking of catching the jython NameError in the Java code, initializing the variable causing the exception to a default value if the variable causing the exception "looks like" a parameter (adding a naming convention is OK), and restarting where the exception occurred. Alternatively, I can require the script user to write code such as this:
parameter(foobar, "some default value")
Or something equivalent.
Well, this is one ugly workaround I found so far. Be careful, as this will call the script in loop many times, and is O(n^2).
private void callScriptLoop(String scriptfile) {
PythonInterpreter pi = new PythonInterpreter();
pi.set("env", someEnv);
int nloop = 0;
boolean shouldRestart;
do {
shouldRestart = false;
try {
pi.execfile(scriptfile);
} catch (Throwable e) {
if (e instanceof PyException) {
PyException pe = (PyException) e;
String typ = pe.type.toString();
String val = pe.value.toString();
Matcher m = Pattern.compile("^name '(.*)' is not defined")
.matcher(val);
if (typ.equals("<type 'exceptions.NameError'>")
&& m.find()) {
String varname = m.group(1);
pi.set(varname, Py.None);
System.out.println(
"Initializing missing parameter '"
+ varname + "' to default value (None).");
shouldRestart = true;
nloop++;
if (nloop > 100)
throw new RuntimeException(
"NameError handler infinite loop detected: bailing-out.");
}
}
if (!shouldRestart)
throw e;
}
} while (shouldRestart);
}
This question already has an answer here:
Attempt to index local 'v' (a nil value)
(1 answer)
Closed 5 years ago.
There has been a lot of post about this kind of error and most people say it is related to table and array indexing problems. But I am not using tables at all, I am just trying to call a library function I made and I get this error. Here is the lua script called from java:
String script = new String (
"function event_touch ( )"
+ " pb.open_form ('view_monster');"
+ " print ('I ran the lua script');"
+ "end");
PBLUAengine.run_script(script, "event_touch");
This gives me the following error when trapping the exception:
"function event_touch ( ) pb.open_form ('view_monster'); print ('I ran the lua script');end:1 attempt to index ? (a nil value)"
The run_script() function calls the script like this( I am using luaj):
public static LuaValue run_script ( String script )
{
try
{
LuaValue chunk = s_globals.load( script );
return chunk.call();
}
catch ( Exception e)
{
Gdx.app.error ("PBLUAengine.run_script()", e.getMessage() );
}
return null;
}
The library method goes like this and the same piece of code works when called from java:
static class open_form extends OneArgFunction
{
public LuaValue call (LuaValue formname)
{
String tmpstr = (String ) CoerceLuaToJava.coerce(formname, java.lang.String.class );
try
{
PBscreen_game.hide_subscreen(PBscreen_game.MENU_SUBS);
PBscreen_game.show_subscreen ( PBscreen_game.FORM_SUBS);
PBsubscreen_form.open_form ( new PBform_regular ( tmpstr ) );
}
catch (Exception e)
{
Gdx.app.error("PBLUAlibrary.open_form", e.getMessage());
}
return valueOf ( 0 );
}
}
It basically convert the lua parameter to string, create a new from and pass in parameter the string.
The declaration of the library functions goes like this:
public LuaValue call( LuaValue modname, LuaValue env )
{
LuaValue library = tableOf();
library.set( "open_form", new open_form() );
library.set( "open_system_form", new open_system_form() );
env.set( "pb", library );
return library;
}
Which could be the only "table" I can see in the whole system. This is generally used link the right class with the right function name.
Anybody have an idea?
most people say it is related to table and array indexing problems
It's related to table and array indexing. If you try to index an object and that object is nil, you'll get that error:
I am not using tables at all [..] Here is the lua script:
pb.open_form
pb is being indexed. It's probably nil.
I seems that I solved the problem by adding a require line to include the library. So the new script is:
String script = new String (
"require 'com.lariennalibrary.pixelboard.library.PBLUAlibrary'"
+ "function event_touch ( )"
+ " pb.open_form ('view_monster');"
+ " print ('I ran the next button lua script');"
+ "end");
It ask to include my library class which will add all the "pb.*" functions. I probably deleted the line by error, or managed to make it work somehow without it. Since this library will be required by all script, I might append it by default before each script I try to run.
Thanks Again
I am new to selenium.
My application is only IE compatible.
I know that we can run test cases in any any browsers using respective drivers but is there any way that we can use to record test case using selenium IDE in Internet Explorer ??
We have implemented our own Recorder which will be used only for recording in Internet Explorer. It is a javascript file.
The concept is to add listeners to each object in the source code of the GUI of web page.
Below code helps you to do that. As soon as the page is loaded these listeners will be added. When you perform click action, all its properties will be captured.
Here i have given an example of adding listener and getting properties of the object of type "SELECT", you can do the same thing for other types of objects.
var added_MClistener = false;
var tagn = dObj.tagName;
if(tagn == "SELECT")
{
dObj.attachEvent("onchange",so_showObjInfo);
dObj.added_OClistener = true;
dObj.so_prevBGColor = alll[i].style.backgroundColor;
}
if(tagn != "OPTION" && tagn != "SELECT" )
{
dObj.added_MClistener = true;
dObj.attachEvent("onclick",so_showObjInfo);
dObj.so_prevBGColor = alll[i].style.backgroundColor;
}
function so_showObjInfo(e) {
if(pause)return;
if(isActive)return;
var preE = e;
var e =e? e:window.event;
var ele=e.target?e.target:e.srcElement;
activeObj = ele;
var eltagn= activeObj.tagName;
var currentNode=activeObj;
var path=[];
while(currentNode){var pe=getNode(currentNode);if(pe){path.push(pe);if(pe.indexOf('#id')!=-1)break;}currentNode=currentNode.parentNode;}var xpath="//"+path.reverse().join('/');
var fff=0;
var xpath;
while(currentNode){var pe=getNode(currentNode);if(pe){path.push(pe);if(pe.indexOf('#id')!=-1){fff=1; break;}if(pe.indexOf('#name')!=-1){fff=1; break;}}currentNode=currentNode.parentNode;}if(fff==1){xpath="//"+path.reverse().join('/');}
var acurrentNode=activeObj;
var apath=[];
while(acurrentNode){var ape=agetNode(acurrentNode);if(ape){apath.push(ape);}acurrentNode=acurrentNode.parentNode;} var axpath="//"+apath.reverse().join('/');
var el=activeObj;
var cssPath = cssselect(el);
if (cssPath!=null)
{
cssPath="css="+cssPath;
}
var objval=activeObj.value;
var objname=activeObj.name;
var objidd=activeObj.id;
}
In this way we can add listeners to the objects on the webpage and get their properties. Now its up to you what to do next. You can either write it in an excel like we did(in a particular format) or you can create a notepad file.
Hope it helps....
Selenium IDE is only available on Firefox. There is noway to record your test on IE using Selenium IDE.
Recorder is for Firefox. Record with Firefox replay on ie. Tweak script as needed
I have a mongo db instance and I want to get all the clients connected to it. In the mongo shell I write
db.currentOp(true)
And I get all the clients and their properties.
How can I pull that data in java?
I tried something like this but it didn't work:
mongoclient.getDB("local").command("currentOp")
It says that there is not such a command.
It seems currentOp is a command on the shell, but it is not a first-class mongodb command supported in all drivers. You will need to query the $cmd.sys.inprog collection with findOne(). With java driver you can do the following (which is exactly what currentOp calls under the hood):
DB db = mongoclient.getDB("local");
DBObject currentOp = db.getCollection("$cmd.sys.inprog").findOne();
If you look what is going on under the hood when calling currentOp you get the idea:
> db.currentOp
function ( arg ){
var q = {}
if ( arg ) {
if ( typeof( arg ) == "object" )
Object.extend( q , arg );
else if ( arg )
q["$all"] = true;
}
return this.$cmd.sys.inprog.findOne( q );
}
>
Is there a way to specifiy the JOB name when creating a spooled file?
So that my created s.f. doesn't have the default "QPRTJOB".
My method that creates a spooled file with the default QPRTJOB job:
public static SpooledFile createSpoolFile( com.ibm.as400.access.AS400 as, PrinterFile pPrinterFile,
OutputQueue outq, String msg ) {
SpooledFile result = null;
try {
PrintParameterList parms = new PrintParameterList();
// create a PrintParameterList with the values that we want
// to override from the default printer file...we will override
// the output queue and the copies value.
parms.setParameter( PrintObject.ATTR_PRINTER_FILE, pPrinterFile.getPath() );
parms.setParameter( PrintObject.ATTR_JOBUSER, AS400.getUser().getUserProfileName() );
parms.setParameter( PrintObject.ATTR_JOBNAME, "NASAOBRJVA" );
parms.setParameter( PrintObject.ATTR_OUTPUT_QUEUE, outq.getPath() );
parms.setParameter( PrintObject.ATTR_CHAR_ID, "*SYSVAL" );
SpooledFileOutputStream spool = new SpooledFileOutputStream( as, parms, pPrinterFile,
outq );
SCS5256Writer scsWtr = new SCS5256Writer( spool, pPrinterFile.getSystem().getCcsid(), pPrinterFile.getSystem() );
String[] redovi = msg.split( "\n" );
for ( int i = 0; i < redovi.length; i++ ) {
if (redovi[i].equals( "" ) || redovi[i].equals( " " )) {
continue;
}
scsWtr.write( redovi[i].trim() );
if (i < redovi.length - 1) {
scsWtr.newLine();
}
}
scsWtr.close();
result = spool.getSpooledFile();
System.out.println("Spool is in Job: " + result.getJobNumber() + "/" + result.getJobUser() + "/" + result.getJobName());
}
catch ( Exception e ) {
LOG.error( e );
}
return result;
}
ATTR_JOBUSER and ATTR_JOBNAME are read-only attributes for a spooled file. I've noticed that whenever my Java programs talk to the AS/400--even those that are running natively on the AS/400--they talk to host server jobs and not necessarily the job that submitted the Java call. In this case, you are talking to a print server job on the 400 and all of your spooled files will get a QPRTJOB job name.
An elaborate work-around would be to have your Java program submit a new job named NASAOBRJVA with a command to call some simple RPG program with the message text as a parameter. That's probably a lot of effort for a job name on a spooled file, but you know your project enough to know if it's worth that effort.
Job, user and job number are assigned by the system and cannot be changed. To the best of my knowledge anyway.