Is there a java sdk for cygwin? - java

Is there a java sdk for cygwin?

It would be nice if there were a native cygwin implementation which used the cygwin file system and X-windows for display, unfortunately I am not aware of such a release. I would assume it is quite an effort to port OpenJDK as well, but I haven't tried.

Although there is no java sdk for cygwin, you can get the Windows jdk to work if you are willing to accommodate workarounds for various problems:
some cygwin paths are not handled as expected by java programs
the file path separator is backslash rather than slash
the PATH entry separator is semicolon instead of colon
In my experience, the first bullet is by far biggest problem, although the three are somewhat inter-related. The separators tend to take care of themselves as a side-effect of solving the first problem.
All three problems are largely resolved by setting up a development environment in which all file paths of interest (as viewed by java.io.File and java.nio.Path, etc.) can be represented without specifying a drive letter.
As it turns out, it's rarely necessary to use backslashes in a file path string under windows. The only exceptions to this rule that I have encountered are when passing file path strings as parameters when spawning a command line for a program that require backslashes (e.g., CMD.EXE). The java.io and java.nio packages all accept forward slashes, and so, for that matter, do the Microsoft development libraries. Most programs that reject a path with forward slashes are (IMHO) likely to be doing so gratuitously.
So, the real problem is that "/cygdrive/c" is not recognized by java.io.File as referring to "C:\".
In other words, the following file test will return false:
new java.io.File("/cygdrive/c").exists()
whereas this works as expected:
new java.io.File("c:/").exists()
Recent versions of Windows now support general symlinks, providing a way to setup a cygwin development environment in which drive letters are not used. With a unified view of the entire filesystem (with all files appearing below "/", the default drive letter being invariant, e.g., C:) , the drive letter can be discarded from file path strings. In other words, you want to be able to refer to "c:/" as "/". This can be accomplished in various ways, one being to symlink other drives below c:/, for example:
$ ln -sFT d:/ c:/d
If env variable CYGWIN contains "winsymlinks:native", this will create a Windows symlink, with the result that (assuming c: is the default drive) your java program will correctly recognize the string "/d" as referring to "D:\", so you can do this:
new java.io.File("/d").isDirectory // returns true, as expected
If you are unable or reluctant to modify you cygwin environment, there is another approach, which is more universal. You can extend java.io.File and override constructors and various methods to (in effect) to translate cygwin paths to their windows equivalent (like cygpath -m or -w), and to translate windows path strings to a more POSIX-like format. I have such a library (written in scala, but usable from java) and intend to make it available, hopefully sometime soon.

Related

How to change / to \\ in the path to jvm.dll

I thought which title to choose for 30 minutes, because my problem is rather strange.
Suppose we have a C++ native dll (C.dll). I want to load this dll with the help of JNA into my java project. Now what's important: in C.dll there is widely used a file path, from where this dll was called. And there is literally an if-statement like this:
if (filepath[2] != _T('\\'))
{
//throw an arror and close dll loading
}
If I try to load this dll via JNA, it throws an internal dll error with the following message: "There is missing a certain sign '\' in: "C:/Program Files/AdoptOpenJDK/jdk-14.0.0.36-hotspot/bin/client" on position: 3"
I know the nature of that error and I also understand, that this if-statement is really silly, because it is absolutely anti-crossplatform, but I couldn't change C.dll, because it has come from 3rd party, well, you know that story.
What is also problematic - I couldn't just replace this file path parameter somewhere (f.e. via some other wrapper.dll or so), call then this wrapper via JNA and be happy, because all that file path checking inside C.dll is harcoded with the help of multiple macros and it is implied, that all the routines of receiveing and checking this file path are occured fully automatically (this is actually provided by other dlls, which C.dll have to use, and for which I don't have a source code, yes, it is that bad). So it is not so easy to find a concrete value which I could directly replace.
So, my question is: is it somehow possible to replace those (/) to double (\) backslashes in file path of jvm.dll in runtime or so? Is it possible to write a wrapper.dll, that will do it for my C.dll, either in C++ or java? I need to run this finally in JNA, that's actually why the file path is exactly JAVA_HOME or so - because as far as I understood java virtual machine is exactly the process, who loads C.dll in that situation, that's why I got the path to jvm.dll as a wrong file path. AFAIK all the java paths are harcoded with (/) in JDK, so from the JNA's side it is not directly possible in my opinion. But is it possible generally without changing original .dll? Maybe there exist something like path-replacers tools for java in Windows or so?

Cygwin Could not find or load main class edu.stanford.nlp.patterns.surface.GetPatternsFromDataMultiClass

Hi,
I am trying to run the SPIED viz master demo of the Stanford Library that helps train the model on our own language tags. I am running this on Windows 7 with Cygwin. According to the documentation I got the setupWithCoreNLP.sh to work which put all the required jar files and other dependencies in the right folds and path. Now when I run demo.sh I get the main class not found error. I corrected the home path in the demo.sh file but I am not sure what else to fix to make this demo work.
Any help would be greatly appreciated.
There are two problems using java for windows under cygwin:
java for windows use ; as jar separator (: is used for drives), while java for POSIX systems use :
java for windows does not understand cygwin pathnames, like /cygwin/c/Users/.... Please, take a look at this article, which explains how to handle cygwin POSIX pathnames while using windows programs, like java. This one can also be useful, although is more general.
In your case, I'd do something like:
java -cp $(cygpath -wp ./stanford-corenlp-3.5.1.jar:./stanford-corenlp-3.5.1-models.jar:./javax.json.jar:./joda-time.jar:./jollyday.jar) edu.stanford.nlp.patterns.GetPatternsFromDataMultiClass -props patterns/example.properties
You'll have to change jars paths according to the appropiate directory.
I mean, if stanford-corenlp-3.5.1.jar is located in C:\Users\k.shwetika\Desktop\NLP\SPIED-viz-master\SPIED-viz-master, then change ./stanford-corenlp-3.5.1.jar to
/cygdrive/c/Users/k.shwetika/Desktop/NLP/SPIED-viz-master/SPIED-viz-master/stanford-corenlp-3.5.1.jar.
The same for the other jars.
Lastly, I assume edu.stanford.nlp.patterns.GetPatternsFromDataMultiClass is within any of these jars.
UPDATE
I think, instead of using cygpath command to convert POSIX pathnames to windows pathnames, you can also use windows pathnames escaping jar separator ; (ie: \;), but I not completely sure.
For example
java -cp win_path\jar1.jar\;...\;win_path\jarN.jar MainClass
Hope this helps!

Remove (absolute) paths in ANTLR generated java classes:

I am using ANTLRWorks 1.4.3 together with ANTLR 3.4 to generate a Java-based parser and lexer from a grammar file. The generated .java-files contain strings like
C:\\Users\\[path to the eclipse project]\\src\\some\\package\\name\\MyGrammar.g
This absolute path is used as
return string e.g. in method getGrammarFileName() of lexer and parser, and
throughout the both files various times as comment.
I see following disadvantages:
If somebody else with different paths in his development environment will regenerate these files, a lot of changes will be introduced even if no changes in the grammar file were done.
Nobody, especially in an open source project, needs to know where I exactly store my grammar files. E.g., what about C:\\Users\\simon\\customerA\\crap_software\\[rest of the path to grammar file]
Is there a way to control this in ANTLRWorks or ANTLR s.th. at least only relative paths are used?
Finally I found a way to solve my own problem.
Paths seem to depend from where and how you invoke ANTLR. I was not able to achieve this with ANTLRWorks, but using command line ANTLR you are able to perform this. You can do the following (example is for Windows but should be reproducible on other OSes, too):
Download Antlr for command line and copy it to e.g.
C:\Program Files (x86)\ANTLRworks\antlr-3.4-complete.jar.
Open a Windows command line (cmd.exe) and change to the directory where your grammar file is located:
cd C:\Users[path to the eclipse project]\src\some\package\name
Invoke
java -jar "C:\Program Files (x86)\ANTLRworks\antlr-3.4-complete.jar" MyGrammar.g
from commandline.
The generated java files will only contain the name of your grammar file and no path anymore.
Is there a way to control this in ANTLRWorks or ANTLR s.th. at least only relative paths are used?
Short answer
No.
Long(er) answer (Containing highly subjective views! Proceed at own risk)
This is target-specific, but, AFAIK, no target allows you to specify the type (absolute or relative) of the path.
The "no" might be because getGrammarFileName() is only used while debugging generated lexers/parsers. And one should probably not check in generated source files into source control, so no one would ever see the path you see in your generated source file. One ought to check in the grammar, and let developers generate their own lexers/parsers from it.
Again, this is all speculation on my part.

Java are there any known libraries for directory tab completion?

I would like to create a program in a linux/unix environment that runs from command line. The desired outcome would be to have the ability to tab complete directories. Are there any libraries available to achieve this?
Synopsis: /ho
[tab] /home/
There exists a JNI wrapper for the GNU "readline" library (which is what Bash uses for tab-completion); see http://sourceforge.net/projects/java-readline/. Tab-completion is a generic feature, not specifically tied to the filesystem — for example, the PostgreSQL command-line client uses tab-completion to complete table-names — so you'll probably want to use this in concert with the PrefixFileFilter that Tomasz Nurkiewicz mentions (or another similar approach for generating the list of filenames).
PrefixFileFilter from apache-commons IO might be helpful:
File dir = new File(".");
String[] files = dir.list(new PrefixFileFilter("ho"));
This will return a list of files in current directory starting with ho. You'll get the rest.
I don't think you need a library for that, just code it your self. File class already contains everything needed like:
File[] listFiles()
boolean isDirectory()
boolean isFile()
...
Then you just need to create:
take the temporary path, eg "/home/Ja"
split it between last concrete part and part to complete, /home and Ja
list files from concrete part new File("/home").listFiles()
and select only currently correct for partial file.getName().startsWith("Ja")
I guess it will be around 50-100 LOCs including all the checks necessary to avoid weird things.
If you want a good approach, use FilenameFilter, so that you will be able to filter out files directly when invoking listFiles, eg
files = folder.listFiles(new PartialFileFilter("Ja"))
Are there any Java libraries to create command line applications with TAB completion of directories?
You may be interested in picocli. Picocli is a 1-file Java library for building command line applications with almost zero code; it can generate ANSI colored usage help messages, and picocli supports command line autocompletion on Linux (and Cygwin and babun on Windows) since version 1.0.
How does this work? The bash and zsh Unix shells provide something called "programmable completion", and picocli leverages this to generate an autocompletion script tailored to the #Option and #Command annotations in your application.
With this script installed, users can type the TAB key, and the Unix shell will show a list of the available subcommands and options. For options associated with a java.io.File or java.nio.file.Path field, the shell will show the available files and directories that match what the user typed so far.
This actually handles more than just files and directories: the picocli-generated completion script shows known hosts (from the user's /etc/hosts file) for options of type java.net.InetAddress, and shows enumvalues for options on fields of any enum type, including custom enums.
The below animation demonstrates what is possible.
You can use a recent JLine version.
The latest one is available from https://github.com/jline/jline3.
It provides built-in completers for directories and files.
JLine is probably no longer maintained, but there are still quite a few Java projects that use it:
http://jline.sourceforge.net/index.html
However, if you know what you want to use Linux/Unix, and the only completion you want is simple file/directory names, you could just shift the problem and run your Java app under rlwrap:
$ rlwrap -c java ...

Why do we add a semicolon in Java PATH variable and not for the JAVA_HOME variable?

I have a very basic question to ask, that why do we need to add a semicolon at the end of PATH variable and why don't we add semicolon in JAVA_HOME variable?
I read lot of books and forums:
To separate different paths in PATH variable? or to tell the system or JRE not to look any further after that.
JAVA_HOME variable is to help the JRE to look for more files and extensions like JDBC drivers etc. in future development.
JAVA_HOME is used to specify a single directory. PATH specifies several directories, so you use a semi-colon to separate those directories.
JAVA_HOME is the location of the JDK or JRE installation. Many Java related libraries and files are stored here. It is a single location, not a set of locations and therefore there is no need to use a ';' to separate locations.
The PATH and CLASSPATH variables specify multiple locations, and therefore use ';' to delimit the entries.
Note that ';' is specific to Windows.
PATH is an operating system-specific idea. It just means, "when I type a command, check these paths as well". The current directory you are in is usually on the searched paths by default. If you think about it for a minute, you can easily imagine how much of a pain it would be to use a command line if you didn't have the idea of PATH.
So, given a PATH (with multiple directories), you need a way to separate the entries. Each operating system can use whatever character, but the two most popular are semi-colon (on Windows) and colon (on most systems Unix, e.g. Mac OS X).
JAVA_HOME just points to wherever your preferred Java installation is located. One value, so no need for a character to separate entries.
As an aside, you'll also run into CLASSPATH, which is the paths of all of the libraries (JARs) and resources (e.g. property files) your Java app is loading. CLASSPATH uses the same format/characters as PATH.
As an exercise, try writing a little bit of code that loops over and prints out the values of System.getProperties() and System.getenv(). It's a great way to see all of the little configuration elements.
A semicolon is the delimiter; it separates multiple items in a path.
JAVA_HOME only points to one place (the JDK/JRE directory)
Your PATH (or CLASSPATH) can encompass many locations.
That being said, putting a semicolon at the end of a path doesn't do anything and is ignored.
(Note that this is a colon in *nix rather than a semicolon)
JAVA_HOME is the root directory of JDK/JRE. On my system, JDK_HOME is:
C:\program files\java\jdk1.6.0_24
Since the command line tools (java, javac, jar, etc) are located in the bin directory, you puth %JAVA_HOME%\bin on the PATH, and not %JAVA_HOME% itself...

Categories