Package them all! Perl, python, java for naive users (in windows) - java

I have several scripts written in perl, python, and java (wrapped under java GUI with system calls to perl & python). And I have many not-tech-savy users that need to use this in their windows machines (xp & 7).
To avoid users from installing perl,python,and java and to avoid potential incompatibility between various versions of these interpreters, I'd like to make a local copy of these interpreters in a folder and then calling them. I'd zip the whole folder (which would also contain my code) and send it away.
I'd have to worry about environment variables and make calls to the correct interpreter (especially when other versions of python,java,perl may exists in their current system), but not sure what other problems I may face. Any better ideas?
I never used jython and do not know the overhead of moving to it. I also suspect a complex python system, with many files and 3rd party modules will have problems. Same with perl scripts and I don't know a robust perl interpreter callable from java.
Thank you, in advance.

Try Portable Python and Portable Perl. You can unzip them into your application tree and they should work.

Why don't you try migrating your perl/python code into java and then packagin everything into a nice webstart application? What do perl/python offer that java doesn't support?
For perl you can use something like perl2exe and for python py2exe so you can have 2 exes (which would include all the necessary interpreter bits) and invoke them as resources from within java? Or unzip them inside user's home directory and call them again as normal external programs (ProcessBuilder ?) ?

Related

running java code form terminal getting error

I found some reference that says I can add #!/usr/bin/java --source 12 at the beginning of the file and run the file directly from the terminal.
I am able to run using this on my local machine, however, when I tried the same on Github action I'm getting the error error: invalid value for --source option: 12
I'm not really an expert in shell scripting or java, can someone help me understand what this --source means is it the java version, I tried setting up the same version (jdk18) on Github action but still did not work.
java (the runtime executable) can only run class files. Until, that is, java12, where a normal JDK distribution (and not the bizarro JREs that some packagers like Azul publish ^1) has a java.exe that can run java files straight up. It's simple sugar - the compiler is still involved, of course. It's just that java will execute it for you.
You don't need --source 12; just java MySourceFile.java is fine. Edit that comment at the top of your source file, it should just be #!/usr/bin/java. The thing you do need is that java on your command line PATH is a java v12 or higher, and it is not. There isn't anything your java source file can do about this, you're going to have to impose on your users to have at least java12 installed or this simply does not and can not be made to work. It looks like you're on some linux distro or other; apt or yum or snap or whatever package manager you have will tell you how to fix this: Install java17, and uninstall the rest or use java-alternatives or whatever mechanism your package manager has to set the default executable (the one /usr/bin/java links to). Read the documentation of the package supplying java17, possibly following some links to the generalized java infrastructure package, it should tell you.
Mostly this is a red herring, this just isn't how java files are distributed. It's virtually pointless because:
Java is not a language that tends to be used for quick shell script-esque things. Such things tend to be self-fulfilling prophecies: Because nobody does this, library authors aren't thinking about it when they develop their APIs and the users of their libraries won't file enhancement requests for this either. Because common libraries aren't convenient when used for quick off-the-cuff shell scripts, java isn't used for it, thus perpetuating the cycle.
Any serious java app would definitely involve packages, dependencies, and more - and such apps cannot be run like this.
Class files are as platform agnostic as source files are. There is no sane reason to distribute java-written shell-script-esque tooling as a source file instead of a jar, except for off-the-cuff editing off them, which gets you right back to point #1 and #4.
The java core APIs work on a model of lowest common denominator: If there is a major OS that cannot or doesn't work in a certain way, then java simply does not expose this at all. For example, on all posix systems (i.e. pretty much every major OS except windows), you have your usual TERM, KILL, HUP, etc signals. Java core libs don't let you interact with them (unless you dip into hidden sun.misc.* API which doesn't reliably work in the first place). This makes java extra unsuitable for quick command line scripting where you want a different model: If at least one OS can do it, the language should have a library for it, and that library should simply fast-crash if you attempt to use it on an OS that doesn't support it. One easy way around this is a third party library that adds support for OS-specific stuff, but your model of distribution (stick #!/usr/bin/java at the top and distribute a source file) cannot include dependencies.
Java as a runtime model is mostly focused on running things eventually very quickly, at the cost of starting off slowly. This is fantastic for web servers which need to run efficiently but will be running for quite some time. It's utterly unsuitable for shell scripting, though.
CONCLUSION: You don't want to stick #!/usr/bin/java at the top even if you could make it work.
[1] A JRE is a java distribution without compilers and other development tools like jstack. These cannot run java SomeSourceFile.java, obviously; they do not have a compiler. However, JREs died - there are no JREs anymore; JDK8 is the last one that shipped with an official JRE. The JRE serves as a distribution model: The end user installs a JRE, and you ship your jars to them. This model is obsolete (you are now responsible to get something that can run your class files on the deployment machine), and therefore JREs died. However, some packagers of OpenJDK builds, such as Azul, still publish them, confusing matters. Hence, 'bizarro'. Azul and co have relatively good reasons for doing it, but, you shouldn't be using these unless you really know what you are doing.

How to use NLTK in Jython, or PY4J cross platforn?

I have two questions, this could go into different directions based on opinion, but as of right now I am writing a Java/Kotlin API. So far it is compatible across all platforms, excluding IOS(have not tested).
A few of the tasks it runs is python using PY4J but the way the API calls the python script to start the PY4J connection is
Runtime.getRuntime().exec("python script.py") # Is there a better way to do this?
Which is fine until it comes to Android. Will Android be able to use this method? If so, the question is answered and finished there.
If not, is there a way to embed a python interpreter into a JAR file? Java project?
I like Jython, but I could not get NLTK to work with it.
1) Is there a way to make Jython work with NLTK : If not,
2) Is there a way to use PY4J in Python?
3) Is there a way to embed a custom Python interpreter in Java/JAR?
Feel free to edit my question, code and title. I don't do this much, so it is probably sloppy.
This was silly, but I will keep it up since this was a real question. You can install python3 directly into the JAR. When the python installation screen shows up you can just install it into a folder inside your Java project.
For the Android part, there is a python package called p4a, python-for-android. You can create a python interpreter with dependencies. This should work.

How to package all required libraries with .so file linux

I am attempting to port an application that was written with a combination of c++ for the back end, and java for the front end. This application relies on the library opencv 2.4.13, which is outdated, as well as multiple other libraries. The concern i have is that i do not want the end user to need to install these dependant programs, as they have been proving challenging to install on any but a select few linux distributions. I believe the term i am looking for is statically linking, but i'm a bit unfamiliar with c++ compilation at the moment, so i am unsure the steps i need to take to make these files portable. The java application requires these files to be libraries, and while i have managed to get them to compile on one machine, the problem seems to be getting them to run on a different one after compilation.
Don't bother - this might also give you licensing problems, depending on what libraries you need.
Instead, just figure out what platforms your application is supposed to run on and package the libraries for each platform with your jar - or download them at startup, or provide them as a separate package. The exact mechanics you choose depend on your use case, the point is you don't need to rely on system wide installs.

How do I know whether my Java application uses "native code"?

On a recent question, I got comments asking whether I was using "native code" in my application. Now, I know that there is some way to call code in traditional binary libraries (DLLs, SOs) from inside a Java application using a thing called "JNI". I have read that Wikipedia entry but I never used this.
I am using a number of libraries, some of which may or may not use native code. How do I find out if they do? I did not have to install any SOs (running on Linux), but I guess that doesn't mean the libraries are not using any? Do I have to browse through all the documentation (which varies greatly in quality between libraries) or can I do some analysis on the JARs?
Usually using libraries that require JNI requires some additional setup (like putting .dll or .so files in the right places or setting the java.library.path System property).
If you did nothing of that, then chances are that you're not using JNI anywhere. This is also somewhat likely, as only quite specialized libraries require JNI.
However there's also JNA, which is a wrapper around JNI which simplifies its usage and which sometimes makes it unnecessary to do any explicit setup. If that's used by one of your libraries, then it's harder to detect.
If you get a crash dump, then checking that for any non-standard libraries can give a hint if a user-loaded native library is to blame.
To nitpick, every single Java application uses JNI indirectly at least. For example, System class contains several native methods, which map to the native JRE (as can be seen from its source code).
Whether your program/libraries use (directly or indirectly) some other native functions than those contained in the standard JRE, is indeed hard to detect. The .dlls / .sos may be packed into the .jar, to be extracted only when needed, so not having to install native libraries doesn't guarantee that it doesn't use any. It should usually be stated in the library documentation, though, because the vendor probably won't provide binaries for every imaginable system that Java runs on. But to be sure, I think the only way is to scan through the source code for native methods.
If a java library (jar) uses a native library (dll on Windows or so on Linux) the chances are that it is a system wide and well known library (such as glibc on Linux) or a custom one. In the last case it is common to pack it within the jar, so you can just open it up with a ZIP decompressor (i.e. 7zip on Windows will do fine) and browse the files. You should see dll files if it is targeted to Windows, so files if targeted to a Unix platform, or even both. The native library files usually are left at the root level of the jar.
If the jar uses custom libraries but it is packed along with an application it is common to leave the native libraries in an external folder with other application files (in this case there is no consensus). In this case you should look for the application launcher (a bat / sh file) or the configuration file if the lanucher is binary (an ini / conf file) and find out the JVM configuration (where java.library.path points to).
Probably the easiest way of doing this is using jmap or pmap to show which .so (shared object) files are mapped into your Java process. If there's anything other than stuff that's in /lib, /usr/lib or the Java lib directory it's a JNI suspect. You can also look at the /proc entry for the Java process under /proc/<pid>/maps. See the following manpages:
http://linux.die.net/man/1/jmap-java-1.6.0-openjdk
http://linux.die.net/man/1/pmap
http://linux.die.net/man/5/proc

Running Java, Python, Ruby and Perl programs in .NET

I've .NET framework 3.5 installed in my laptop. Just .NET alone, no Visual Studio. How can I run Java, Python, Ruby and Perl programs from the console?
Do I need to install something else also, for running these language files?
In case there is a need for something extra to be installed and after i have all of them, what are the commands that I need to type in the console to run these programs?
Do you want to run programs in these languages inside the .NET platform? You'd need IronPython or IronRuby (I don't think anything like IronPerl exists).
If you want to run "normal" Python/Ruby/Perl/Java programs, then yes, you'll need to install a Python interpreter, a Ruby interpreter, a Perl interpreter and a Java VM.
Perl is a bit of a problem, see this SO question. IronRuby and IronPython cover those two languages. For Java, I think you need Microsoft's J# (but I'm not entirely clear on the "visual vs not" situation for that product).
None of those languages are supported natively with .NET. You can try IronPython or IronRuby for those languages, but to run Java or Perl I think you'll actually need to download and install a Java VM and a perl interpreter.
There's no practical common virtual machine or binary for the options you list. You will require a separate install for each of these (note that all are unrelated to .NET)

Categories