Executing an external rails project command from Java application - java

I'm working on a big system that interconnects different platforms in different languages. Two of these platforms are a RoR website and a Java application whose task is to insert data (no matter where from) to the RoR PostgreSQL database. Currently, I was using simple SQL queries to insert, for example, a product. This is working right, however, I can't take advantage of framework's included tools like timestamps and model callbacks.
The question is, is there a way to, instead of executing those SQL queries, execute rails console commands, considering my Java application runs completely apart the RoR application? If you need to know, I'm using rails 4.
Please excuse my english and thank you in advance.

I don't think that is a good idea at all. But you can achieve this if the java application connects to the same machine RoR is running. You can then use rails runner or you can execute some rake task. The use of rails runner is really simple, check out this example from the official documentation from http://guides.rubyonrails.org/command_line.html#rails-runner
$ bin/rails runner -e staging "Model.long_running_method"

I did as #IvanT suggested, however despite the diverse approaches I can't make it work, here's one of the codes I tried:
String railsCmd = "Product.where(:category_id => 9).each { |p| p.update_attribute(:brand, 'NO BRAND') }";
String wholeCommand = "rails runner -e development \"" + railsCmd + "\"";
StringBuilder output = new StringBuilder();
Process p = Runtime.getRuntime().exec(wholeCommand, null, new File("/path/to/rails/project/bin"));
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = reader.readLine())!= null) {
output.append(line).append("\n");
}
System.out.println(output.toString());
It takes a couple seconds to process, as it's doing something, but there is no change in products themselves. I tried the command directly in the terminal and works good.
I would also like to know why you think it's not a good idea.
Thank you for your time.

Related

Start a lightweight web-server using Swift to receive OAuth1.0 callback in iOS App

I'm a newbie in Swift (and iPhone dev). I'm working on a project where I need to build an iOS (using swift) mobile client to demonstrate OAuth1.0 (3-legged flow).
I'm not finding any concrete solution to start a server using swift. I need to pass a call-back endpoint to the request_token url so that my program can receive the oauth_verifierId.
I found the following close solutions (libs) from net, but either lack of examples/docs or due to my less exp on swift, things are not in place yet.
https://github.com/swisspol/GCDWebServer - No/less concrete example (not sure how to import this in swift project)
https://github.com/robbiehanson/CocoaHTTPServer - Looks good but not
getting any e2e solution. I want to avoid Obj-C lib in my Swift project.
https://github.com/glock45/swifter
Actually, I don't need a wrapper like above. It would be best if I could write a Java equivalent like following.
ServerSocket s = new ServerSocket(7000);
Socket remote = s.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(
remote.getInputStream()));
PrintWriter out = new PrintWriter(remote.getOutputStream());
String str = null;
while (!str.equals("")){
str = in.readLine();
if(str.startsWith("GET")){
String[] splitStr = str.split("&");
for(String s1 : splitStr){
if(s1.startsWith("oauth_verifier")){
String verifierId = s1.split("=")[1];
System.out.println("VerifierId - " + verifierId);
}
}
break;
}
}
I think my answer would a little bit late, just put a sign here for later comers.
If you are about to use GCDWebServer:
pod "GCDWebServer", "~> 3.0" in your Podfile, then pod install, pod update.
Put a file named APP_NAME-Bridging-Header.h in SOME_PATH, put these lines below the #define statement:
#import "GCDWebServer.h"
#import "GCDWebServerDataResponse.h"
Go Project Name -> Build Settings -> Search for bridging -> update Objective-C Bridging Header to $(SRCROOT)/SOME_PATH/APP_NAME-Bridging-Header.h.
Now the Objective-C library is globally imported, you could use it everywhere.
Use this line of code to instantiate a GCDWebServer instance:
let webServer = GCDWebServer()
Now play it with yourself :)

Matlab: how can I replace the slow system() function?

I have a Matlab script that makes many system calls through the system() function.
However, I noticed that the function is very slow (has a lot of overhead). For example, the call
tic;system('echo');toc;
takes on average 0.08 seconds. With lots of system calls overhead becomes unacceptable.
I tried to replace the calls with calls to Java (which I do not know, I am just copying and pasting from somewhere else), as follows
runtime=java.lang.Runtime.getRuntime();
process=runtime.exec('commandStringThatNeedsToBeExecuted');
status=process.waitFor();
When it works, it works nicely and the overhead is significantly reduced. However, I have two problems.
First problem: for some commands execution fails (but it does not fail with calls to system()), depending on the program I call. In particular (but this is probably irrelevant), when I make calls to pdflatex, everything works fine, while when I make calls to ImageMagick's convert, execution fails. So, in order to understand these differences in behavior, my first question is: what are the main differences between a Matlab system() call and a system call through Java?
Second problem: how do I get the output of the command (I mean what would be displayed on screen if, for example, the command was executed in a DOS command window) that I can get from the second output argument of the system() function?
To get the output, try this:
p = java.lang.ProcessBuilder({'cmd', 'arg1', 'arg2'}).start();
reader = java.io.BufferedReader(java.io.InputStreamReader(p.getInputStream()));
str = char(java.util.Scanner(reader).useDelimiter('\A').next());
You can replace the last line with this:
...
sb = java.lang.StringBuilder();
while true;
line = reader.readLine();
if isnumeric(line); % Test for NULL
break;
else
sb.append(sprintf('%s\n',char(line)));
end;
end
str = char(sb.toString());
The first is faster if there is a lot of output (matlab's system() is very slow in this case), while the second is clearer and more flexible.
As for why it sometimes fails, I'm not sure. Are you constructing the command string in the same way? Do identical command strings sometimes work and sometimes not work? Are you fiddling with the environment?
The differences are as far as i know, system can actively execute cmd commands (Windows) whereas for runtime.exec() commands you have to insert cmd /c beforehand.
To read the output of the process, do the following:
p.waitFor();
try (BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
final StringBuilder string = new StringBuilder();
String line;
try {
while (input.ready() && (line = input.readLine()) != null) {
string.append(line + "\n");
}
} catch (IOException e) {}
return string.toString();
} catch (Exception ex) {
ex.printStackTrace();
}
This will connect to the outputstream of the process and read it line by line into the stringbuilder.
I'm working on a project where I need to run a lot of shell commands and invoke external tools from matlab. This slowness issue caused me a lot of pain.
I've found the above ProcessBuilder-based approach very helpful (thanks!) but still needed to tweak various things.
Here's my implementation, hope it's useful for future visitors coming here...
https://github.com/avivrosenberg/matlab-jsystem

how to find the names of currently opened applications (on taskbar) in windows, using java?

I'm making an application which is like windows task manager. For that, I need the list of all opened applications (not processes), which are shown in taskbar.
Here are some sources to look into:
http://www.daniweb.com/web-development/jsp/threads/93197
http://java.ittoolbox.com/groups/technical-functional/java-l/java-code-required-to-access-task-manager-569041
http://www.sqaforums.com/showflat.php?Cat=0&Number=658713&an=0&page=6
Looks like you'll be using the Runtime class.
None of your links CFL_Jeff says anything of how to get active application windows (which I assume is what you want?
Don't think this can be accomplished with java or a simple windows commandline.
Here might be a way to do it in C#:
Get the list of opened windows C#
Or you might have to take a look here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ff468919%28v=vs.85%29.aspx
An emergency solution might be to use the "tasklist /v" command and get all processes that have a "windowtitle" that differ from "I/T"(might be locale dependent), but that will give you tray icons aswell I'm afraid.
Edit:
To get the tasklist, you can use the following:
try
{
Process p = Runtime.getRuntime().exec("cmd /c tasklist /v");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
String input;
while ((input = stdInput.readLine()) != null)
{
output += input;
}
stdInput.close();
}
catch(Exception k){JOptionPane.showMessageDialog(null, k.getMessage());}

Java Application conversion into Java applet and passing Parameters from HTML

I'm new to Java and tried to create an application which runs a system command when executed.
I accomplished just that with the following code:
package printtest;
import java.io.*;
import java.util.*;
public class PrintTest {
public static void main(String args[])
throws InterruptedException,IOException
{
List<String> command = new ArrayList<String>();
command.add(System.getenv("programfiles") +"\\Internet Explorer\\"+"iexplore.exe");
command.add("http://www.google.com");
ProcessBuilder builder = new ProcessBuilder(command);
Map<String, String> environ = builder.environment();
builder.directory(new File(System.getenv("programfiles")+"\\Internet Explorer\\"));
System.out.println("Directory : " + System.getenv("programfiles")+"Internet Explorer\\");
final Process process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("Program terminated!");
}
}
If I run the application, it runs a system command in the following syntax "iexplore.exe http://www.google.com". This is great.
The problem I'm having, and I would like to ask for help in it, is this:
I would like to pass variables to this application from a HTML page so the arguments after the executable can be passed in the java application by changing PARAMS in HTML. For this I understood that this app needs to be an applet.
I don't know how to modify this to compile for inclusion in HTML.
Can you help me with this issue?! I've been searching for 2 days now for an answer.
UPDATE:
I'm sorry, I think I'm not explaining as I should. Here's what needs to be done: 1. An order management interface written in PHP needs a way to run a system command with extra parameters to print transport recepts. To do this somehow a webpage should trigger the printing via an applet or any other solution. If you have a an idea about solving this please do tell me. Thanks
I would like to pass variables to this application from a HTML page so the arguments after the executable can be passed in the java application by changing PARAMS in HTML. For this I understood that this app needs to be an applet.
No. As long as you have something on the server side that will generate documents dynamically (e.g. for parameters in HTML or a JNLP launch file), you can use that functionality to create an unique (includes parameters for that use) launch file for a Java Web Start launch.
Of course, whether it is an applet or JWS app., it will require a GUI.
BTW - in case you do not realize:
The code being used will open IE on Windows.
I use Windows but my default browser is FireFox.
It will fail completely on Mac, Linux, Unix..
Java has 3 built-in ways to open a web page.
An Applet has access to the 'AppletContext' class, which offers AppletContext.showDocument(URL).
Java Web Start apps. have access to the JNLP API, which offers BasicService.showDocument(URL).
Java 6+ apps. can use Desktop.browse(URI).
Either of the last two is superior to the Applet method, since they either return a boolean to indicate success, or throw a range of helpful exceptions. For use in an applet or an app. launched using JWS, either of the Desktop class or using a Process would require digitally signed and trusted code.

Sending a password to a Java Process

I am trying to access SVN through the process command in Java as part of a larger GUI to see what files are on the SVN. After much research, I have significantly refined my methods, however I still cannot accomplish it. If I run the code in the GUI, it just hangs. To discover what that problem was, I simplified it and ran it as a console program. When I ran it there, it displayed a request for my GNOME keyring. My code enters the password but the console does not seem to accept it. My code follows:
public class SvnJavaTest{
public static void main(String[] args){
try {
String[] commands = {"svn", "ls", "https://svnserver"};
Process beginProcess = Runtime.getRuntime().exec(commands, null, new File("/home/users/ckorb/Desktop"));
BufferedReader br = new BufferedReader(new InputStreamReader(beginProcess.getInputStream()));
BufferedWriter write = new BufferedWriter(new OutputStreamWriter(beginProcess.getOutputStream()));
write.write("password");
write.flush();
String line=br.readLine();
while (line != null){
System.out.println(line);
line =br.readLine();
}
br.close();
write.close();
beginProcess.waitFor();
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
I don't get any errors running this and if I type in my password manually into the console and then run it, it works because it remembers my password. I have looked and found that there are some packages that would automatically enter my keyring on login but that isn't really an option. Thank you very much.
The main problem with a solution like this is that you don't really have control over stdin and stdout. A malicious person can wrap the svn command with a shell script that makes a copy of the stdin (thereby capturing all the passwords your program transmits). While shell's flexibility makes it great in so many ways, it is the same flexibility that you are connecting to, and you'd better be comfortable with it (and it's consequences).
That is the real reason why it is better to use a Java API to use the client, there's a much smaller chance of injecting code which captures sensitive data (and better error reporting).
Use the SVN Kit library instead.
Better to use svn java API (there are several, I am not sure which one is better), it's more straightforward solution.
Answering you question - you could provide auth info in the url: https://username:password#svnserver

Categories

Resources