How to match multiple packages in btrace - java

Assuming I want to trace method calls in all the classes in packages com.abc and com.def
I put the following in my tracing script:
#OnMethod(clazz = "/com\\.(abc|def)\\..*/", method = "/.*/")
ran the script, but the output only contained method calls in com.abc package.
I changed the above line to:
#OnMethod(clazz = "/com\\.def\\..*/", method = "/.*/")
and ran the script again. The output contained method calls in com.def package.
So what's wrong with the part "(abc|def)"?
I've tried to find some information under the following link:
https://github.com/btraceio/btrace/wiki/BTrace-Annotations
The description is very abstract:
/regex/ is a standard regular expression used to identify the class
names
Does it support OR-relation?

Related

javassist - How can I replace a method body without extra startup flags on Java 17?

I'm trying to redefine a method at runtime using javassist, but I'm running into some issues on the last step, because of the weird requirements I have for this:
I can't require the user to add startup flags
My code will necessarily run after the class has already been defined/loaded
My code looks like this:
val cp = ClassPool.getDefault()
val clazz = cp.get("net.minecraft.world.item.ItemStack")
val method = clazz.getDeclaredMethod(
"a",
arrayOf(cp.get("net.minecraft.world.level.block.state.IBlockData"))
)
method.setBody(
"""
{
double destroySpeed = this.c().a(this, $1);
if (this.s()) {
return destroySpeed * this.t().k("DestroySpeedMultiplier");
} else {
return destroySpeed;
}
}
""".trimIndent()
)
clazz.toClass(Items::class.java)
(I'm dealing with obfuscated method references, hence the weird names)
However, calling .toClass() causes an error as there are then two duplicate classes on the class loader - and to my knowledge there's no way to unload a single class.
My next port of call to update the class was to use the attach API and an agent, but that requires a startup flag to be added (on Java 9+, I'm running J17), which I can't do given my requirements. I have the same problem trying to load an agent on startup.
I have tried patching the server's jar file itself by using .toBytecode(), but I didn't manage to write the new class file to the jar - this method sounds promising, so it's absolutely on the table to restart the server after patching the jar.
Is there any way I can get this to work with my requirements? Or is there any alternative I can use to change a method's behavior?

Getting `java.lang.ClassNotFoundException: org.apache.commons.pool.PoolableObjectFactory` when using Java reflection

I am trying to invoke a function using java reflection. My initial program is written in Ballerina which is given below.
import ballerina/http;
function __getQueryResults() returns error|string{
http:Client myClient = check new("https://disease.sh");
http:Response response = check myClient->get("/v3/covid-19/all");
return response.getTextPayload(); }
I am creating a Ballerina project with above function, build the project, and I am getting a jar file as the result.
Then I get the URLClassLoader of the jar file as below
URL pathUrl = Paths.get(executablePath).toUri().toURL();
URLClassLoader classLoader = AccessController.doPrivileged((PrivilegedAction<URLClassLoader>) () ->
new URLClassLoader(new URL[]{pathUrl}, ClassLoader.getSystemClassLoader()));
and trying to invoke the __getQueryResults function by invoking $configureInit, $moduleInit, $moduleStart and __getQueryResults orderly.
I am getting the below exception when trying to invoke $moduleInit function
java.lang.NoClassDefFoundError: org/apache/commons/pool/PoolableObjectFactory
Any possible causes or solutions to this issue ?
This NoClassdEfError happens if the internal data structure of the class definition cannot be find or if the previous attempt to load the class was failed due to class path issue.
BTW we do not recommend to use java reflection to invoke ballerina function from java native side, since async code will not work properly since we do not properly schedule ballerina function call.
We have discussed same issue in https://github.com/ballerina-platform/ballerina-lang/issues/34793 and decided to generate ballerina project with the main function which calls the required ballerina function, and use the bal run command to execute the generated project.

How do I execute a java method/function inside jmeter's __groovy() function?

I'm new to jmeter. I have a java function whose output needs to be passed to Http Request body. I'm using jmeter's groovy() function for the same. I created a jar file and placed it in the lib folder, and restarted jmeter. Then, when I try to make an instance of the class and execute a method, I'm not able to get the value returned by the function. How do I execute a java snippet/function inside jmeter's groovy() function.
Request Body :-
"key": "${__groovy(TestEncryption encryption = new TestEncryption(); encryption.encrypt();)}"
I don't see any response at all after the API call.
It would be something like:
${__groovy(new your.package.your.Class().yourFunction(param1\, param2),)}
for example calling Random.nextInt() will look like:
${__groovy(new java.util.Random().nextInt(10),)}
Demo:
More information:
JMeter: Functions and Variables
Apache Groovy - Why and How You Should Use It

imageJ plugin argument

Hello I am trying to pass arguments to my ImageJ PlugIn. However it seems no matter what I pass, argument string will be considered as empty by the program. I couldn't find any documentation on the internet about THAT issue.
My Java plugIn looks like this, and compiles fine.
import ij.plugin.PlugIn;
public class Test implements PlugIn {
public void run(String args) {
IJ.log("Starting plugin Test");
IJ.log("args: ." + args + ".");
}
}
I compile, make a .jar file and put it into the ImageJ plugins folder.
I can call it with the ImageJ userInterface (Plugin>Segmentation>Test) and the macro recorder will put the command used:
run("Test");
Then my code is executed, the log window pops-up as expected:
Starting plugin Test
args: ..
I can manually run the same command in a .ijm file, and get the same result.
However, when I run the following macro command:
run("Test", "my_string");
I get the same results in the log window:
Starting plugin Test
args: .. // <- I would like to get "my_string" passed there
Where it should have displayed (at least what I expect it to do)
Starting plugin Test
args: .my_string.
So my question is: how can I pass parameters to PlugIn and especially how to access them?
Many thanks
EDIT
Hey I found a way to bypass that:
Using the Macro.getOptions() : this method will retrieve the string passed in argument to the plugin.
However, I still can't find a way to pass more than 1 string argument. I tried overloading the PlugIn.run() method but it doesn't work at all.
My quick fix is to put all my arguments in 1 string, and separating them by a space. Then I split this string:
String [] arguments = Macro.getOptions().split(" ");
I don't see a more convenient way to get around that. I can't believe how stupid this situation is.
Please, if you have a better solution, feel free to share! Thanks
You are confusing the run(String arg) method in ij.plugin.Plugin with the ImageJ macro command run("command"\[, "options"\]), which calls IJ.run(String command, String options).
In the documentation for ij.plugin.Plugin#run(String arg), it says:
This method is called when the plugin is loaded. 'arg', which may be blank, is the argument specified for this plugin in IJ_Props.txt.
So, arg is an optional argument that you can use in IJ_Props.txt or in the plugins.config file of your plugin to assign different menu commands to different functions of your plugin (see also the excellent documentation on the Fiji wiki).
To make use of the options parameter when running your plugin from macro code, you should use a GenericDialog to get the options, or (as you apparently learned the hard way) use the helper function Macro.getOptions().

How to embed version strings in java classes

We'd like to have the version of the java source code, in our case the svn $Id$ string, embedded in the generated class file.
We'd like to be able to determine this information from a static inspection of the class file, preferably by running the strings or what command.
A naive attempt to declare a private final static String variable set to this value inside each class didn't result in a legible string embedded in the class file.
You said ... preferably by running the strings or what command ...
Let's assume you have something like this in your code:
private static final String SVN_ID =
"$Id: SvnIdDemo.java 1081 2008-09-30 19:03:23Z john $";
The following Perl one-liner ...
$ perl -nwe 'print "$1\n" if /.*(\$Id:[^\$]+\$).*/' SvnIdDemo.class
... prints the SVN ID string to STDOUT.
$Id: SvnIdDemo.java 1081 2008-09-30 19:03:23Z john $
You could add a method to the bottom of each class with a predefined name. Say you used:
public String extractChaimGeretzVersionNumber() {
return "$Id$";
}
Then you find the version with a program that loads the class and, via reflection, calls the magic method and retrieves the version.
You would either have to have code that inserted the method to the .java files before building the .class and .jar files OR you could have a build step that checked that the magic method was already in every one of them. Fail the build if not found.

Categories

Resources