I want to write the Perl equivalent of this Java Database Utility Class such that I can call the appropriate subroutines passing the required connection arguments (Perl driver, Perl URL, username, password and in same cases other arguments) from the Java application. Issues are: 1) I do not understand from other/earlier posts how to call Perl subroutines from Java, and 2) how to provide/pass the required arguments to such Perl subroutines. As always thanks for your time and assistance.
So you want to start a Perl script from Java.
I guess you know how to start any executable with a list of parameters from Java, or at least you should know how to get that information.
Depending on your platform (Win32 / Unix), you may need to call the Perl interpreter with the name of the perl script (Win32), or you can directly call the perl script (Unix). Calling the Perl interpreter with the name of the perl script also works on Unix.
You can pass a lot of arguments to the script, Linux allows something like 4 kBytes, ancient DOS would allow only 126 Bytes, Windows should be somewhere in between, maybe even more that 4 kBytes.
Perl has Getopt::Long to parse that arguments into variables.
So, using all of these parts, you end with Java doing the equivalent of
/usr/bin/perl yourscript.pl --datasource=dbi:Pg:dbname=MyDatabase --db
+user=Me --dbpass=T0pS3cr3t --action=frobnicate --frobnicate-foo=42 --
+frobnicate-bar=lalala
In yourscript.pl, you would call a Getopt::Long function (RTFM) to parse the arguments, create a DBI connection using the datasource, dbuser, dbpass arguments, then look at the action parameter, and call a function for the given argument (using if-then-else, switch-case, or a hash mapping actions to function references).
You can also use the action as first argument to the script, then call a function that calls Getopt to parse the remaining arguments depending on the current action. Your command line would look like this:
/usr/bin/perl yourscript.pl frobnicate --datasource=dbi:Pg:dbname=MyDa
+tabase --dbuser=Me --dbpass=T0pS3cr3t --frobnicate-foo=42 --frobnicat
+e-bar=lalala
In yourscript.pl, you would start with my $action=shift @ARGV;, then decide which funtion to call, depending on $action. In the called function, you would call Getopt.
More options: You can pass data from Java to Perl using STDIN or files written by Java. You can pass data from Perl to Java using STDOUT or files written by Perl.
Both Java and Perl can easily use JSON to transfer structured data, so you may want to use JSON for communication using files, STDIN, STOUT.
Update: Passing passwords on the command line is not the best idea, as any user can use tools like ps to read the command line arguments of any running program. So you may want to pass at least the password via STDIN to perl, and - if required - use a separate file instead of STDIN to pass large amounts of data from Java to Perl.
Update: You could also omit all command line parameters and pass the entire "job" as JSON via STDIN: action, action parameters, database connection information. Action parameters can be an arbitary large data block, structured or not, both is possible with JSON.
Update: To avoid encoding trouble, you may want to make sure that the generated JSON uses only ASCII characters, i.e. all non-ASCII characters are expressed using escape sequences. JSON::XS offers the ascii() method for that. I assume that one of the Java encoders has a similar feature.
I've explained a different approach in Re: Dazed/Confused from previous posts on how to call Java method from Perl.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
|