This has really got me baffled.
In my Eclipse workspace I have a project called "Java scratchpad". In "Package Explorer" you see "src" (Source Folder) under this and then "root" (Package). Under "root" is a .java file called "LoggingTest.java".
So the path to this java file is "G:\My Documents\software projects\workspace\Java scratchpad\src\root\LoggingTest.java".
When I run the following code in Eclipse:
Path currentRelativePath = Paths.get("");
String s_currRelPath = currentRelativePath.toAbsolutePath().toString();
String pathWithForwardSlashes = s_currRelPath.replace( "\\", "/" );
System.out.println( "path " + pathWithForwardSlashes );
The result is
path G:/My Documents/software projects/workspace/Java scratchpad
But... when I am running the same piece of code at the Command Prompt I have to start in the following directory:
G:\My Documents\software projects\workspace\Java scratchpad\bin
... and then go > java root.LoggingTest at the prompt.
The output from the above bit of code is then:
path G:/My Documents/software projects/workspace/Java scratchpad/bin
In other words, when you run the thing at the Command Prompt you are running a .class file under the \bin directory, but when you run in Eclipse, the Eclipse framework "pretends" that the bin directory doesn't exist.
And the upshot is that I get different values for the "current relative path" (CWD) depending on whether I'm running in Eclipse or at the Command Prompt. If I want to make or use a directory relative to the CWD I'm going to get different values depending on whether I'm running in Eclipse or at the Command Prompt.
I'm feeling quite slow tonight. What should I do? Is there a way of detecting whether a project is being run in Eclipse or at the Command Prompt? Or should I simply try to detect whether the path ends in "\bin" and remove those four characters to make the paths equivalent?
later
Just adding a note in reply to the comment from E-Riz:
It's a simple thing: I want to create logs and I want to create Lucene indices... and to keep things in one location (at this stage anyway) I just want to put this output in a location such as ...\Java scratchpad\output\indices\[name of index] or, respectively, ...\Java scratchpad\output\logging\[name of log].
And, yes, of course at present I do know the absolute path involved here... however, as the name suggests, this is a "scratchpad" or test area... so then this code which uses the CWD to determine where to put or find logs or indices can be used more generically, without having to know the absolute paths involved.
But it has to work either in Eclipse or at the command prompt...!
NB my current workaround is indeed to check whether pathWithForwardSlashes ends in "\bin", and if so to delete these last 4 chars. I can't be the only person to have encountered this oddity. Bet there are cleverer solutions!
There's a couple of facts that you should know or keep in mind:
At runtime, Java can (should) be given a classpath to work with; the default application classpath is just . (the current directory where java was invoked from). That's why it seems to you that you must run your program from the \bin directory of your project; because you haven't told the JVM anywhere else to look for classes. You should be setting the runtime classpath when running your application, which can be done a variety of ways but for simple programs is often done via a batch file or shell script. Note that using -cp to specify the classpath will be crucial when you depend on any JARs.
In Eclipse, since applications aren't run via a command-line, Eclipse has Launch Configurations that encapsulate all the details necessary for launching a program (in "run" or "debug" mode). Here's a decent tutorial (although a bit dated; you can find lots more info about Launch Configurations out there on the Interwebs. The key piece of configuration you're looking for is on the Arguments tab, where you can specify the working directory for a program launch config. The default is the project's root directory. See how that's different than when you've been running your on command line? That explains the difference you're seeing in output. You could change the working directory in the Eclipse Launch Configuration, but I tend to prefer to keep it as the project root.
So, you have a couple of options to make things consistent: use a script/batch to run your app on the command-line, specifying -cp so the JVM knows where your class files are (and any other JARs it might need down the road, too); or, reconfigure your Eclipse launch to match where you run from on the command line. I think the (by far) preferable option is the first one.
Having said all that, you should usually not need to do any path manipulation at all when it comes to files/resources in Java. Everything is relative to either the current working directory where Java was run from, or the classpath.
Related
Can anyone please post detailed, step-by-step instructions how to install Saxon (10 HE) and how to run a transformation from the command line in MacOS (10.13.6)?
I have installed Java on my computer.
I have downloaded the SaxonHE10-6J.zip file from SourceForge.
Based on the recommendation here I have placed the saxon-he-10.6.jar in the myUserName/Library/Java/Extensions folder.
I then opened the Terminal application and entered a command based on this answer:
java -jar saxon-he-10.6.jar -'/Users/myUserName/Documents/path/to/mystylesheet.xsl' -s:'/Users/myUserName/Documents/path/to/some.xml'
This results in:
Unable to access jarfile saxon-he-10.6.jar
All my attempts, including moving the .jar file to the /Library/Java/Extensions directory or including a full path to the .jar file within the command failed with the same error message.
Please note that I am not a Java developer and I do not intend to use this in an application. All I want is to be able to perform an occasional transformation.
I should also note that the locations of my XML and XSLT files may change from one case to another. I would like to be able to keep the .jar file in a constant location and supply the paths to the XML and XSLT files as required - IOW, I want to have a command template where I only need to change the 2 filepaths (and possibly add some options to the transformation).
What do I need to do?
Eventually I got it working. Although these are not exactly the detailed, step-by-step instructions I was hoping for, I will summarize here what I have learned so far. Hopefully this will save someone the hours of frustration I had to go through.
Make sure you have Java installed on your computer. If not, download
from Oracle and install.
Download Saxon from SourceForge. Unzip and place it anywhere on your
hard disk, except:
do not place it in /Library/Java/Extensions or in myUserName/Library/Java/Extensions;
do not place it within a folder whose name contains a / (see below for description).
To initiate a transformation, make your command:
java -jar 'path/to/saxon-he-10.6.jar' -xsl:'path/to/mystylesheet.xsl' -s:'path/to/some.xml'
Alternatively, you can use:
java -cp 'path/to/saxon-he-10.6.jar' net.sf.saxon.Transform -xsl:'path/to/mystylesheet.xsl' -s:'path/to/some.xml'
This form can be also used to run XQuery by changing
net.sf.saxon.Transform to net.sf.saxon.Query.
For adding more options and/or parameters to your command, see the
instructions given here:
https://www.saxonica.com/html/documentation10/using-xsl/commandline/
but do not follow the instructions at the top of the page regarding
the form of the basic command.
Corrections/additions are most welcome.
Description of the problem with folder name containing /:
Put all 3 files (saxon-he-10.6.jar, mystylesheet.xsl and
some.xml in a folder named XML/RSS in my Documents folder;
Ran the following command:
java -jar '/Users/myUserName/Documents/XML:RSS/saxon-he-10.6.jar' -xsl:'/Users/myUserName/Documents/XML:RSS/mystylesheet.xsl' -s:'/Users/myUserName/Documents/XML:RSS/some.xml'
Received the following error:
Error: Could not find or load main class net.sf.saxon.Transform Caused by: java.lang.ClassNotFoundException: net.sf.saxon.Transform
Moved only the .jar file to the parent folder and ran the following
command:
java -jar '/Users/myUserName/Documents/saxon-he-10.6.jar' -xsl:'/Users/myUserName/Documents/XML:RSS/mystylesheet.xsl' -s:'/Users/myUserName/Documents/XML:RSS/some.xml'
Result: successful transformation.
Moved the .jar file back, renamed the folder to XMLRSS and ran the
following command:
java -jar '/Users/myUserName/Documents/XMLRSS/saxon-he-10.6.jar' -xsl:'/Users/myUserName/Documents/XMLRSS/mystylesheet.xsl' -s:'/Users/myUserName/Documents/XMLRSS/some.xml'
Result: successful transformation.
I don't ever use it myself: however myUserName/Library/Java/Extensions is special as far as the classpath is concerned (you don't need to put JAR files in this directory on the classpath), but it's not special as far as the -jar option is concerned - that needs to be an absolute or relative filename in the normal way and has nothing to do with the classpath.
If you've chosen to put the JAR file in this magic location, then I would use the command java net.sf.saxon.Transform options to pick Saxon up from the classpath rather than identifying the -jar location directly.
There are good reasons for NOT putting Saxon in this magic location, however; one reason is it will affect applications that don't actually want to use Saxon (they might be written to use some other XSLT processor, and you might not actually be aware that they use XSLT at all, until they stop working).
I have some basic java knowledge and i decided to switch from Intellij to VS Code. I know how to compile and run a java file (which may use other imported .java files) from the terminal, but i want to run a java program using the run icon inside vs code.
I'm not a 100% sure, but i think that in order to run a java program inside vs code you need a extension. For this reason i downloaded the Java extension pack. Note that i already have installed the latest jdk on my computer.
After i installed the plugin, i could run the program using the "run without debugging"/clicking in the run icon. However, no .class files are produced. I control+h but there isnt any hidden folder that vs code may drop the .class files.
How does the program run in the first place?
How can i config vs code in order to compile the java files before running the one that has the main function?
Basically, when you run a java file normally, you compile it with javac and then run it with java (or something along those lines, there are many different variations of possible ways to do it). If you go ahead and try, it is possible to run java filename.java and skip the normal javac step. In the case of VSCode, it will differ based on what extensions you have, but some may run the code with a simple java filename.java and others may have different settings set. If you take a look at your extension preferences as well as your preferences for java by searching your settings, there may be an option, such as "Java Source Paths" enabled which changed where compiled files are saved by VSCode.
If your project is a folder containing Java source files. And no build tools(Maven/Gradle) are used.
If that is the case, you can trigger the command Java: Configure Classpath, then find the section output and then set a relative path to your workspace.
The output files are by default stored inside the workspace storage.
If after triggering the command, what you see is the native vs code setting page. Then try to search java.project.outputPath and then set a relative path to it.
I am making a Java program that I will wrap to become an .exe for testing and production. Part of the programs initialization process is to make a folder named "config" on the same level as the executable file. For illustration:
---> Parent Folder
---> myProgram.exe
---> config/
That is what ideally what should happen.
As of now, I'm testing this block of code:
String config_dir = "./config";
if(!new File(config_dir).exists()){
new File(config_dir).mkdirs();
return;
}
And what it does is to check if the directory exists, and create it if it doesn't.
However, this code is run by my Main.java class, and when it goes one level higher to create the config directory, it is still on the same level as the other folders inside the workspace directory:
---> MyProject
---> bin
---> external_lib
---> src
---> config
Which makes sense since I only made the app create the folder one level higher. However, after it is packaged as an exe file, it needs to make that folder on the same level as the exe file. I am just worried that it might not work that way.
Does anyone have a way to ensure that a folder is created on the same level as the packaged executable Java file? I'm working on a Mac and it might take time to be able to test it.
From a "running a JAR" perspective, you could use
System.getProperty("user.dir")
which returns the path where the JVM was started from. Once you turn this into an executable, I'm unsure exactly what you might need. But you might also try
getClass().getProtectionDomain().getCodeSource().getLocation()
Java
Irrelevant.
How does relative folder creation differ from non-compiled code to an executable?
It doesn't.
I am making a Java Program that I will wrap to become an .exe for testing and production. Part of the programs initialization process is to make a folder named "config" on the same level as the executable file.
For that purpose you need to know the location of the executable file. For a C or C++ executable that is given by argv[0] of the main() method. For Java JAR files it is given by getClass().getProtectionDomain().getCodeSource().getLocation().
String config_dir = "./config";
That will create a folder in the current working directory of the user, same as returned by System.getProperty("user.dir"). Not 'at the same level as the executable file'.
However, this code is run by my Main.java class, and when it goes one level higher to create the config directory, it is still on the same level as the other folders inside the workspace directory:
It is still in the current working directory. Your workspace has nothing to do with it unless it is the current working directory.
However, after it is packaged as an exe file, it needs to make that folder on the same level as the exe file.
No. In the current working directory. Always. That's what . means.
Does anyone have a way to ensure that a folder is created on the same level as the packaged executable java file?
See above, but, judging by comments and what you've accepted in your own answer, I don't think that's what you actually want. I think you want it in the current working directory, and that's what you're getting. What the current working directory actually is depends on how you run the program, and where from. If you run from within the IDE you will get the IDE's idea of it. If you run from a command line you will get the shell's cwd. If you run by double-clicking you will get whatever cwd is defined for the double-click, which may be the directory of the executable or JAR file.
I am using ClearTK along with SVM-Light programmatically within Java. I have downloaded the package both for ClearTK integration as well as for SVM-Light itself. Whether I run via Eclipse or the command line, I keep getting
Cannot find file "svm_learn"
I try putting it in the current directory. I try putting including its location using "-cp" on the command line or add the folder in Eclipse to the runtime classpath. What must I do to get my Java code to recognize where the two executables reside?
You need to adjust the $PATH variable for your system to include the location for the two executables. Only then will eclipse or command line execution pick up these tools. It is not good enough to do -cp or add it to your Eclipse runtime classpath.
Examples include:
export PATH=$PATH:{svm light path}
for Linux or
set PATH=%PATH%;{svm light path}
for windows
In addition, if using Eclipse, you may have to go to your environment tab and make sure you reference the system path variable by pushing Select and then selecting Path
This is probably the most frequent question you get in the world, and I apologize, but I have to ask anyway. I recently downloaded the newest version of java (1.7.0_45-b18), and I recently finished making a small program for a local community of mine in Eclipse. I'd like to share it with them so anyone can run it by clicking it, but opening the jar file just hasn't seemed to work for me.
I attempted opening it with command prompt by using
java -jar StatCalc.jar
but it always tells me
'java' is not recognized as an internal or external command, operable program or batch file.
I looked up many solutions for this, the most common being to change your Path. So I went to the environment variables, and changed the path to
C:\Program Files (x86)\Java\jre7\bin\java.exe
But it still gives me the same result. Only when the directory is exactly in java, and the jar file is in the java bin folder can I run the program. I wan't any person to be able to run this.
How do I get command prompt to work and allow this program to be run by both me and other people in this small community?
The path shouldn't contain the executable itself - just the directory containing java.exe. So you want this on your path:
C:\Program Files (x86)\Java\jre7\bin
Restart your console, check that the path is correct (just run path and look at the output) and all should be well.
Note that if you're going to be developing Java code, you should probably use the JDK path instead of the JRE path. For example, my path contains c:\Program Files\Java\jdk1.7.0_17\bin. (Yes, I need to update :)
I hope you do not have changed your PATH variable, only added (...);C:\Program Files (x86)\Java\jre7\bin\ (on UNIX systems, use a colon (:) as the separator instead) at the end. Otherwise, you will have many issues with all other Windows applications. Note that you must add the folder that contains java.exe, not the path to the executable itself.
Then, try to restart your Command-Line or even your Windows session.
Optional: You may set JAVA_HOME to specify JDK location. See this link.
Here you have a tutorial of oracle for setting the path
http://docs.oracle.com/javase/tutorial/essential/environment/paths.html
C:\Program Files (x86)\Java\jre7\bin --> This would be your PATH variable.