Test works on local Windows machine but fails on Linux server - java

I have this test:
#Test
void testHeader() {
String inputFile = ".\\src\\main\\resources\\binaryFile";
MDHeader addHeader = new MDHeader();
try (
InputStream inputStream = new FileInputStream(inputFile);
) {
long fileSize = new File(inputFile).length();
byte[] allBytes = new byte[(int) fileSize];
inputStream.read(allBytes);
ProducerRecord<String, byte[]> record = new ProducerRecord<String, byte[]>("foo", allBytes);
ProducerRecord<String, byte[]> hdr = addHeader.addMDHeader(record);
for (Header header : hdr.headers()) {
assertEquals("mdpHeader", header.key());
}
}
catch(Exception e) {
assert (false);
}
}
The test succeeds when run locally through Eclipse on my Windows desktop but it fails at com.me.be.HeaderTests.testMDHeader(HeaderTests.java:81) when trying to build the jar on a Linux server. That's the line assert (false). I haven't got any more information on the issue yet but was wondering if it could be the backslashes in inputFile in a Linux environment?

Java on Windows and Linux will both accept / as path separator, whereas Linux does not like \\ as a path separator - so treats the whole string as ONE path component, not 4 parts as you'd expect:
String inputFile = "./src/main/resources/binaryFile";
However for file handling it is better to use java.nio.Path or java.io.File in place of String.
WINDOWS
jshell> Path.of("./src/main/resources/binaryFile")
$2 ==> .\src\main\resources\binaryFile
Linux
jshell> Path.of("./src/main/resources/binaryFile")
$1 ==> ./src/main/resources/binaryFile
You can also use Path.of without any file separator for any OS:
Path p = Path.of("src","main","resources","binaryFile");

The File.separator string is handy to concat into the path string in order to produce an OS independent file path.
String inputFile = "." + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "binaryFile";
Should give you a cross platform compliant file path.

Related

Fortify pointed out an issue: "Portability Flaw: File Separator", but there is no hard-coded separator in the code

Fortify SCA tool find an issue called Portability Flaw: File Separator, but with the source of those issues, there is none hardcoded file separator such as "/" or "\", only file extensions such as "." exists.
Our customer used Fortify SCA to scan their legacy system source codes. Fortify found Portability Flaw: File Separator issues. It said that the file names which declared in a String array contain hard-coded file separator (this string array is the source of the problem), but I can't see any file separator such as "/" or "\" in those file name strings.
public static final String SYS_SPRAT = File.separator; //this is declared as a class attribute
String[] fileNames = { //fortify points out here is the source of this issue
"",
"2.5.1aaaaa.pdf",
"2.5.2bbbbb.pdf",
"2.5.3ccccc.pdf",
.......
"5.1.4甲甲甲甲甲.pdf",
};
String fileName = null;
File file = null;
int iParam = Integer.parseInt(sParam);
if (iParam >= 1 && iParam <= 26) {
fileName = fileNames[iParam];
String filePath = SYS_SPRAT + "home" + SYS_SPRAT + "xxx" + SYS_SPRAT + "ooo" + SYS_SPRAT + "Resource" + SYS_SPRAT + fileName;
file = new File(filePath);
else {
addFacesMessage("wrong parameter");
return null;
}
I still can't figure out why there is an issue. Is it a false positive? (but why?)
It seems that Fortify may be overly strict here. Even their website says that using File.separator like this should be ok.
I can't see any portability problem using File.separator. Even on OpenVMS systems, where file paths are in the format devicename:[directory.subdirectory]file.ext;version, the Java runtime internally translates between a / separator and the proper VMS format.
First, double-check using a "Find" tool that you don't have any \ or / characters in any of the strings in filenames[] (don't just rely on visual inspection). If there is definitely no such character, then proceed with the suggestion below.
Try avoiding File.separator altogether. Instead, try using Paths.get:
public static final Path RESOURCE_DIR = Paths.get(
"home", "xxx", "ooo", "Resource");
String[] fileNames = {
"",
"2.5.1aaaaa.pdf",
"2.5.2bbbbb.pdf",
"2.5.3ccccc.pdf",
.......
"5.1.4甲甲甲甲甲.pdf",
};
String fileName = null;
File file = null;
int iParam = Integer.parseInt(sParam);
if (iParam >= 1 && iParam <= 26) {
fileName = fileNames[iParam];
file = RESOURCE_DIR.resolve(filePath).toFile();
else {
addFacesMessage("wrong parameter");
return null;
}
Is Fortify ok when you do this?

How to pass arguments to pre compiled java code

I need to process a high volume of resumes. And want to use this parser:
https://github.com/antonydeepak/ResumeParser
But you run it in powershell with the file to read and the output file.
But I do not know how to automate this, so it read a whole folder containing the resumes.
I know some Java, but cant open the code. Is scripinting in powershell the way to go?
Thanks!
> java -cp '.\bin\*;..\GATEFiles\lib\*;..\GATEFILES\bin\gate.jar;.\lib\*'
code4goal.antony.resumeparser.ResumeParserProgram <input_file> [output_file]
Either make a batch file from an edited directory listing, or write a program.
As this is stackoverflow:
So starting with the same classpath (-cp ...) you can run your own program
public void static main(String[] args) throws IOException {
File[] files = new File("C:/resumes").listFiles();
File outputDir = new File("C:/results");
outputDir.mkDirs();
if (files != null) {
for (File file : files) {
String path = file.getPath();
if (path.endsWith(".pdf")) {
String output = new File(outputDir,
file.getName().replaceFirst("\\.\\w+$", "") + ".json").getPath();
String[] params = {path, output);
ResumeParserProgram.main(params);
// For creating a batch file >x.bat
System.out.println("java -cp"
+ " '.\\bin\\*;..\\GATEFiles\lib\\*;"
+ "..\\GATEFILES\\bin\\gate.jar;.\\lib\\*'"
+ " code4goal.antony.resumeparser.ResumeParserProgram"
+ " \"" + path + "\" \"" + output + "\"");
}
}
}
}
Check that this works, that ResumeParserProgram.main is reenterable.

How to Bunzip a file stored

I have to archive the HDFS files frequently. The files have to be compressed in the Bunzip format using Java code. Now, what I did is the following:
Move the input files to a local location hdfs.moveToLocalFile
bzip using the bzip2 command.
Move the .bz2 files to the HDFS to another locationhdfs.moveFromLocalFile.
I'm using Hadoop 1.1.2 version. Is there any API available to bzip the files directly, without local copy and BZip?
Also now I'm using the linux shell command to BZip the files. Can somebody help me how to do the BZip command using Java code?
public void addFile(String source, String destination, Configuration paramConfiguration) throws IOException, URISyntaxException {
FileSystem localFileSystem = FileSystem.get(paramConfiguration);
String str1 = paramString1.substring(source.lastIndexOf('/') + 1, source.length());
if (destination.charAt(destination.length() - 1) != '/') {
destination = destination + "/" + str1;
} else {
destination = destination + str1;
}
BZip2Codec localBZip2Codec = new BZip2Codec();
String str2 = localBZip2Codec.getDefaultExtension();
Path localPath = new Path(paramString2 + str2);
CompressionOutputStream localCompressionOutputStream = localBZip2Codec.createOutputStream(localFileSystem.create(localPath));
IOUtils.copyBytes(localFileSystem.open(new Path(paramString1)), localCompressionOutputStream, 4096, true);
}

Remove filename from a URL/Path in java

How do I remove the file name from a URL or String?
String os = System.getProperty("os.name").toLowerCase();
String nativeDir = Game.class.getProtectionDomain().getCodeSource().getLocation().getFile().toString();
//Remove the <name>.jar from the string
if(nativeDir.endsWith(".jar"))
nativeDir = nativeDir.substring(0, nativeDir.lastIndexOf("/"));
//Load the right native files
for(File f : (new File(nativeDir + File.separator + "lib" + File.separator + "native")).listFiles()){
if(f.isDirectory() && os.contains(f.getName().toLowerCase())){
System.setProperty("org.lwjgl.librarypath", f.getAbsolutePath()); break;
}
}
That's what I have right now, and it work. From what I know, because I use "/" it will only work for windows. I want to make it platform independent
Consider using org.apache.commons.io.FilenameUtils
You can extract the base path, file name, extensions etc with any flavor of file separator:
String url = "C:\\windows\\system32\\cmd.exe";
String baseUrl = FilenameUtils.getPath(url);
String myFile = FilenameUtils.getBaseName(url)
+ "." + FilenameUtils.getExtension(url);
System.out.println(baseUrl);
System.out.println(myFile);
Gives,
windows\system32\
cmd.exe
With url; String url = "C:/windows/system32/cmd.exe";
It would give;
windows/system32/
cmd.exe
By utilizing java.nio.file; (afaik introduced after J2SE 1.7) this simply solved my problem:
Path path = Paths.get(fileNameWithFullPath);
String directory = path.getParent().toString();
You are using File.separator in another line. Why not using it also for your lastIndexOf()?
nativeDir = nativeDir.substring(0, nativeDir.lastIndexOf(File.separator));
File file = new File(path);
String pathWithoutFileName = file.getParent();
where path could be "C:\Users\userName\Desktop\file.txt"
The standard library can handle this as of Java 7
Path pathOnly;
if (file.getNameCount() > 0) {
pathOnly = file.subpath(0, file.getNameCount() - 1);
} else {
pathOnly = file;
}
fileFunction.accept(pathOnly, file.getFileName());
Kotlin solution:
val file = File( "/folder1/folder2/folder3/readme.txt")
val pathOnly = file.absolutePath.substringBeforeLast( File.separator )
println( pathOnly )
produces this result:
/folder1/folder2/folder3
Instead of "/", use File.separator. It is either / or \, depending on the platform. If this is not solving your issue, then use FileSystem.getSeparator(): you can pass different filesystems, instead of the default.
I solve this problem using regex.
For windows:
String path = "";
String filename = "d:\\folder1\\subfolder11\\file.ext";
String regEx4Win = "\\\\(?=[^\\\\]+$)";
String[] tokens = filename.split(regEx4Win);
if (tokens.length > 0)
path = tokens[0]; // path -> d:\folder1\subfolder11
Please try below code:
file.getPath().replace(file.getName(), "");

Invalid character in zipfile path (Windows)

I have to unzip one file that contains a invalid path for Windows OS:
9f96bc3dE8d94fc2B1fd2ff9ed8d2637\html\portlet\facilit\planooperativo\themes\plano-operativo-theme\css\data:image
data:image, in windows it's not permited to be directory with : in path
then my code to unzip got this exception
java.io.IOException: The filename, directory name, or volume label syntax is incorrect
How can I fix it, changing : for another character (underline for example) or just skip this directory.
I've tried this code below, but it doesn't work:
while (ze != null) {
String fileName = ze.getName();
File newFile = new File(outputFolder + File.separator + fileName);
String nameFile = newFile.getAbsolutePath();
if (nameFile.contains(":")){
nameFile.replaceAll(":", "_");
newFile = new File(nameFile);
}
actually my path needs to contain : because the complete path needs to begin with C:\, please give me one solution (Detail: it works fine in Mac)
while (ze != null) {
String fileName = ze.getName();
if (fileName.contains(":")){
fileName = fileName.replaceAll(":", "_");
}

Categories

Resources