android add java.lang.management API - java

Now I have a problem with Android non-supported libraries. In fact it does not support this API: "java.lang.management".
Eclipse shows me this error :
10-25 17:53:03.460: java.lang.NoClassDefFoundError: java.lang.management.ManagementFactory.
I wonder how I can add this API to be supported by my android application.
Any help please.

That API is not a part of Android, and is not compatible with Android.
The java.lang.management API is for managing and monitoring the Java VM. Android's Dalvik VM is not a Java VM.

It seems that with Android Version 23, situation has slightly improved. For example I found a replacement for:
GarbageCollectorMXBean gb = ....
long gctime = gb.getCollectionTime();
Thanks to #Jacob, I am now using this code. First the getRuntimeStat() method is not available in all android versions. So I am doing some reflection first:
static {
try {
Class<?> debugClass = Debug.class;
getRuntimeStat = debugClass.getDeclaredMethod(
"getRuntimeStat", String.class);
} catch (NoSuchMethodException x) {
getRuntimeStat = null;
}
}
Retrieving the GC time is then a matter of calling the method handle, with the correct property name. I am currently using this property name:
String gctimestr;
try {
gctimestr = (String) (getRuntimeStat != null ?
getRuntimeStat.invoke(null, "art.gc.gc-time") : null);
} catch (IllegalAccessException e) {
gctimestr = null;
} catch (InvocationTargetException e) {
gctimestr = null;
}
The gctimestr can then be converted to a long value, if its non-null. On the other hand if its null the statistics is not available, through this API.

Related

How do I resolve this error using Paths.of?

I have been trying many of the examples provided and have yet to be successful. Here is the code I am currently trying, but getting an error in Eclipse on Paths.of (the of is underlined in red) that says: "rename in file".
String content;
try {
content = Files.readAllLines(Paths.of("C:", "Calcs.txt"));
} catch (IOException e1) {
e1.printStackTrace ();
}
System.out.println (content);
First it is not possible, if you get a list as return type, to assign this to a string. So you must write:
List<String> content;
Second regarding to the Java 8 documentation there is no method of available for this class. You can use the method get like this:
List<String> content = Files.readAllLines(Paths.get("C:", "Calcs.txt"));
Otherwise there exists a method of in the Path class since Java 11. Therefore you can write something like that:
List<String> content = Files.readAllLines(Path.of("C:", "Calcs.txt"));
You're probably looking for Paths.get:
String content;
try {
content = String.join("\n", Files.readAllLines(Paths.get("/home/hassan", "Foo.java")));
} catch (IOException e1) {
e1.printStackTrace ();
}

Android - Dynamically load system library without exact path?

A couple months ago I graduated from Android samples to work-related projects. As such, I am still painfully new to this build system and fully admit my inexperience with all things *.mk file and Android related.
I have a library that depends on OpenCL v1 or greater. Loading is delayed until the functionality is needed, and only if the minimum version of OpenCL is supported. Up until a couple days ago, I would receive a java.lang.UnsatisfiedLinkError whenever I tried to load it because libGLES_mali.so could not be located. Apparently the device my coworker tested on had this file while my device does not. I found other GLES libs that do exist on my test phone but my code to load them is... longer than I would think it should be.
Trying to use System.loadLibrary("GLES") didn't yield success, nor anything similar.
According to this site (http://www.2net.co.uk/tutorial/android-egl-cgf-is-dead) I need to try to load every GLES library I can think of by name, from both system/lib/ and system/lib/egl/. Consequently, currently my code for loading this library is as follows:
boolean bGles = false;
if(!bGles) {
try {
System.load("system/lib/egl/libGLES.so");
bGles = true;
} catch (java.lang.UnsatisfiedLinkError e) {
}
}
if(!bGles) {
try {
System.load("system/lib/libGLES.so");
bGles = true;
} catch (java.lang.UnsatisfiedLinkError e) {
}
}
if(!bGles) {
try {
System.load("system/lib/egl/libGLES_android.so");
bGles = true;
} catch (java.lang.UnsatisfiedLinkError e) {
}
}
if(!bGles) {
try {
System.load("system/lib/libGLESv1_CM.so");
bGles = true;
} catch (java.lang.UnsatisfiedLinkError e) {
}
}
if(!bGles) {
try {
System.load("system/lib/egl/libGLESv1_CM.so");
bGles = true;
} catch (java.lang.UnsatisfiedLinkError e) {
}
}
It's so terribly messy! Is there no way of asking Android to load whatever the default 'GLES' is on the system? Default version number? I can't knock the tutorial completely, as all my libraries now load and function correctly now, but what will I do for other devices? With other names for their GLES libs?
I feel that I must be misunderstanding the article. Certainly, there must be a better way to load a shared system library than this?
First off, there's a better way to do what you're doing
String libraries[] = {"name1","name2",...}
boolean success = false;
for(String library : libraries) {
try{
System.load(library);
success = true;
break;
}
catch(UnsatisfiedLinkError) {}
}
if(!success) {
//Handle the failed all case
}
Secondly- why do you think you need to do this to begin with? Why aren't you using the build in OpenGL functionality and Java classes? If you aren't, your app is likely to break badly between devices. Edit: Ok, I now noticed OpenCL and did some digging. Android does not support OpenCL. Some devices do, but there's no general libraries for it. I'd reconsider going this route, if you do follow it you will only ever work on a subset of devices, and you're going to have to add hacks for each new generation.

java.lang.nosuchfielderror in j2me app

Hey Hi Friends I am created one j2me app. it runs perfectly in Emulator but in Mobile it showing error like java.lang.nosuchfielderror:No such field HEADERS.[[Ljava/lang/String;.
Why this happening with mobile, it runs good in emulator......
Please help me to remove this error......
public String connectPhoneName() throws Exception{
String url = "http://122.170.122.186/Magic/getPhonetype.jsp";
String phoneType;
if ((conn = connectHttp.connect(url, HEADERS)) != null) {
if ((in = connectHttp.getDataInputStream(conn)) != null) {
byte[] data = connectHttp.readDATA(in, 100);
phoneType = new String(data);
System.out.println("DATA : " + phoneType);
} else {
throw new Exception("ERROR WHILE OPENING INPUTSTREAM");
}
} else {
throw new Exception("COULD NOT ESTABLISH CONNECTION TO THE SERVER");
}
return phoneType;
}
In this code i have used HEADERS.
It looks like your app is using some (I guess) or static final or final field of some library class that does not exist in the profile of Java ME your mobile device implements.
But I can't figure out where that field comes from. Perhaps you should search your codebase for use of "HEADER" as an identifier ...
If the HEADER field is properly declared in your codebase (your MagiDEF interface) and the code you showed is using the HEADER from that interface, then you must have something wrong with your build or deployment process. Specifically, you are not deploying the version of MagiDEF that your code (above) has been compiled against. Maybe you've got an old version of something in some JAR file?
Basically, the error indicates that you have a binary incompatibility between some of the classes / interfaces that make up your app.

Replace <Unknown Source> in Java Rhino (JSR223) with actual file name

In my code, all of the scripts are contained in .js files. Whenever one of the scripts contains an error, I get this:
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "nonexistant" is not defined. (<Unknown source>#5) in <Unknown source> at line number 5
What bugs me is the <Unknown Source>. Multiple files are in one ScriptContext, and it can be hard to track down an error. It also looks horrible.
Is there a way to replace <Unknown Source> with the actual file name? None of the methods I see support passing a File object, so I'm really confused here.
Use the ScriptEngine.FILENAME constant:
scriptEngine.put(ScriptEngine.FILENAME, scriptFile.toString());
The question hasn't been specifically asked yet, but I thought I'd offer this to anyone who stumbles upon this topic in the future: this will change when Java 8 is released and we move from Rhino to Nashorn as the underlying JavaScript engine. Under Nashorn, the file name is applied to the ScriptContext, rather than to the ScriptEngine itself:
ScriptContext context = new SimpleScriptContext();
context.setAttribute(ScriptEngine.FILENAME, "test.js", ScriptContext.ENGINE_SCOPE);
try
{
engine.eval(script, context);
}
catch (ScriptException e)
{
/* e.getFileName() will return "test.js" */
}
If you attempt to apply the file name using ScriptEngine.put(), as you do under Rhino, nothing will happen and your exceptions will return "<eval>" as the file name.
I would imagine that a few people will run into this issue in the coming months, so thought I'd offer it. This does not appear to be documented anywhere. I had to dig into the Nashorn source code to figure it out.
The Java 8 (Nashorn) way of setting the filename for the script engine through the ScriptContext figured out by mattj65816, works for the Rhino engine as well. So, I'd recommend using only
context.setAttribute(ScriptEngine.FILENAME, "test.js", ScriptContext.ENGINE_SCOPE);
since this piece of code works for both common JavaScript engines. You don't event need to create you own context, but only set the attribute to the engine's default context:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
if (engine != null) {
ScriptContext ctx = engine.getContext();
ctx.setAttribute(ScriptEngine.FILENAME, "test.js", ScriptContext.ENGINE_SCOPE);
...
}
perfect!
ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
// javax.script.filename
engine.put(ScriptEngine.FILENAME, "test1.js");
try {
engine.eval("function throwError1(){throw new Error('test, haha')}");
} catch (ScriptException e) {
}
engine.put(ScriptEngine.FILENAME, "test2.js");
try {
engine.eval("function throwError2(){throw new Error('test2, haha')}");
} catch (ScriptException e) {
}
try {
engine.eval("throwError1()");
} catch (ScriptException e) {
System.out.println(e.getMessage());
}
try {
engine.eval("throwError2()");
} catch (ScriptException e) {
System.out.println(e.getMessage());
}
output :
Error: test, haha in test1.js at line number 1
Error: test2, haha in test2.js at line number 1

How can a Java program get its own process ID?

How do I get the id of my Java process?
I know there are several platform-dependent hacks, but I would prefer a more generic solution.
There exists no platform-independent way that can be guaranteed to work in all jvm implementations.
ManagementFactory.getRuntimeMXBean().getName() looks like the best (closest) solution, and typically includes the PID. It's short, and probably works in every implementation in wide use.
On linux+windows it returns a value like "12345#hostname" (12345 being the process id). Beware though that according to the docs, there are no guarantees about this value:
Returns the name representing the running Java virtual machine. The
returned name string can be any arbitrary string and a Java virtual
machine implementation can choose to embed platform-specific useful
information in the returned name string. Each running virtual machine
could have a different name.
In Java 9 the new process API can be used:
long pid = ProcessHandle.current().pid();
You could use JNA. Unfortunately there is no common JNA API to get the current process ID yet, but each platform is pretty simple:
Windows
Make sure you have jna-platform.jar then:
int pid = Kernel32.INSTANCE.GetCurrentProcessId();
Unix
Declare:
private interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
int getpid ();
}
Then:
int pid = CLibrary.INSTANCE.getpid();
Java 9
Under Java 9 the new process API can be used to get the current process ID. First you grab a handle to the current process, then query the PID:
long pid = ProcessHandle.current().pid();
Here's a backdoor method which might not work with all VMs but should work on both linux and windows (original example here):
java.lang.management.RuntimeMXBean runtime =
java.lang.management.ManagementFactory.getRuntimeMXBean();
java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
sun.management.VMManagement mgmt =
(sun.management.VMManagement) jvm.get(runtime);
java.lang.reflect.Method pid_method =
mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);
int pid = (Integer) pid_method.invoke(mgmt);
Try Sigar . very extensive APIs. Apache 2 license.
private Sigar sigar;
public synchronized Sigar getSigar() {
if (sigar == null) {
sigar = new Sigar();
}
return sigar;
}
public synchronized void forceRelease() {
if (sigar != null) {
sigar.close();
sigar = null;
}
}
public long getPid() {
return getSigar().getPid();
}
The following method tries to extract the PID from java.lang.management.ManagementFactory:
private static String getProcessId(final String fallback) {
// Note: may fail in some JVM implementations
// therefore fallback has to be provided
// something like '<pid>#<hostname>', at least in SUN / Oracle JVMs
final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
final int index = jvmName.indexOf('#');
if (index < 1) {
// part before '#' empty (index = 0) / '#' not found (index = -1)
return fallback;
}
try {
return Long.toString(Long.parseLong(jvmName.substring(0, index)));
} catch (NumberFormatException e) {
// ignore
}
return fallback;
}
Just call getProcessId("<PID>"), for instance.
For older JVM, in linux...
private static String getPid() throws IOException {
byte[] bo = new byte[256];
InputStream is = new FileInputStream("/proc/self/stat");
is.read(bo);
for (int i = 0; i < bo.length; i++) {
if ((bo[i] < '0') || (bo[i] > '9')) {
return new String(bo, 0, i);
}
}
return "-1";
}
Since Java 9 there is a method Process.getPid() which returns the native ID of a process:
public abstract class Process {
...
public long getPid();
}
To get the process ID of the current Java process one can use the ProcessHandle interface:
System.out.println(ProcessHandle.current().pid());
You can check out my project: JavaSysMon on GitHub. It provides process id and a bunch of other stuff (CPU usage, memory usage) cross-platform (presently Windows, Mac OSX, Linux and Solaris)
java.lang.management.ManagementFactory.getRuntimeMXBean().getName().split("#")[0]
In Scala:
import sys.process._
val pid: Long = Seq("sh", "-c", "echo $PPID").!!.trim.toLong
This should give you a workaround on Unix systems until Java 9 will be released.
(I know, the question was about Java, but since there is no equivalent question for Scala, I wanted to leave this for Scala users who might stumble into the same question.)
For completeness there is a wrapper in Spring Boot for the
String jvmName = ManagementFactory.getRuntimeMXBean().getName();
return jvmName.split("#")[0];
solution. If an integer is required, then this can be summed up to the one-liner:
int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("#")[0]);
If someone uses Spring boot already, she/he might use org.springframework.boot.ApplicationPid
ApplicationPid pid = new ApplicationPid();
pid.toString();
The toString() method prints the pid or '???'.
Caveats using the ManagementFactory are discussed in other answers already.
public static long getPID() {
String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
if (processName != null && processName.length() > 0) {
try {
return Long.parseLong(processName.split("#")[0]);
}
catch (Exception e) {
return 0;
}
}
return 0;
}
I am adding this, in addition to other solutions.
with Java 10, to get process id
final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
final long pid = runtime.getPid();
out.println("Process ID is '" + pid);
The latest I have found is that there is a system property called sun.java.launcher.pid that is available at least on linux. My plan is to use that and if it is not found to use the JMX bean.
It depends on where you are looking for the information from.
If you are looking for the information from the console you can use the jps command. The command gives output similar to the Unix ps command and comes with the JDK since I believe 1.5
If you are looking from the process the RuntimeMXBean (as said by Wouter Coekaerts) is probably your best choice. The output from getName() on Windows using Sun JDK 1.6 u7 is in the form [PROCESS_ID]#[MACHINE_NAME]. You could however try to execute jps and parse the result from that:
String jps = [JDK HOME] + "\\bin\\jps.exe";
Process p = Runtime.getRuntime().exec(jps);
If run with no options the output should be the process id followed by the name.
This is the code JConsole, and potentially jps and VisualVM uses. It utilizes classes from
sun.jvmstat.monitor.* package, from tool.jar.
package my.code.a003.process;
import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.VmIdentifier;
public class GetOwnPid {
public static void main(String[] args) {
new GetOwnPid().run();
}
public void run() {
System.out.println(getPid(this.getClass()));
}
public Integer getPid(Class<?> mainClass) {
MonitoredHost monitoredHost;
Set<Integer> activeVmPids;
try {
monitoredHost = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null));
activeVmPids = monitoredHost.activeVms();
MonitoredVm mvm = null;
for (Integer vmPid : activeVmPids) {
try {
mvm = monitoredHost.getMonitoredVm(new VmIdentifier(vmPid.toString()));
String mvmMainClass = MonitoredVmUtil.mainClass(mvm, true);
if (mainClass.getName().equals(mvmMainClass)) {
return vmPid;
}
} finally {
if (mvm != null) {
mvm.detach();
}
}
}
} catch (java.net.URISyntaxException e) {
throw new InternalError(e.getMessage());
} catch (MonitorException e) {
throw new InternalError(e.getMessage());
}
return null;
}
}
There are few catches:
The tool.jar is a library distributed with Oracle JDK but not JRE!
You cannot get tool.jar from Maven repo; configure it with Maven is a bit tricky
The tool.jar probably contains platform dependent (native?) code so it is not easily
distributable
It runs under assumption that all (local) running JVM apps are "monitorable". It looks like
that from Java 6 all apps generally are (unless you actively configure opposite)
It probably works only for Java 6+
Eclipse does not publish main class, so you will not get Eclipse PID easily
Bug in MonitoredVmUtil?
UPDATE: I have just double checked that JPS uses this way, that is Jvmstat library (part of tool.jar). So there is no need to call JPS as external process, call Jvmstat library directly as my example shows. You can aslo get list of all JVMs runnin on localhost this way.
See JPS source code:
I know this is an old thread, but I wanted to call out that API for getting the PID (as well as other manipulation of the Java process at runtime) is being added to the Process class in JDK 9: http://openjdk.java.net/jeps/102
Based on Ashwin Jayaprakash's answer (+1)
about the Apache 2.0 licensed SIGAR, here is how I use it to get only the PID of the current process:
import org.hyperic.sigar.Sigar;
Sigar sigar = new Sigar();
long pid = sigar.getPid();
sigar.close();
Even though it does not work on all platforms, it does work on Linux, Windows, OS X and various Unix platforms as listed here.
You can try getpid() in JNR-Posix.
It has a Windows POSIX wrapper that calls getpid() off of libc.
I found a solution that may be a bit of an edge case and I didn't try it on other OS than Windows 10, but I think it's worth noticing.
If you find yourself working with J2V8 and nodejs, you can run a simple javascript function returning you the pid of the java process.
Here is an example:
public static void main(String[] args) {
NodeJS nodeJS = NodeJS.createNodeJS();
int pid = nodeJS.getRuntime().executeIntegerScript("process.pid;\n");
System.out.println(pid);
nodeJS.release();
}
Here is my solution:
public static boolean isPIDInUse(int pid) {
try {
String s = null;
int java_pid;
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
java_pid = Integer.parseInt(rt.getName().substring(0, rt.getName().indexOf("#")));
if (java_pid == pid) {
System.out.println("In Use\n");
return true;
}
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
return false;
}
This is what I used when I had similar requirement. This determines the PID of the Java process correctly. Let your java code spawn a server on a pre-defined port number and then execute OS commands to find out the PID listening on the port. For Linux
netstat -tupln | grep portNumber

Categories