how to compile interdependent packages in Java? [duplicate] - java

This question already has an answer here:
setting the correct classpath for compiling and running Java packages? [duplicate]
(1 answer)
Closed 9 years ago.
I have two packages in my project folder:
src/main/java/com/scg/domain/* and src/main/java/com/scg/util/*. Both of them have classes that import others.
eg:
import com.scg.util.Address in one of the Class in src/main/java/com/scg/domain/
and import com.scg.domain.TimeCard in one of the Class in src/main/java/com/scg/util/.
Now I want to compile all the Java files in both packages.
To compile all the Java files in src/main/java/com/scg/util/
I tried this:
javac -cp src/main/java/com/scg/domain/*:src/main/java/com/scg/util/* src/main/java/com/scg/util/*
but it gave me 72 errors. I am pasting a sample of it:
src/main/java/com/scg/domain/ClientAccount.java:11: error: cannot find symbol
public final class ClientAccount implements Account {
^
symbol: class Account
src/main/java/com/scg/domain/ConsultantTime.java:16: error: cannot find symbol
private Account account;
^
symbol: class Account
location: class ConsultantTime
src/main/java/com/scg/domain/ConsultantTime.java:35: error: cannot find symbol
public ConsultantTime(final Date date, final Account account,
^
symbol: class Account
location: class ConsultantTime
src/main/java/com/scg/domain/ConsultantTime.java:66: error: cannot find symbol
public Account getAccount() {
what is the easiest way to compile all the java files in two packages where there is dependency (I mean import here).

You should compile all the Java source files at once:
javac src/main/java/com/scg/domain/*.java src/main/java/com/scg/util/*.java
Your classpath option is useless, and not valid. The classpath is supposed to contain directories or jar files containing the root of a package tree, containing already compiled classes used by the source files you want to compile.
Compiling many files from the command line is useful to understand the mechanisms of the compilation. But you should really learn to use a build tool like Gradle or Ant to build your project, and an IDE to compile and test your classes during development.
EDIT:
Reading the documentation again, you can use -cp to specify path where sources must be found. But the root of the package tree must be specified:
-cp src/main/java

Related

Compiling multiple java files within a single file?

Trying to compile a multi file package. Needing to compile via: javac mainfile.java while also compiling all the other (about 4 other .java files) at the same time through the one file? I have tried using statements like extend and import package.* Any help would be appreciated.
I have used different compiling methods and arguments but trying to do it just by only inserting javac mainfile.java and java mainfile
Summary: Trying to compile multiple java files at once, through java compiling a single file.
My current code for the main file:
package mypackage;
import mypackage.*;
public class mainfile{
public static void main(String[] args) {
Myfile.main(args) //run main from other file
}
}
Edit: Sorry for the lack of information, when compiling, the compiler returns:
MainFile.java:15: error: cannot find symbol
Myfile.main(args);
^
symbol: variable Myfile
location: class mainfile
1 error
javac as a tool does not do what you want. But, that's why other tools exist.
What you're asking for boils down to 'I want a build system'. The vast majority of java projects use maven or gradle.
It would seem like this works fine:
javac -sourcepath src src/mainfile.java
but you'd be deceived. That will merely compile all source files that are directly referenced by the code in mainfile.java, but there are many other ways to refer to code, such as SPI, reflection, XML config files. The vast majority of java projects will end up using some construct that ends up 'breaking' the -sourcepath "trick" sooner rather than later, which is presumably why all java projects use a build system instead of relying on -sourcepath.
Note that all source files act as if they have:
import java.lang.*;
import yourownpackage.*;
at the top, whether you write this out or not. And, import is java-ese for 'alias'. import foo.bar.Baz; means: Whenever 'Baz' appears in this file as a type, assume I meant to write 'foo.bar.Baz', and that is all: import foo.bar.Baz does not run any code that is in the Baz class whatsoever. If you don't use Baz, then the class file produced doesn't mention Baz at all. This will also not cause javac to then compile your entire directory.

setting the correct classpath for compiling and running Java packages? [duplicate]

This question already has an answer here:
getting error when I compile the Java code using package in commandline?
(1 answer)
Closed 8 years ago.
I have been using Eclipse lately, where compiling and running the program is very simple. Not much needs to be done in setting the classpath. But apparently that is not the case when it comes to running them from commandLine. when I try compiling from terminal, I am having various errors. I am pasting an image of my package structure of the project cp125_soln. Now I want to compile Invoice.Java in the com.scg.domain package,
I tried
javac src/main/java/com/scg/domain/Invoice.java
src/main/java/com/scg/domain/Invoice.java:17: error: package com.scg.util does not exist
import com.scg.util.StateCode;
.......................//long error message
This means I do not have com.scg.util.* in my classpath. so I tried
javac -cp src/main/java/com/scg/util/* src/main/java/com/scg/domain/Invoice.java
src/main/java/com/scg/util/ListFactory.java:8: error: package org.slf4j does not exist
import org.slf4j.Logger;
^
src/main/java/com/scg/util/ListFactory.java:9: error: package org.slf4j does not exist
import org.slf4j.LoggerFactory;
^
src/main/java/com/scg/util/ListFactory.java:11: error: cannot find symbol
import com.scg.domain.ClientAccount;
^
symbol: class ClientAccount
location: package com.scg.domain
................... // long error message
I read different articles on how classpath works and how to provide it in command-line. but when it comes topackage level structures, I am not able to find a good tutorial on how to COMPILE and RUN packages. If a little help could be provided here on the propery way to compile and run these kind of packages, it will be very helpful.
javac src/main/java/com/scg/domain/Invoice.java
Try this:
cd src/main/java
javac com/scg/domain/Invoice.java

Javac can't find class that is in the same directory

I am trying to compile a Java file and I'm getting this error message:
$ javac -cp "bc-j-mapi-w-2.4.jar;apache-commons/*;json-org/*;lib/*" BrightcoveVideoQueryPOI.java
BrightcoveVideoQueryPOI.java:57: cannot find symbol
symbol : class BrightcoveAPI
location: class BrightcoveVideoQueryPOI
BrightcoveAPI brightcoveAPI = new BrightcoveAPI(BrightcoveAPI.PROD_READ_URL_TOKEN);
^
BrightcoveVideoQueryPOI.java:57: cannot find symbol
symbol : class BrightcoveAPI
location: class BrightcoveVideoQueryPOI
BrightcoveAPI brightcoveAPI = new BrightcoveAPI(BrightcoveAPI.PROD_READ_URL_TOKEN);
^
BrightcoveVideoQueryPOI.java:57: cannot find symbol
symbol : variable BrightcoveAPI
location: class BrightcoveVideoQueryPOI
BrightcoveAPI brightcoveAPI = new BrightcoveAPI(BrightcoveAPI.PROD_READ_URL_TOKEN);
^
3 errors
This would suggest that javac cannot find the class BrightcoveAPI. I'm not sure what the problem is as it is in the same directory:
$ ls
apache-commons bc-j-mapi-w-2.4.jar BrightcoveAPI.class BrightcoveAPI.java BrightcoveVideoQueryPOI.java json-org lib
You need to include . (the current directory) in your classpath:
javac -cp ".;bc-j-mapi-w-2.4.jar;apache-commons/*;json-org/*;lib/*" BrightcoveVideoQueryPOI.java
Some notes:
. is in the default classpath, but if you use -cp to specify an explicit classpath, then it's only included if you specify it.
A previous version of this answer added . to the end of the classpath, but aioobe says that it's typically put first, which makes sense, so I've edited accordingly. (The classpath is searched in order, so if you have two copies of a class, one in . and one in a library, then you probably want the . version to supersede the library version, so you need to list it first. But of course, it's not usually a good thing to have two non-identical copies of a class!)
What you've pasted looks like a *nix shell, but you're using ;, which is the separator expected on Windows. (On *nix the expected separator is :.) This may well be correct, e.g. if you're using Cygwin, but I thought I'd mention it just in case.
If you do not search your current directory (your class path doesn't) javac won't add that directory in for you as an additional default.
This behavior allows the javac compiler to be called consistently for a project (set of source code files) independent of the directory the user that invoked the compiler. If it were any other way, then you would have to ensure that you always compiled from the same working directory to get the same results.
---- edit after seeing comment in ruakh's excellent answer ----
The second issue you are seeing isn't related to the first. The "Could not find or load main class" is because you are invoking the java command with the source code file name not the class name which is defined in that source code file.
The java command runs classes, not source code files. This makes more sense when you remember that a single source code file could contain more than one class (even if they typically don't).

Problems using protobufs with java and scala

I have a file xxx.proto. I downloaded the protobuf compiler and installed it. Then I issued this command
protoc --java_out=./ xxx.proto
and it generated my xxx.java
Now I want to compile this file into a class file which I can use with Scala.
javac xxx.java
Which gives me this error
xxx.java:7: package com.google.protobuf does not exist
com.google.protobuf.ExtensionRegistry registry) {
^
xxx.java:12450: package com.google.protobuf.Descriptors does not exist
private static com.google.protobuf.Descriptors.Descriptor
^
xxx.java:12453: package com.google.protobuf.GeneratedMessage does not exist
com.google.protobuf.GeneratedMessage.FieldAccessorTable
...
...
...
100 errors
Now I guessed, it doesnt have the package.
So I copied the class files of package com.google.protobuf into the same folder where xxx.java exists. Note - I didnt compile this package. I downloaded the jar from another extension which had the jar files. So I extracted them. Now my current path where xxx.java resides has com/google/protobuf/ *.class of protobuf library.
I issued the javac command again.
This time I got a different set of errors -
xxx.java:10: cannot find symbol
symbol : class MessageOrBuilder
location: package com.google.protobuf
extends com.google.protobuf.MessageOrBuilder {
^
xxx.java:215: cannot find symbol
symbol : class MessageOrBuilder
location: package com.google.protobuf
extends com.google.protobuf.MessageOrBuilder {
^
xxx.java:608: cannot find symbol
symbol : class MessageOrBuilder
location: package com.google.protobuf
extends com.google.protobuf.MessageOrBuilder {
^
xxx.java:1017: cannot find symbol
symbol : class MessageOrBuilder
location: package com.google.protobuf
extends com.google.protobuf.MessageOrBuilder {
..... 100 errors
I even tried to compile the source files which came with google protobufs. The generated java classes are giving the same errors.
Any ideas what to do ??
Answer
Okay. Thanks everyone.
The main problem is that protocol buffers compiler package from google doesnt by default create the java library. I assumed that it does and installs it. It actually does if you are running Maven. But i didnt have maven
So i compiled the code in /java/src and used the jar.
^
When compiling, you need to have protobuf lib on your classpath. All those missing packages and classes are from protobuf lib.
Find protobuf jar and use
javac -cp path/to/protobuf.jar xxx.java
You may need to use version 2.4.1 (or 2.4+, at least) of the protobuf kit, including making sure that you update protoc (the protobuf compiler) and recompile your proto definition using the new protoc. (In other words, everything has to be the same version:
the protobuf-vn.n.n.jar file;
the protoc compiler; and
the output of compiling your .proto files with protoc.
One I got everything synched, I began to move forward with a Clojure project I'm looking at. You may be encountering the same version skew problem.
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
you can download protoc.exe (new release) from>>.
https://code.google.com/p/protobuf/downloads/detail?name=protoc-2.5.0-win32.zip&can=2&q=
in your *.proto file you correctly config
option java_package = "com.example.package";
option java_outer_classname = "class name";
One can install the protobuf jar file using the ubuntu a
apt-get install libprotobuf-java
This will copy the protobuf-java-2.4.1.jar under /usr/share/java/
Hope this helps

"Cannot find symbol" for my own class

I do not have a %CLASSPATH% set up. As I understand, this should not be a problem because Javac will assume a classpath of the current directory.
As you can see below, javac is unable to find my Case class even though it's in the same exact directory. Any thoughts on why this is happening? This code works fine when I use Eclipse.
C:\Documents and Settings\joep\My Documents\GCJ\src\codejam2011\Round0\D>dir /B
Case.class
Case.java
EntryPoint.java
C:\Documents and Settings\joep\My Documents\GCJ\src\codejam2011\Round0\D>javac EntryPoint.java
EntryPoint.java:16: cannot find symbol
symbol : class Case
location: class codejam2011.Round0.D.EntryPoint
ArrayList<Case> cases = new ArrayList<Case>();
^
EntryPoint.java:16: cannot find symbol
symbol : class Case
location: class codejam2011.Round0.D.EntryPoint
ArrayList<Case> cases = new ArrayList<Case>();
^
EntryPoint.java:24: cannot find symbol
symbol : class Case
location: class codejam2011.Round0.D.EntryPoint
cases.add(new Case(new Integer(count), line));
^
3 errors
C:\Documents and Settings\joep\My Documents\GCJ\src\codejam2011\Round0\D>
Update 1:
After trying to compile from my package root (src), I get a new error (even after deleting the Case.class file)
C:\Documents and Settings\joep\My Documents\GCJ\src>javac -cp . codejam2011/Round0/D/EntryPoint.java
codejam2011\Round0\D\EntryPoint.java:16: cannot access codejam2011.Round0.D.Case
bad class file: .\codejam2011\Round0\D\Case.java
file does not contain class codejam2011.Round0.D.Case
Please remove or make sure it appears in the correct subdirectory of the classpath.
ArrayList<Case> cases = new ArrayList<Case>();
^
1 error
C:\Documents and Settings\joep\My Documents\GCJ\src>
Update 2:
It appears to be grabbing the Case.java file from a different package.
C:\Documents and Settings\joep\My Documents\GCJ\src>javac -d ../classes codejam2011\Round0\D\*.java
.\codejam2011\Round0\D\Case.java:4: duplicate class: codejam2011.Round0.C.Case
public class Case
^
codejam2011\Round0\D\EntryPoint.java:16: cannot access codejam2011.Round0.D.Case
bad class file: .\codejam2011\Round0\D\Case.java
file does not contain class codejam2011.Round0.D.Case
Please remove or make sure it appears in the correct subdirectory of the classpath.
ArrayList<Case> cases = new ArrayList<Case>();
^
2 errors
C:\Documents and Settings\joep\My Documents\GCJ\src>
You need to compile from the package root, not from inside the package.
So, cd to the src folder and compile from there.
javac -cp . codejam2011/Round0/D/EntryPoint.java
Update: as per your new problem, you need to recompile Case.java the same way. It was apparently compiled the same wrong way (from inside the package).
If the problem is not yet solved by compiling from the package root directory (see the other answers):
make sure all the source files contain classes with names corresponding to their file name
make sure all the source files contain a package statement corresponding to their position in the source file hierarchy
delete all your .class files before compiling (this should only be necessary once, if you checked everything else).
Thus, if the file is codejam2011\Round0\D\Case.java, it should contain package codejam2011.Round0.D; as the first declaration, and then public class Case { ... }. Also, make sure there is no other source file containing this package and class declaration.
From your error message, it looks like the package statement is package codejam2011.Round0.C; instead (and you also have a class Case in the real codejam2011.Round0.C package).
You are in the wrong directory for compiling.
location: class codejam2011.Round0.D.EntryPoint
That tells me, that your package is codejam2011.Round0.D (which is against the convention (all lowercase) but beside the point ...
cd to the parent dir of codejam2011, which is src, isn't it?
javac codejam2011\Round0\D\EntryPoint.java
might do the trick.
Often you have a directory for compiled classes, like 'bin' or 'classes'. To produce the classes there, use -d (destination):
javac -d ../classes codejam2011\Round0\D\EntryPoint.java
I have similar issue, it might not apply to all cases, but what I have done is remove .gradle, build and out folder and rebuild the program again.

Categories