Is Java capable of process monitoring? - java

Is it possible to write an application in Java that runs in the tray and when a certain application is launched, it can detect it? I want to do this for certain programs to find out how long I use them for a weekly basis. I'm new to Java, so I don't know if Java is even the best language for this, or if it has the proper access to the operating system to do this.

Java in itself does not have much integration into system-specific features (nor do most other general-purpose languages). If you're talking about windows, the system language of choice would be C# (or C/C++). On Mac, it'd be ObjectiveC (or C/C++). On linux, it'd be C.
To access process monitoring facilities on a given system, you need to first understand the APIs you're going to be using. Then you can evaluate whether a given language has built-in or third-party library support for those APIs.
In the case of Java, you'd need to either write some JNI (C code), use JNA (Java only), or parse the output of Runtime.exec() (call various system/shell commands) to access the system APIs related to managing and/or monitoring processes.

Related

Window manipulation using java

I want to make a program that would be able to manipulate the desktop based on user input commands (Preferably by voice, but... baby steps). Similar to Windows Speech Recognition, or Cortana.
I would like to make this as easy as possible to use and set up etc. For this reason I had planned on writing it in Java so that it would be cross-platform, and as simple as possible for users.
After looking further into how I would go about this, I saw mentioned here (Manipulating windows from other applications in Java) that I should use JNI.
I'm now wondering if (as mentioned in the top comment) it would be easier if I were to switch to C++ as using JNI might negate the cross-platform capability benefits of Java?
Or if possible, would it be possible to have the program select the appropriate JNI classes automatically based on the operating system?
In short: Does JNI negate the benefits of Java cross-platform compatibility?
Sorry if this post is a bit confusing. I've quite a few questions so this may seem a bit all over the place.
Many Operating System specific tasks cannot be done platform independent. But what Java already does a lot and JNI allows you to do too is that you can have different native binaries for different platforms - and possibly a single Java API to use all of them platform-independent.
Going C++ has the disadvantage that you need to have multiple executables. With Java you could have just 1 that loads different native code.
Although if you need a lot of different native code to implement your idea, maybe it's easier to just implement it for just 1 platform directly in a language that has bindings to all the required native APIs. Like maybe C# for Windows and something else for other platforms?

What is the meaning of "Java is portable"?

I'm confused about Java portability. If the Java language is portable, why is enum unknown in J2ME?
In C++, it's not important which platform or library is used. The "C++ language" doesn't change in all platforms.
My purpose is developing a Java library that just uses primitive types like int, String, or Array (something like a library for Genetic algorithms). I want to use this library in mobile and desktop applications. But it seems that enum and some other keywords do not exist in all platforms.
So I think I misunderstood the meaning of "Java portability". What does that mean?
There are three flavors of Java: ME for mobile, SE for desktops, and EE for enterprise.
"Java is portable" refers to the SE version. It means that you can run Java bytecode on any hardware that has a compliant JVM.
It doesn't mean that ME is the same as SE is the same as EE. EE has EJBs, but SE and ME don't. That does not make them less portable.
C++ language doesn't change in all platforms.
This statement is not strictly correct. Microsoft adds extensions to their C++ that won't run elsewhere.
ANSI C++ might mean portable source code, as long as you stay away from platform-specific extensions. It does not mean portable bytecode; you may have to recompile and relink.
You want to run genetic algorithms on phones? I know that mobile devices have become pretty powerful, but I'm educated to think that GA would be a server-side functionality. Mobile devices feel more like view to me.
Every hardware architecture has its own somewhat unique instruction set (add ax, bx...) when you build a C++ code, the compiler turns it into a machine code specific to the system/architecture you are working on. So you have to customize and build your code for different architectures for it to work on them.
But What happens in java is, When you build it, it is compiled into a Byte code (as opposed to machine code). And the java virtual machine(JVM) interprets the Byte Code into an instruction that is understandable by the specific architecture you the program is running on.
There is JVM for every major architecture and operating system so the code you write on windows will be interpreted and run on MAC-OS or linux without any source level modification by you.
That is why Java is portable and that is where the Write Once Run Everywhere motto comes from
Java is known as a "portable language" because Java code can execute on all major platforms. What's more, once you've compiled your Java source to "byte-code" .class, those files can be used on any Java-supported platform without modification, unlike many other languages, which require compiling "machine code" for each platform, e.g. a separate ".exe" for 32-bit vs 64-bit environments.
Another meaning of "portable", used mainly in Windows environments, means that the Java run-time environment can be run from any arbitrary location in your filesystem and does not need to be "installed", that is, have important information stored in the Windows registry. This is also true for most Java applications, and enables them to be run from different drive letters, via for example an external storage device like a USB flash drive from any computer without having to install the application first.
Java provides three distinct types of portability:
Source code portability: A given Java program should produce identical results regardless of the underlying CPU, operating system, or Java compiler.
CPU architecture portability: the current Java compilers produce object code (called byte-code) for a CPU that does not yet exist. For each real CPU on which Java programs are intended to run, a Java interpreter, or virtual machine, "executes" the J-code. This non-existent CPU allows the same object code to run on any CPU for which a Java interpreter exists.
OS/GUI portability: Java solves this problem by providing a set of library functions (contained in Java-supplied libraries such as awt, util, and lang) that talk to an imaginary OS and imaginary GUI. Just like the JVM presents a virtual CPU, the Java libraries present a virtual OS/GUI. Every Java implementation provides libraries implementing this virtual OS/GUI. Java programs that use these libraries to provide needed OS and GUI functionality port fairly easily.
See this link
While C and C++ language syntax and semantic are standardised, to write a truly cross-platform application is extremely difficult, unless you limit yourself to extremely basic applications.
There are a number of high level and low level reason for this - from the endianness up to how to interact with the underlying operating system (eg. opening a window).
In addition, C/C++ source code only can be considered portable, not the result of the compilation - resulting executable code and libraries are not portable, with major difference between system architectures (different CPUs for example) and Operating Systems.
Java is a fairly successful attempt to solve both of these issues:
Java does not compile code to assembly, but to a more abstract "bytecode" - a pseudo-assembly language which is "interpreted" or "recompiled on the fly" by the virtual machine (JVM) into assembly. This conversion is usually fairly efficient as bytecode is mostly quite a low level language. Some version of the ARM processor can even execute bytecode natively.
Thus, once a java app is compiled, the result can run on "any" architecture (provided a JVM is available for that machine)
Java comes bundled with a really large runtime library which provides not only an extensive implementation of the most common data structure (implemented in the JVM in the most efficent way for a particular architecture) but also provide an "hardware and software abstraction layer" - you can interact with the system in a standard way while coding, it is the JVM job to translate it into appropriate architecture and OS calls. As an example, Java provides the Swing framework, which allows you to create a GUI in a system independent way - ie, you open a window, and this is translated into Win32/MFC calls in Windows and XWin calls in Linux
Said that, there are different "types" of java:
JavaSE is the most common
JavaME is a cut down version with a limited library and not implementing the Java5.0 language changes
JavaEE for enterprise use, same as JavaSE but with a much larger runtime
Android Java, mostly compatible with JavaSE but with additional functionalities specific to android phones
However, you should be aware that the Java architecture has been designed to allow interoperability, in particularly to allow to mix libraries built for different versions or even different "types"
it means that your java program written on one machine will run on any other machine provided that machine has JVM.
refer to this link.
Portability refers to the ability to run a program on different machines. Running a given program on different machines can require different amounts of work (for example, no work whatsoever, recompiling, or making small changes to the source code). When people refer to Java applications and applets as portable, they usually mean the applications and applets run on different types of machines with no changes (such as recompilation or tweaks to the source code).

"Low level" project using Java

I'm wondering if it would make sense to do some low level or OS stuff (a project) using Java. Reason why I ask is because I would like to expand my knowledge in Java and I'm into doing stuff like file compressor, bulk file renamer, etc. Are there any examples out there that I can look at or play with? Or should I just be using C or C++ instead?
stuff like file compressor, bulk file
renamer, etc.
I wouldn't consider that "low level or OS stuff".
In my book, "low level or OS stuff" means things like device drivers. For that kind of thing, Java is very badly suited because it runs in a VM and simply does not have access to the OS API and the hardware (well, unless you run a Java-based OS).
For the two examples you name, Java could work quite well, but you could also easily run into limitations that are hard or impossible to overcome: Java's filesystem API dictates what you can do, and if that's not enough, the only thing left is to call native (i.e. C/C++) code via JNI or Runtime.exec().
I'm wondering if it would make sense to do some low level or OS stuff(a project) using Java.
Generally speaking, no. The low-level stuff is either taken care of by the JVM (or the operating system) or is impossible to do in pure Java.
However, if you are really interested in this kind of stuff, wander across to the JNode project and take a look at the various student projects on offer. JNode is a complete operating system that boots and runs on a "bare-metal" PC and is implemented (almost) entirely in Java.
Low level OS stuff is not very related to Java; Java uses a lot of abstractions (and hence making it higher level). You can, however, use the Java language and VM to interact with lower level API's using Java Native Access.
The problem with "low level" is: what is low level? Do you want to execute assembly instructions? And then there is Java: completely platform independent. Using more lower level API's in Java means that you lose the independency from your platform (think of: OS or hardware).
You can, however, also learn more about Java bytecodes: this is also quite low level.
If you provide more information on your project, I can give you a more specific answer.

I/O prioritization in Java

I'd like to use of the Vista+ feature of I/O prioritization. Is there a platform independent way of setting I/O priority on an operation in Java (e.g. a library, in Java 7) or should I revert to a sleeping-filter or JNx solution? Do other platforms have a similar feature?
If you really need to use this feature and you really want to do this in Java, you can always use Java JNI to hook the JVM into your own, custom C/C++ implementation of an I/O handler. It allows you to write native (OS specific) code and call it from a Java application.
This is the kind of thing that is difficult for Java to support because it depends heavily on the capabilities of the underlying operating system. Java tries very hard to offer APIs that work the same across multiple platform. (It doesn't always succeed, but that's a different topic.)
In this case, a Java API would need to be implementable across multiple versions of Windows, multiple versions of Linux, Solaris, and various other third party platforms. Coming up with a platform independent model of IO prioritization that can be mapped to the functionality of the range of OS platforms would be hard.
For a now, I suggest that you look for a platform specific solution that goes outside of Java to make the necessary tuning adjustments; e.g. use Process et al to run an external command, or do the work in a wrapper script before starting your JVM.
From a google search it does not seem that Java supports IO Prioritization yet.
Windows Vista does but I don't know anything about it. Is it per process or more fine-grained?
Linux since 2.6.13 supports ionice(1), which will set IO priority on a per process basis.

Java runtime vs OS calls

The Java runtime provides a set of standard system libraries for use by programs. To what extent are these libraries similar to the system calls of an operating system, and to what extent are they different???
Half the point of java was to make it platform independent, so what it tries to do is provide an api that remains the same regardless of the OS underneath it.
If the OS is underpowered, Java will add library code to compensate for it.
If the OS has an implementation that doesn't map, Java will do it's best to map it.
If a new function becomes popular and Java users need to provide access to it, a new library can be created through which you can access the new functionality. If this library is popular, it will be restructured and added into the Java SDK at some point
For instance, an implementation of some concurrency libraries became popular, and soon they were voted upon and added to the standard libraries. This happens all the time.
That obviously depends on the OS you're running on, since the system calls are generally different for every OS :-).
That said, I believe Java was mostly inspired by Unix conventions (not surprinsingly, as Sun is a Unix vendor), so some Java system libraries are similar to Unix sytem calls.
E.g. java.nio.MappedByteBuffer was probably inspired by Unix's mmap() call. But ultimately most concepts are present on most OSes, so you cannot really say what inspired what.
Some of Java's "low-level" functions are basically "wrappers" around some OS
system calls.
I don't see an objective way (and reason) to "compare" both.
If you are interested in this topic, you can search the Java source code
for the native keyword, which indicates some "hidden"
(mostly OS-dependend) functionality.
Java's standard library often has a similar feature set compared to the native library but there are several important differences.
Java is Object Oriented, whether you like it or not. The advantage of this is that certain concepts are easier to manage. For example, most file related operations are found directly in the File object. Compare this to Posix, where a FILE is a handle which is really just a number; an index into your process's open file list. The Posix approach is very close to how the OS actually implements stuff. But in Java you don't see that or know it or care.
Java has certain lowest-common-denominator behaviours in certain cases. There are many AWT APIs that are the way they are because AWT needed to be identical on a number of separate platforms. That turned out to be madness, and Sun quasi-deprecated most of AWT, because supporting platform equally meant supporting every platform crappily. The newer library, Swing, implements almost everything in pure Java, and thus is far better at cross-platform stuff, and thus has a richer API. And that API is very different from the native windowing library. Also, Swing doesn't integrate too well because it uses so little of the native OS.
Java has certain limitations that the native libraries don't have. For example, you don't have function pointers. Thus you have Listeners and Runnable and other Java patterns for doing things that in C++ would involve function pointers. So any API that needs one of these features will be significantly different in Java than in the native OS.
So in conclusion, Java often has libraries that offer similar behaviour to the native OS, and sometimes offer completely different behaviour, but it's best to think of Java as a platform in its own right. Sometimes you need advanced performance, such as OpenGL or super-fast data transfer, in which case you'll want a specific Java API (Jogl, nio), but most of the time you should evaluate Java as its own thing.

Categories

Resources