D.Davis
D.Davis

Reputation: 1

JMeter Bean Shell Sampler error "...Static method get( java.lang.String ) not found in class'java.nio.file.Paths" when copying files

I am attempting to copy and rename a file on my local machine (Win 7) using Bean Shell Sampler in JMeter 3.0 (Java v1.8). The idea is to create the new file with a unique name and have the name saved as a variable that can be used in place of the file name in an FTP PUT request.

Here is the code I am using for the copy and rename:

import java.text.*;
import java.nio.file.StandardCopyOption.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

String filename = new SimpleDateFormat("dd-MM-yyyy_hh:mm:ss").format(new Date())+".xlsx";
log.info(filename);

Path source = Paths.get("C:/dropfile/qatp/QATP_GuestRecords.xlsx");
Path target = Paths.get("C:/dropfile/qatp/"+filename);

Files.copy(source, target, REPLACE_EXISTING);

The error I am receiving in the log:

ERROR - jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import java.text.; import java.nio.file.StandardCopyOption.; import java.io.IO . . . '' : Typed variable declaration : Error in method invocation: Static method get( java.lang.String ) not found in class'java.nio.file.Paths'

I have been searching for an answer to this issue and came across a solution where the suggestion was: "My guess is that the problem is that it's not populating the varargs parameter. Try:

Path target = Paths.get(filename, new String[0]);"

I tried this solution by modifying my code like so:

import java.text.*;
import java.nio.file.StandardCopyOption.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

String filename = new SimpleDateFormat("dd-MM-yyyy_hh:mm:ss").format(new Date())+".xlsx";
log.info(filename);

Path source = Paths.get("C:/dropfile/qatp/QATP_GuestRecords.xlsx", new String[0]);
Path target = Paths.get("C:/dropfile/qatp/"+filename, new String[0]);

Files.copy(source, target, REPLACE_EXISTING);

And received this error:

ERROR - jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import java.text.; import java.nio.file.StandardCopyOption.; import java.io.IO . . . '' : Typed variable declaration : Method Invocation Paths.get

Does anyone know why I am hitting this error and how to get around it?

Upvotes: 0

Views: 4332

Answers (2)

Dmitri T
Dmitri T

Reputation: 168157

Beanshell != Java, it doesn't support all the Java features (think about it as about Java 1.5 and amend your code appropriately.

So I would recommend switching to JSR223 Sampler and Groovy language, Groovy is much more Java-compliant and performs much better.

Also be aware that you can use FileUtils.copyFile() method which will work for both Beanshell and/or Groovy

import org.apache.commons.io.FileUtils;
import java.text.SimpleDateFormat;

String filename = new SimpleDateFormat("dd-MM-yyyy_hh:mm:ss").format(new Date()) + ".xlsx";
FileUtils.copyFile(new File("/tmp/QATP_GuestRecords.xlsx"), new File("/tmp/" + filename));

See Groovy is the New Black article for more information on using Groovy language in JMeter test scripts.

Upvotes: 1

Hugues M.
Hugues M.

Reputation: 20477

Even in plain old Java this is a misleading use of Paths.get, which takes an URI, or an array of strings (varargs). See javadoc.

In Java what you tried works because the static typing allow the compiler to determine that you are passing an array of a single String. Apparently BeanShell does not and gets confused. The trick suggested in the other answer is not a good one in my opinion: again in Java it would work, by joining the two strings (2nd one is empty, so result is 1st string, which is what you want), but it confuses BeanShell all the same because there is another static get method that takes 2 arguments.

If you already have the path as a single String, try this instead:

Path source = new File("C:/dropfile/qatp/QATP_GuestRecords.xlsx").toPath();

Alternatively, you could use Paths.get like this:

Path source = Paths.get("C:", "dropfile", "qatp", "QATP_GuestRecords.xlsx");

Or like this (varargs is syntaxic sugar to help pass an array):

Path source = Paths.get(new String [] { "C:/dropfile/qatp/QATP_GuestRecords.xlsx" });

It's perfectly valid to pass fragments of path as arguments, or the entire path string as single argument, but that seems to trip BeanShell, so, better avoid Paths.get in BeanShell, unless you pass an array explicitly as in last example.

Upvotes: 2

Related Questions