How to pass dalvik command line parameters through .apk? - java

I know that it is possible to launch java program in Android in a such way:
adb push "hello_world.zip" $REMOTE_PATH/
adb shell mkdir $REMOTE_PATH/dalvik-cache
adb shell dalvikvm -cp "$REMOTE_PATH/hello_world.zip" -Xint:portable -Xdexopt:none -Xverify:none hello_world
It's very good!
But now I want to create Android .apk file. And I want this application to be launched with the same command line parameters "-Xint:portable -Xdexopt:none -Xverify:none" automatically.
I assume that parameters names may differ from this "-Xint:portable -Xdexopt:none -Xverify:none", but functionality must be the same. I have no idea what I have to do and google doesn't want to help me to solve this issue.
Any help would be much appreciated!

I think #Delyan's answer hit the important points, but I wanted to add a few more details that didn't fit in a comment.
The official doc on doing this sort of thing is Controlling the Embedded VM (in source tree). The execution-mode property affects all apps, because the VM is only started once -- as "zygote" -- and all apps are launched by forking that process.
It's possible to change the mode of the VM once it has started, perhaps by introducing a new VMRuntime API call, but I don't think anybody has tried that and I'm not sure offhand how it would interact with the JIT compiler.
Most DEX optimization and verification is performed by dexopt before the app is ever launched, and the results are stored in the .odex file in /data/dalvik-cache, so tweaking -Xdexopt and -Xverify at app launch time may not do much (see dexopt docs; source).

I'm reasonably certain that you can't. You can change the system-wide interpreter mode with setprop dalvik.vm.execution-mode int:portable but you would need root. I don't know of any way to disable dexopt for your process only (that would be a security risk!). You most certainly can't touch the bootclasspath (which is the classpath that your app initially runs under).
I believe you can disable jnicheck for your process but that's about it.
Apps on the device run via app_process and the zygote, you can think of them as restricted wrappers around Dalvik. There are no dalvikvm invocations apart from the initial zygote one - every future process starts with a fork(), so you can't actually change those parameters without messing with the zygote. (I'm simplifying but I'm pretty sure I'm right)

Related

What is JFR parameter filename meaning? File ends up being empty after exit

I have situation where I start JDK18 jvm from c++ code to produce vst plugin goal being to implement audio signal algorithms in java side with added value of full java GUI api. My framework works very smoothly apart from the repeatable state where my audio streaming crashes after 14 hours. So I thought this is good place to start learning JFR. My jvm starting parameters are in xml file and relevant part is:
<param>
-XX:StartFlightRecording,dumponexit=true,filename=c:/out/blackbox.jfr
</param>
Even when application exits that named file keeps empty. So what is the idea of filename parameter if it stays empty and how to use it?
The recording is dumped in a Java shutdown hook. If you terminate the C++ application with exit(status), the Java hook never gets a chance to run.
Not sure how to best run the shutdown hooks, but you could perhaps invoke System.exit(status) from native using CallStaticVoidMethod?
My solution with JDK 18 and flight recorder is not to use JVM startup options at all but instead use jcmd's JFR commands. This is due to incompatible JVM options at startup and lacking documentation. Available documentation is clearly for some older versions of JVM. Here is the available documentation:https://docs.oracle.com/javacomponents/jmc-5-5/jfr-command-reference/toc.htm which proposes use of -XX:+UnlockCommercialFeatures which has been long gone. What is current state of command line options is not achieveable for average programmer.
But "jcmd JFR.start" is example of things that work. I got things working observing with "jcmd PID JFR.check" . It is obvious that JFR api is also little bit broken and needs to addressed in a certain way to get the wanted results. There must have been very hurry when implementing it because the order of parameters is very crucial. And there is a nag that "name" must not be a number even it uses it as number. Now I know it is sensitive. So the way I want it to function is to sample and dump periodic chunks so that differences reveal them selves. Now I have the solution to that but it needs another question with no stupid complaints. Baseline is that jcmd with JFR parameter must be used as it comes out of the box in the way which is not obvious.

How to view history of curl command executed using Runtime.getRuntime().exec?

We can view bash commands history. It is stored normally in ~/.bash_history. For the same reason it is not recommended to send a curl request along with certificates and passwords.
But when I execute the same curl command using Runtime class in java Runtime.getRuntime().exec(command); I don't see this in the bash history.
It makes sense as this is done under the Runtime object and not executed from terminal. So where can I get the history of curl when done from Java using Runtime class?
Also is it safe to use Runtime class instead of actually storing certificate in a Trustore and using Https related Java classes?
Note: The certificates will be kept securely in Jenkins anyways.
How to view history of curl command executed using Runtime.getRuntime().exec?
You didn't run it with bash so, no, it is not in bash history. The answer to your question is OS dependent (and 'linux', in this sense, isn't detailed enough. What kind?) But, for example, as long as the command is running, ps auxww will probably show it, with the full command line including the arguments. As long as it is running, the directory representing the status of the process in the /proc virtual filesystem definitely lets you see the arguments it was invoked with.
Also is it safe to use Runtime class instead of actually storing certificate in a Trustore and using Https related Java classes?
That's just not how security works. It's shades of gray, not black and white. However, starting a subprocess for this is definitely a much darker gray (far less safe) than using java itself: As long as it is running, that subprocess arguments can be seen. The version of whatever command you invoke is less controllable (are you going to hash the executable? How would you know that the executable isn't being changed on you? This is of course entirely fine if you know who administrates the box and trust them, but that gets back to that shades of gray thing: If that part doesn't matter, sure, then this part is less problematic (heck, if you are the only one with an ssh login to this box, and only run trusted software, you can write the password across 50 files with global readability all over the file system and it wouldn't matter - and yet nobody is going to go on record and just make a blanket statement that this is 'safe'!).

Modify JVM flags at Runtime

I would like to modify/set JVM flags as soon as my program starts. I cannot do it on the command line, because I work with people who don't even know that exists. So it has to be automatically done in the program.
I am particularly interested by these three flags: -Xms4G -Xmx8G -noverify
I found in this discussion (or that one) that it is possible to modify some flags using the Interface HotSpotDiagnosticMXBean. And this code shows how to modify the flags. Unfortunately, the flags Xms or just ms are not recognized and then an exception is thrown.
I've also found that capsule may do the work, but it seems pretty heavy to use.
Is there any easy way to do it?
You need to write two programs: one that is just a launcher to provide the correct parameters to run your other program. This is how Eclipse works, and Jitsi, and the now-end-of-life InstallShield Multiplatform launchers. It may be that you can write a trivial (eg one line or close to it) shell, .bat, or VBS script to do the job.

Multi-threaded time-based call hierarchy

I am using eclipse to write java code. If I'm debugging some code I can set a breakpoint and follow along as the code goes through each of the functions or I can backtrack. I can also look at the call hierarchy or the references to get an idea. But that's not enough.
I would like to have a some sort of time-based visualization of what each thread is doing along the process from ... let's say "point A" (pressing a button on the interface) to "point B" (getting the result). I want to see which classes/methods were called in what order. I want a good way to visualize what kind of output is coming from one method and going into another method which fires off a new process ...etc.
Is a profiler the only thing available for this type of visualization? Basically I want an action diagram or flow diagram created. Is there some plugin or app which can generate something like this?
Edit: Here is an example of what I'm thinking ... at least visually:
essmodel.sourceforge.net/index.html
It has some flow of where the code is leading. But I think this is just a static map of what classes lead to other classes and what inputs/output options are available. I would want to map the flow based on a specific case.
JProfiler offers such a view, it's called the "Call tracer":
It's important to restrict your filters very carefully in order not to record to much data.
Disclaimer: My company develops JProfiler.
I believe using a profiler is going to be your best option. Are you familiar with VisualVM? It comes with the JDK (look for "jvisualvm.exe" inside your JDK's bin directory) and is capable of profiling local virtual machines automatically as well as remote machines when configured properly. And it does give a pretty slick overview of what threads are running and the code they are spending time in, so I think you could easily do what you need from it. And best of all, it's free :)
As I said, local profiling is a breeze. You just run JVisualVM.exe standalone, and it will find any and all java processes running on the local machine automatically (you can just pick them out of a menu that VisualVM gives you upfront). If you want to profile remotely, set the following VM arguments for whatever it is that you're running:
-Dcom.sun.management.jmxremote.port=[0-65535]
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
Then within VisualVM, use the hostname of the machine your remote JVM is running on and the port you configured in the first VM argument above.

Is there a way to include a VM parameter inside a .jar?

I have a game implemented in Java that was having a problem when running too much code from scripts: depending on the script language, the game could have these "hiccups" where the game would freeze for a couple frames every now and then, making the game "jerky" at times.
After some research, I discovered that was happening when the Garbage Collector decided to run. After some more research and testing, I discovered that using the incremental garbage collector (by using the -Xincgc VM parameter) fixed the problem. Yes, I am aware it makes the GC run about 10% slower, but it is the cost I pay.
With that background information, now what I want to do is package the game in a .jar like I have been doing so far, but I know no way of making the application use the incremental GC without using -Xincgc, and I didn't want to create .bat/.sh files where before the user only had to double-click the .jar.
Is there any way to make the .jar run with the incremental GC without needing some kind of loader (.bat/.sh) or wrapper around it? Is there some way to include that parameter in the .jar?
No, there's no way to do that. VM arguments can only be supplied as command-line parameters to JVM invocation: Java Tool
You can definitely do this with JNLP, which can be configured to add a shortcut to the desktop and automatically keep jars up to date, among other things.
From just a jar file, you can't do this. Adding Java WebStart can allow you to add java VM commands. If you are not against wrapping the jar in an executable Launch4J will wrap the jar in a executable as well. It only makes a windows exe, but it can make it on linux or windows. I haven't found a good alternative for linux.
I don't know of too many java apps outside of internal coorporate or dev stuff that people run via clicking a jar. Even a shortcut can specify this. Fancier options exist that let you create an exe, run as a service, or even wrap the whole thing in an installer... if we are talking windows, similar things exist for linux.
Besides Java Web Start, you could consider wrapping with JSMooth. It gives an EXE which in turn invokes the JVM - you can provide arguments there.
One option - I always wondered - is to re-run the jar program with Runtime.exec() call when the parameters are inadequate? Never tried it but seems possible.

Categories