Purpose
I want to be able to create a package and call it.
Alternatively, I would like to create separate files for my method (to avoid having x classes in one file).
Setup
Here is my LetterGrader.java file:
package grade.util;
import java.util.*;
import java.io.*;
public class LetterGrader {
private void readArgs() {
System.out.println("Hello, read CLA!");
}
}
Here is my TestLetterGrader.java file:
import java.util.*;
import java.io.*;
public class TestLetterGrader {
public static void main(String[] args) {
LetterGrader letterGrader = new LetterGrader(); // instantiate
letterGrader.readArgs(); // call method
}
}
Steps Taken
First, I compile LetterGrader:
This auto creates the bin/grade/util/LetterGrader.class file
javac -d bin -sourcepath src src/grade/util/LetterGrader.java
Here is my working directory at this point
Second, I compile TestLetterGrader:
This fails
javac -d bin -sourcepath src src/grade/util/TestLetterGrader.java
The error message:
src/grade/util/TestLetterGrader.java:6: error: cannot find symbol
LetterGrader letterGrader = new LetterGrader(); // instantiate
^
symbol: class LetterGrader
location: class TestLetterGrader
Question
I believe I am misunderstanding how to call a classes from separate files (in the same location). How can I accomplish this?
You are importing class that is in bin folder. Don’t do that it would not work. You don’t need any import, because the classes are in the same place. Make package under src folder and place the classes there. Remove package grade.util and rename it to the package where you place the classes.
File structure:
src
\
\
yourpackage
\
\
LetterGrader.java TestLetterGrader.java
Then delete everything in your build folder and compile the classes. Java will make it’s magic. You do need to worry about bin folder, it is only for storing compiled classes.
Classes will look like this:
//package name that you created
package yourpackage;
public class LetterGrader {
//need to be public when calling from another class
public void readArgs() {
System.out.println("Hello, read CLA!");
}
}
And
//folder that you placed the .java files
package yourpackage;
//without any import
public class TestLetterGrader {
public static void main(String[] args) {
LetterGrader letterGrader = new LetterGrader(); // instantiate
letterGrader.readArgs(); // call method
}
}
Your second question:
You can use classes from other folders, but you you have to import them and they have to be under src folder.
Tell you have class A.java in folder Second and class B.java in folder Main. You will import the the folder in this case import Second.A;
And then call the class A a = new A();
When you have method in a that you want to call simply do:
a.yourmethod();
You have to change private void ... to public void... because you cannot call private outside of the class.
When you are running compiled classes they have to be in the same folder.
Thanks #maratonec for the guidance.
My initial mistake was that I was misunderstanding/misassigning the classpath assignment variable when running a program via terminal. The below helped me.
Compiling and Running a Java Program (on a PC)
• Set the working directory (say, JavaBook)
C:\> cd JavaBook
• Compile HelloWorld.java
C:\JavaBook> javac -d bin src\HelloWorld.java
•Run the program
C:\JavaBook> java -classpath bin HelloWorld
Also, the approach of having all my class files in the same location simplified things. I didn't have to worry about classpath. But not ideal as I have many files to work with.
As for the package creation, I am going to play around with java a bit more before using it. I think I need to solidify my understanding.
Thanks for helping me!
Related
I have a basic package structure. I have Main class and Player class in first package 'pack1' and then in subdirectory 'pack2' I have a Monster class. I need to use javac and java commands when running this program because it's my homework, but it just tells me that package pack1.pack2 does not exist. I am trying to run it by using command 'javac Main.java'. If I remove packages and place them in the same folder, then the command 'javac Main.java' works fine. When I run this program by using Visual Studio Code "Run" command it runs fine.
My file structure looks like this:
pack1
|_ Main.java
|_ Player.java
|_ pack2
|_ Monster.java
I have been fighting with this for the past 2 hours now, trying to google different solutions but with no luck. I am probably using the javac command in a wrong way. I have tried using -d argument and some path arguments, but since I don't understand them clearly it probably was not the correct way of using them.
package pack1;
import pack1.pack2.Monster;
public class Main extends Monster {
public static void main(String[] args) {
killPlayer();
}
}
package pack1;
public class Player {
public void shout() {
System.out.println("Shout");
}
}
package pack1.pack2;
import pack1.Player;
public abstract class Monster {
public static void killPlayer() {
Player p = new Player();
p.shout();
}
}
on pack1 parent folder:
Compile all your java files.
javac $(find . -name "*.java")
And then,
java pack1.Main
So, I have a package "com", which consists of two sub-packages "Common" and "Model1". The Model1 contains a class Model which I am trying to import in the Servlet2 class, which resides in the Common package. I compile the Model class first which stays fine, but the Servlet2 class doesn't and comes up with an error saying "package com.Model1 doesn't exist"
Here's the Model class:
package com.Model1;
import java.util.*;
**public** class Model{
public ArrayList<String> getBrands(String color){
ArrayList<String> brands=new ArrayList<String>();
if(color.equals("amber")){
brands.add("Jack Amber");
brands.add("Red Moose");
}
else{
brands.add("Jail Pale Ale");
brands.add("Gout Stout");
}
return brands;
}
}
Here's the Servle2 class:
package com.Common;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import com.Model1.Model;
public class Servlet2 extends HttpServlet{
public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{
res.setContentType("text/html");
PrintWriter out=res.getWriter();
out.println("Coffee selection advice<br>");
String c=req.getParameter("color");
Model m=new Model();
ArrayList result=m.getBrands(c);
out.println("<br>Got coffee color "+c);
Iterator it=result.iterator();
while(it.hasNext()){
out.println("<br> Try: "+it.next());
}
}
}
I just can't seem to figure out how to sort this out.
Edit: Realised that default modifier is restrictive, but even making it public doesn't seem to work.
I am using notepad++ and I hope this works as the Minimal, Complete, and Verifiable example:
package com.common;
import com.model.*;
public class TheClassIWantToImportInto {
public static void main(String[] args){
System.out.println("Testing 1");
TheClassIwantToImport obj=new TheClassIWantToImportInto();
obj.testFunction();
}
}
The second class:
package com.model;
public class TheClassIWantToImport{
public void testFunction(){
System.out.println("testing function");
}
}
Both the .java files are in the same folder "C:\Program Files\Java\jdk1.8.0_161\bin"
Using the following commands in this order:
javac -d . TheClassIWantToImport.java (Works fine)
javac -d . TheClassIWantToImportInto.java (Error: package com.model doesn't exist)
Set up your project such that you have some root dir which is your project's main directory. Let's call that /Users/you/projects/MyCoolProject
Within that, make a src/main dir which will contain your sources. A source file goes in a directory that matches its package declaration. com.Model1 is a bad package name for three reasons. Convention states not to start them with caps, convention states that they are supposed to represent either your reverse website or failing that, at least the project name, and finally 'model1' is not descriptive. So let's go with package com.mycompany.coolproject.vehicleModel; instead. In that case, your Model class should be on your disk at /Users/you/projects/MyCoolProject/src/main/com/mycompany/coolproject/vehicleModel/Model.java
Use a build tool such as maven or gradle to build your project. This is going to be a lot simpler than trying to manually make javac do the right thing here. If you MUST use java, make dir build in /users/you/projects/MyCoolProject, make sure you're in that directory, and then try: javac -d build -sourcepath src/main src/main/com/mycompany/coolproject/vehicleModel/*.java and note that you'll have to add a path to that every time you make another package (to avoid having to do that... use maven or gradle).
Once you've done that, this error goes away (the error indicates that javac can't find the other source file because your project isn't properly set up yet. The above instructions lead to a properly set up project, with javac/maven/gradle being capable of finding all your source files as needed, and it's how almost all java programmers work).
I have a class called MyClass in the file MyClass.java file (code mentioned below)
package myclass;
class MyClass {
public int add (int a, int b){
return a+b;
}
public static void main(String args[]) {
MyClass obj = new MyClass();
System.out.println(oobj.add(2, 3));
}
}
I am compiling the class with
javac MyClass.java
But I am trying to run the class using
java MyClass
or
java myclass.MyClass
I am getting the Error
Error: Could not find or load main class MyClass
But, I am able to run this program if I omit out the package name.
where am I going wrong?
Make sure that you are inside the parent directory of the package folder (the folder in which your compiled class file is), and execute the following command:
java myclass.MyClass
Below is an example file structure:
bin
-> myclass
-> MyClass.class
In the example structure above, you would have to execute the command from the "bin" directory.
Also, define the class as public and recompile the java source file.
I ran into this too. It's very frustrating for someone from other languages. The key here is, the java file has to be in the right directory depending on the package declaration.
if the java file Test1.java starts with
package com.xyz.tests;
Then the java file Test1.java needs to be in directory com/xyz/tests
You can compile and run as
javac com/xyz/tests/Test1.java
java com/xyz/tests/Test1
Good luck.
You Need To Compile The Class using :
javac -d ./myclass
I get my example to run by
java <package>.<class>
From parent directory of package
I am extremely new in Java and I couldn't get one thing straight. I have E:\Java\ACP\Cricket\ directory where I have a Main.java, Player.java and CricPlayer.java. Now I am inheriting Player class into CricPlayer.
I have Main.Java as
import Java.ACP.Cricket.*;
public class Main
{
public static void main(String[] args)
{
System.out.println("Hello.");
}
}
CricPlayer.java As...
import Java.ACP.Cricket
public class CricPlayer extends Player
{
}
I need to use objects of CricPlayer in Main.java. As I mentioned earlier I am real new to Java so there might be some really obvious mistakes that I don't know about. But the question is how can I create a package for use in CricPlayer.java and Main.java? Because each time I compile the code using CMD it says "CricPlayer.java:6: error';' expected import java.ACP.Cricket.*" and points ^ to *. I don't know if I haven't created the Package properly or if it's some syntactical issue.
you need to add package declaration in the beginning of your code files. And you don't need imports if all the classes reside in the same package. BTW, good coding convention in java recommends that all letters in package name are lowercase :)
package Java.ACP.Cricket;
public class Main
{
// Your class contents
}
in the class below you shourd write a package (folder in project where file is situated)
for example
package ACP.Cricket;
You forgot the ; at your import in CricPlayer class:
import Java.ACP.Cricket.*;
Now you should be able to create CricPlayer Objects in your Main Class.
Also I don't know if "Java" in your package name is supposed to be capitalized or not. Seems like the compiler is expecting a lower case 'J' from your naming convention
Here's an alternative to your Programs.I've verified this myself, so you can be assured that it will work.
Important thing you need to know, is that any file can be compiled only if you have a main method for that file(ie in that class). so here's a detailed 'How to do it':
PlayerDemo.java:
package Java.ACP.Cricket;
class Player{
//class members & methods
}
class PlayerDemo{
public static void main(String[] args){
System.out.println("Player Class");
}
}
CricPlayerDemo.java:
package Java.ACP.Cricket;
class CricPlayer extends Player{
// class members & methods
}
class CricPlayerDemo{
public static void main(String[] args){
System.out.println("CricPlayer Class");
}
}
Main.java:
package Java.ACP.Cricket;
class Main{
public static void main(String[] args){
System.out.println("Main Class");
//use other class objects here directly.
}
}
In E: , do following stepwise:
1> javac PlayerDemo.java (this creates Player.class & PlayerDemo.class)
2> copy Player.class to Cricket folder.
3> javac CricPlayerDemo.java (this creates CricPlayer.class & CricPlayerDemo.class)
4> copy CricPlayer.class to Cricket folder.
5> javac Main.java
6> copy Main.class to Cricket folder.
7> now,also in E:, java Java/ACP/Cricket/Main
Instead of compiling from E:, you can also compile from Cricket,to avoid copying class files,but it wont work for CricPlayerDemo.java, as CricPlayer extends Player(whose location is acc to package) so you'll have to compile CricPlayerDemo from E:
Vincenzzochi is right, packages are lower case (but it should not break compilation).
And you need to declare the package at the begining of all your classes :
package java.acp.cricket;
And while all your source files are in the same package, you don't have to import anything!
I'm having a strange error. I have 2 classes in the same package but they can't find each other. From what I remember, as long as the classes are in the same package, they should be able to call each other's methods.
My code looks similar to this:
in A.java:
package com.mypackage;
public class A{
public static int read(){
//some code
}
}
in B.java:
package com.mypackage;
public class B{
public static void main(String args[]){
int x = A.read();
}
}
and it's giving me a cannot find symbol variable A error.
Both of these classes depend on some .jar files, but I've already included the path of those jars to CLASSPATH and A.java compiled fine, but B can't find A for some reasons...
When I remove the package com.mypackage; in both classes then they compile fine.
Since you're compiling Java files that are in distinct packages, you'll have to ensure that they compile to the appropriate directories.
You can use this invocation to do just that. Substitute $SRC with the location of your source files, and you can let $BIN be the current directory, or some other location on your machine.
javac -sourcepath $SRC -d $BIN A.java B.java
When you want to run them, you have to add them manually to the classpath again (but that's not such a bad thing).
java -cp $BIN com.mypackage.B
This invocation should work; just made sure of it with A.java and B.java residing on my desktop. With the -d flag, that ensured that when they compiled, they went to the appropriate package folder scheme.
It should be:
A.java
package com.mypackage;
class A {
public static int read(){
//some code
}
}
B.java
package com.mypackage;
class B {
public static void main(String args[]){
int x = A.read();
}
}