Passing console parameters to fastaFromBed under Ubuntu
I'm running into a problem that I simply cannot wrap my head around. As part of my job, I need to run the fastaFromBed application of the "betdools" package, and that only works under Linux. We have an Ubuntu server here that I can run the programme on, but I need to call it from within a larger Java application, and I'm finding myself completely unable to do so, because fastaFromBed apparently fails to recognise input no matter what I do. I've simplified everything down to the very basics and I'm still running into a wall. Here's what I'm trying to do:
Code java:
private void fastaFromBed()
{
try
{
ProcessBuilder builder = new ProcessBuilder("fastaFromBed -fi " +
this.fastaFile.getAbsolutePath() + " -bed " +
this.outputFile.getAbsolutePath() + " -fo test.fa");
builder.redirectErrorStream(true);
Process fastaFromBed = builder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(fastaFromBed.getInputStream()));
String line = reader.readLine();
while(line != null)
{
System.out.println(line);
line = reader.readLine();
}
fastaFromBed.destroy();
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
All of the this.variables have values to them, I made sure in the larger class file, and they have the RIGHT values. For some reason, however, fastaFromBed does not recognise them. As a point of fact, it gives me this vexing output:
Code :
*****ERROR: Unrecognized parameter: -fi *****
*****ERROR: Unrecognized parameter: /home/malidictus/RuddTomato/genomic_fasta.fa *****
*****ERROR: Unrecognized parameter: -bed *****
*****ERROR: Unrecognized parameter: /home/malidictus/RuddTomato/temp/mixed_tomato_sorted.txt.output.gff3.fixed.gff *****
*****ERROR: Unrecognized parameter: -fo *****
*****ERROR: Unrecognized parameter: test.fa *****
Program: fastaFromBed (v2.12.0)
Author: Aaron Quinlan (...)
Summary: Extract DNA sequences into a fasta file based on feature coordinates.
Usage: fastaFromBed [OPTIONS] -fi <fasta> -bed <bed/gff/vcf> -fo <fasta>
Options:
-fi Input FASTA file
-bed BED/GFF/VCF file of ranges to extract from -fi
-fo Output file (can be FASTA or TAB-delimited)
-name Use the name field for the FASTA header
-tab Write output in TAB delimited format.
- Default is FASTA format.
-s Force strandedness. If the feature occupies the antisense strand,
the sequence will be reverse complemented.
- By default, strand information is ignored.
It asks for -fi as a console argument yet does not recognise it. It asks for -bed and doesn't recognise that. It doesn't recognise its own parameters! That's only through Java, however. Running this through the actual linux console works, but trying to run it from Java bombs. Why? I thought it might have something with how I tokenize the input, but I tried everything I could think of. I gave it all as a single string and that bombed - linux interpreted it all as one file. I tried splitting it into two tokens - the programme and all the parameters, but then fastaFromBed read them all as one parameter and didn't recognise them. I then tried what I showed you - to break everything up into individual tokens and THAT didn't work because it still doesn't recognise it.
I'm out of ideas at this point. What does it all mean?
Re: Passing console parameters to fastaFromBed under Ubuntu
Try splitting up the command line arguments into different String objects and pass the values to the ProcessBuilder constructor. For instance:
Code :
ProcessBuilder builder = new ProcessBuilder("fastaFromBed", "-fi ", this.fastaFile.getAbsolutePath(), ......
Re: Passing console parameters to fastaFromBed under Ubuntu
Quote:
Originally Posted by
copeg
Try splitting up the command line arguments into different String objects and pass the values to the ProcessBuilder constructor. For instance:
Code :
ProcessBuilder builder = new ProcessBuilder("fastaFromBed", "-fi ", this.fastaFile.getAbsolutePath(), ......
Oh, damn! I didn't realise what code I'd posted. This is from when I tried to pass everything as a single string. I did try precisely what you suggested, and it threw p the exact same error. The code I meant to post as an example looked more like this:
Code java:
private void fastaFromBed()
{
String[] commandLine = {"fastaFromBed", " -fi ", this.fastaFile.getAbsolutePath(),
" -bed ", this.outputFile.getAbsolutePath(), " -fo ", "test.fa"};
System.out.println();
try
{
ProcessBuilder builder = new ProcessBuilder(Arrays.asList(commandLine));
builder.redirectErrorStream(true);
Process fastaFromBed = builder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(fastaFromBed.getInputStream()));
String line = reader.readLine();
while(line != null)
{
System.out.println(line);
line = reader.readLine();
}
fastaFromBed.destroy();
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
As I understand it, ProcessBuilder takes a List of separate tokens, so I submitted an array I intend to get from elsewhere under normal operations and turned that to a list. I tried it, and it works just as well with a String Array, and it also works just as well like you suggested - as a series of strings. I tried it as a series of strings and it still didn't work.
I really don't know what the deal is with this thing...
Re: Passing console parameters to fastaFromBed under Ubuntu
Well, son of a gun! I always knew it would be something inane that was causing the problem, but I didn't think it would be THIS inane. I've been on the phone with a colleague of mine, brainstorming the problem when I just tripped over the source of the problem. It's spaces.
You'll note that in both my code chunks, I have spaces in the argument strings, i.e. " -fi ". I put those in because I adapted what used to be string concatenation, where those spaces were needed to space out the words in the string. Well, it turns out that not only do I not need the spaces, leaving them in confuses Linux. I took the spaces out and now the programme recognises its own parameters. And I realise why it wasn't recognising them before. What it was telling me was that " -fi " didn't look like "-fi" to it.
When I write this from the command line, it works because the shell's bash compiler edits those out, it's smart like that. It doesn't work when I ask for a process from Java, however, because Java appears to bypass bash entirely and supplies tokens straight to the operating system, putting the onus on ME to clean them up before I supply them. Which I obviously didn't do because I'm used to programming on Windows where the operating system itself does the cleaning and I can be sloppy. Can't do that with Linux - it needs me to be exact.
But yes, the problem is solved and an objective lesson is learned: "Don't feed whitespace to Linux!"