javac command is not able to find .class file in the current directory needed to compile a source file - javac

The files A.java and B.class(Bytecode version of B.java) are in the current directory.
A.java uses B.java in the following way:
class A {
B b;
}
From what I have read the JDK tools first look in the directories where the Java standard libraries are installed. If the class is not found in the standard libraries, the tool searches in the class path. When no class path is defined, the default value of the class path is assumed to be the current directory. Then why is the following command not working:
C:\current> javac A.java

The package structure must match the directory structure, otherwise javac will fail.
http://kevinboone.net/classpath.html

Comment out or get rid of the package statements in the begin of your classes. Since you do keep both java classes in the directory where you compile, the compiler should be able to find the B.class without trouble.

Related

javac not recognizing external libraries

I have a working version of my project in eclipse.
I exported the project as a runnable jar.
Extracted (after converting to .zip)and tried to compile a particular java file from the command prompt
(Doing it this way since I have a project requirement, where input parameter inside that particular file can be modified and recompiled/run by users who wont have Eclipse)
I have used some external libraries( for Eg:json-simple,gson etc).They arent getting recognized , during compilation.
But if I run the class file(from the Eclipse compiled version), it gets executed properly
a)Tried to compile from root folder(using package name)
javac packageName.javaFileName.java
b) and went inside the package and compiled directly.
javac javaFileName.java
The a)part didnt compile at all saying classNotFound. The b)part started compiling but threw an error where none of the external libraries got recognized.(Getting --> error: cannot find symbol for places wherever the code/import of the external lib is used)
a)Tried to compile from root folder(using package name) javac
packageName.javaFileName.java b) and went inside the package and
compiled directly. javac javaFileName.java
The a)part didnt compile at all saying classNotFound.
Yes. javac requires you to specify a filesystem path to the (first) source(s) to compile. You appear instead to have tacked .java onto the end of the desired fully-qualified class name. Probably you want to compile from the root of the unpacked jar, specifying a correct path:
javac [options] package/name/className.java
for class package.name.className. (You can also compile from a different working directory if you specify an appropriate option, as discussed below.)
The b)part
started compiling but threw an error where none of the external
libraries got recognized.(Getting --> error: cannot find symbol for
places wherever the code/import of the external lib is used)
If the class you're compiling depends on others that also need to be compiled then javac would likely make a similar complaint about them. Either compile from the root (as in (a)), or specify the path to the source root via the -sourcepath option. Either way, there's no reason to descend into the source tree to compile.
But the external libs are actually a separate, albeit related, question. You don't need to compile these, but you do need to tell javac to use them as sources of classes. You would do that via the -classpath option, which you can abbreviate to -cp. If those were packaged in the jar itself (i.e. a "fat jar") then that should be fairly easy, something along these lines:
javac -cp .:lib/dependency1.jar:lib/dependency2.jar package/name/className.java
The "lib" part may vary, and the separator definitely differs depending on OS (on Windows it is ;, whereas on Mac / Linux / Solaris is is :, as shown).
If the external libs were not packaged into the main jar then the procedure is the same, but you might have a bigger challenge finding the needed jars. Also, such a jar is probably not runnable if you move it to a different machine. Nevertheless, you should probably look in META_INF/MANIFEST.MF, as it should contain the needed information.

Why while compiling java code through cmd it's written as filename.java and running the same file we omit filetype?

While compiling java files through cmd (ie through javac command) it is written as filename.java but to run the same program we write filename and don't add the extension. Why is extension removed in java command or extension added in javac command ? Any specific reason.
When compiling, you specify the name of one or more source files, thus the .java extension
When running you specify the class name of the main class, thus no extension.
The difference becomes even more apparent, when the class is in a package:
javac mypackage/MyClass.java
java mypackage.MyClass

Haskell, create stack or cabal file from source directory

In Haskell: Given an existing directory tree (with sub-directors) of source files.
Is there a way to get a .cabal or .stack file, created automatically, with all the necessary dependents (references to the import files that are embedded inside the source file) embedded in the command file,with no need to manualy editing the command file.
In other words, get a command file that I will be able to run "straight out of the box" without the regular methods of stack new/stack build etc,commands?
cabal init will create a file that lists all the modules in your sourcedir for you. But you will still need to provide the package dependencies yourself. This is because a module Foo.Bar.Baz may come from multiple packages -- hence the package you intend to import must be explicitly specified.

Why do we still use the package keyword in Groovy / Grails?

in Java/Groovy, afaik, a package has to be defined in the corresponding folder. This results in all class files which are stored in /a/b/c start with the line package a.b.c. Is this still necessary? With regards to convention over configuration, this isn't DRY...
What kind of problems would arise when this package definition would be optional`?
While it is conventional for the directory structure to match the package structure, and certain problems arise if they don't match, it is in fact not a requirement that they match. This is also true of Java (though a lot of folks don't realize that).
Below is an example which demonstrates this.
groovydemo $ mkdir classes
groovydemo $
groovydemo $ cat src/groovy/com/demo/SomeClass.groovy
package com.somethingotherthandemo
class SomeClass {}
groovydemo $
groovydemo $ groovyc -d classes/ src/groovy/com/demo/SomeClass.groovy
groovydemo $ find classes -type f
classes/com/somethingotherthandemo/SomeClass.class
The reasons for using packages in Groovy (and Grails) are some of the same reason why they are used in Java.
Packages serve to organize classes into logical namespaces, typically by grouping collaborating classes together.
It helps avoid naming conflicts with other classes (either Java or Groovy).
In any non-trival system where you have hundreds or thousands of classes, packages provide a very useful mechanism for organization and structure.
I think what you're saying is that the package name is implied by the directory the class is in, so why do you need to state it explicity? This is only true in some cases (like Grails) where there's a convention that establishes the root of the source files (e.g. src/groovy).
But imagine I'm writing a Groovy app and have a file at /a/b/c/D.groovy, how can we tell if the root of the source files is /a and thus the package name is b.c or the root of the source files is /a/b and therefore the package name is just c? As far as I can see, we can't, so the package name needs to be stated in the source file explicitly.

javac -d option, how does it know which directory to go in?

Hi I have the following directory structure...
I enter this at terminal:
javac -d bin src/com/elharo/math/Fraction.java
and the Fraction.class file gets placed in bin/com/elharo/math instead of bin/
I just wondered why the compiler placed the file there. Is it that the point of having source and bin, so that when you compile a source file it goes in the parallel/mirror bin directory?
The output path will be computed from package and class name of the public class that must be defined in the java source file (which must, incidentally, match the file name minus ".java"). And it will be relative to the directory in the -d option, or relative to the current directory.
This is as expected. /com/elharo/math is the package the class exists in. If you took the class out of this directory an just put it in bin you would like get a noclassdeferror.

Resources