I've the root directory like this :
├── classes
└── src
└── vehicles
├── Bicycle.java
└── BicycleMain.java
Bicycle.java
package vehicles;
public class Bicycle {
public int cadence;
public int gear;
public int speed;
public Bicycle(int startCadence, int startSpeed, int startGear) {
gear = startGear;
cadence = startCadence;
speed = startSpeed;
}
public void setCadence(int newValue) {
cadence = newValue;
}
public void setGear(int newValue) {
gear = newValue;
}
public void setSpeed(int newValue) {
speed = newValue;
}
public int getGear() {
return gear;
}
public int getCadence() {
return cadence;
}
public int getSpeed() {
return speed;
}
public void applyBrake(int decrement) {
speed -= decrement;
}
public void speedUp(int increment) {
speed += increment;
}
BicycleMain.java
package vehicles; import vehicles.*;
public class BicycleMain {
public static void main (String args[]){
Bicycle Bike = new Bicycle(10, 20, 1);
System.out.println("We have a new bicycle with speed = " +Bike.getSpeed()+", cadence = "+Bike.getCadence()+", gear = "+Bike.getGear());
} }
I compiled the Bicycle.java and successful, but not for BicycleMain.java :
symbol : class Bicycle
location: class vehicles.BicycleMain
Bicycle Bike = new Bicycle(10, 20, 1);
^
src/vehicles/BicycleMain.java:6: cannot find symbol
symbol : class Bicycle
location: class vehicles.BicycleMain
Bicycle Bike = new Bicycle(10, 20, 1);
^
2 errors
I try to run these files with Netbeans and IT WORKS! but why it doesn't work when I compile in CLI?
First, To compile the java source file using javac you need to specify the files to compile explicitly.
Example:
javac PathToSourceFile/FileName.java
you need not provide the path if the source file is in the current working directory.
Second, whenever java encounters import abc.xyz.ClassName; it tries to resolve abc/xyz/ClassName with respect to the classpath or current working directory.
So if you are inside the vehicles folder and compile your code, it wont compile because it will look for folder vehicles inside folder vehicles (which doesn't exist!).
but, you can do this when inside the vehicles folder
javac -cp ../ BicycleMain.java
and it should compile, because classpath will be set to the directory(../) containing vehicles. which will resolve your Bicycle class.
and then use
java -cp ../ vehicles/BicycleMain to run.
Try deleting the line import vehicles.*; from BicycleMain.java and them compiling with javac in command line.
By the way it happens because while you are compiling in javac you are in the folder vehicles and you write a statement import vehicles.*; in BicycleMain.java which means to the compiler there is another folder vehicles within the vehicles folder which is not the case here
I have solved this problem, compiling from "src".
Something like this: javac ./my_folder/my_file.java
Kind Regards
I tried all the solutions here but eventually I found that the problem for me was I was using different versions of the JDK and JRE.
Check JRE version:
java -version
Check JDK version:
javac -version
Just remove the package line from beginning and it'll work 100%.
Go to the folder in which files are stored via terminal and
type javac *.java
There will be no need to import classes too.
Related
e.g : i have a simple code that take an array list of numbers and computes Sum. I am created a .JAR of this code. now my question is how can I import this JAR in another project and pass array list to it , and JAR give me the result to reuse it ??
This is an example
1- in a directory com\mycompany\myproject create Task.java
package com.mycompany.myproject;
import java.util.*;
public interface Task{
public int sum(List<Integer> list);
}
2- in a directory com\mycompany\myproject\support create MyTask.java
package com.mycompany.myproject.support;
import java.util.*;
import com.mycompany.myproject.Task;
public class MyTask implements Task{
public int sum(List<Integer> list){
int variable = 0;
for(int i: list){
variable += i;
}
return variable;
}
}
3- compile both .java with command $javac com/mycompany/myproject/Task.java and command $javac com/mycompany/myproject/support/MyTask.java
4- create .jar file with command $jar -cvf task.jar com/mycompany/myproject/Task.class com/mycompany/myproject/support/MyTask.class
(I decided to put "task" as name of my .jar file)
At this point you have created you .JAR and you can use it in another project. Let's see how to do it.
5- take your task.jar file and put it where you have defined your CLASSPATH System Variable
6- create Main.java in any directory.
import java.util.*;
import com.mycompany.myproject.*;
import com.mycompany.myproject.support.*;
public class Main{
public static void main(String arg[]){
//create the implementation you want
Task task = new MyTask();
LinkedList<Integer> list = new LinkedList<Integer>();
list.add(8);
list.add(9);
list.add(10);
list.add(2);
int result = task.sum(list);
System.out.println(result);
}
}
7- comnpile Main.java with $javac Main.java
8- take Main.class(result of compilation of Main.java) and put it where you have defined your CLASSPATH System Variable.
9- go to your CLASSPATH directory and execute command $java Main
Assuming you have sum.jar Try running your application with -classpath sum.jar This will make possible importing classed/calling the code in the sum.jar from your application.
I'm executing the programs from command line and using packages in them.
my program file names are TestA.java and TestB.java.
I've executed below initially
javac TestA.java
No issues for the above and it generated the class file as well
for the following i'm observing the issue
javac TestB.java
output :
TestB.java:2: error: '.' expected
import TestA;
^
TestB.java:2: error: ';' expected
import TestA;
^
2 errors
and the TestA.java file is
package a.b;
class TestA {
public static void methodPublic(){
methodPrivate();
}
protected static void methodProtected(){
methodPrivate();
}
static void methodDefault(){
methodPrivate();
}
private static void methodPrivate(){}
}
TestB.java content is :
package a.b;
import TestA;
public class TestB {
public static void main(String args[]) {
TestA.methodPublic();
TestA.methodProtected();
TestA.methodDefault();
}
public static void methodPublic() {
}
protected static void methodProtected() {
}
static void methodDefault() {
}
private static void methodPrivate() {
}
}
I'm executing the javac by navigating to b folder where these two files exist.
I'm executing the javac by navigating to b folder where these two files exist.
You don't want to do that; the fully qualified class name of every class includes the package. They form a tree. Much like your filesystem. From the b folder move up two directories (to the folder containing a - e.g. cd ../.. or cd ..\.. on Windows). Then
javac -cp . a/b/TestA.java a/b/TestB.java
Also, you would normally want that to be written to a "binary" output folder. So
javac -cp . -d bin a/b/TestA.java a/b/TestB.java
Finally, you don't need to import TestA because it is in the same package as TestB. But, if you want to you need
import a.b.TestA;
I am trying to create a compile.bat file using the following classes: HumanTest (main method), Man, Food. Below are the code for the 3 classes. In this situation Food is already compiled and I do not have the .java file for it.
package human.man;
public class Man {
private String name;
private Food f;
public Man(String name, Food f) {
this.name = name;
this.f = f;
}
}
public class Food {
private String foodName;
public Food(String name) {
foodName = name;
}
}
import human.man.*;
public class HumanTest {
public static void main (String[] args) {
Food f = new Food("ckt");
Man m = new Man("joe", f);
}
}
In compile.bat, i run the following code
javac -cp classes;src HumanTest.java
But I get the error that Food class cannot be found. I'm wondering why this is so even though I have already set the classpath for Food.class. Here's the link for the files: https://www.dropbox.com/s/2wussnm55tbnh3t/Question.zip?dl=0
EDIT:
Below is the tree diagram, do let me know if I drew it incorrectly!
--Question
|--compile.bat
|--HumanTest.java
|--classes
|--Food.class
|--src
|--human
|--man
|--Man.java
The problem is not related to batch files, but purely on the organization of your classes. You can't import a default package from a named package, nor can you use a class that is in the default package from a class that is in a named package.
In class human.man.Man, you are trying to use class Food which is in the default package. Try moving Food to a named package instead.
My main folder is ABC inside it is 2 folders named classes and src, inside src is 2 folders named objectFile and testFile, inside objectFile is ABC.java while inside testFile is TestABC.java.(inside classes is the same but .class instead) now ABC contains
package objectFile;
public class ABC
private int something;
while TestABC.java contains
package testFile;
import objectFile.ABC;
public class TestABC
error says TestABC.java:2: error: package objectFile does not exist
import objectFile.ABC;
Are you specifying the sourcepath? This tells the compiler where to find the classes that it needs to import.
javac -sourcepath src -d classes src\testFile\TestABC.java
Note that this compiles not just TestABC.java, but ABC.java as well (because of your import statement).
You can then put the classes into an archive using the jar command:
jar cfe myJavaArchive.jar testFile/TestABC -C classes .
This will create a new jar with the filename myJavaArchive.jar and entrypoint testFile/TestABC made from all the files in the classes directory.
Because it is the entry point, TestABC must have a main method, e.g.
package testFile;
import objectFile.ABC;
public class TestABC {
public static void main(String[] args) {
ABC abc1 = new ABC(1);
ABC abc2 = new ABC(2);
System.out.println("abc1.i is " + abc1.getI());
System.out.println("abc2.i is " + abc2.getI());
}
}
and
package objectFile;
public class ABC {
private int i;
public ABC(int i) {
this.i = i;
}
public int getI() {
return i;
}
}
Then you can execute the code using the java -jar command:
java -jar myJavaArchive.jar
I am trying to use the java.lang.instrument.Instrumentation class which requires usage of the 'premain' class - a good descrip can be found on stack here.
The problem is that I have done this and am having trouble using it in another program. My class looks like this:
public class InstrumentationWrapper {
private static final String INSTR_KEY = "test.instrumentation";
private static Instrumentation instrumentation;
public static void premain(String options, Instrumentation inst) {
Properties props = System.getProperties();
if(props.get(INSTR_KEY) == null)
props.put(INSTR_KEY, inst);
}
public static Instrumentation getInstrumentation() {
if (instrumentation == null) {
instrumentation = (Instrumentation) System.getProperties().get(INSTR_KEY);
}
return instrumentation;
}
public static long getObjectSize(Object o) {
return instrumentation.getObjectSize(o);
}
public static long getSizeOfObjects (Collection<?> col) {
long cumSize = 0;
for (Object o : col) {
cumSize = getObjectSize (o);
}
return cumSize;
}
}
The manifest is in the Jar file as such:
$ jar -tf target/instrumentator-1.0.jar
META-INF/
META-INF/MANIFEST.MF
com/
com/testTools/
com/testTools/instrumentation/
com/testTools/instrumentation/InstrumentationWrapper.class
META-INF/maven/
META-INF/maven/com.netrecon.testTools/
META-INF/maven/com.netrecon.testTools/instrumentator/
META-INF/maven/com.netrecon.testTools/instrumentator/pom.xml
META-INF/maven/com.netrecon.testTools/instrumentator/pom.properties
and the MANIFEST.MF is just:
$ more src/resources/META-INF/MANIFEST.MF
Manifest-Version: 1.0
Premain-Class: com.testTools.instrumentation.InstrumentationWrapper
In the launch configuration in eclipse I get the following problem
Failed to find Premain-Class manifest attribute in Z:\workspace\<project>\testTools\instrumentor\target\instrumentator-1.0.jar
and the option is -javaagent:${workspace_loc:instrumentator}\target\instrumentator-1.0.jar
I am really unsure how I can get this to work - All I really need to do is have a test harness that will let me look at the memory foot print of an array. Any ideas?
Nothing jumps out at me, but if you want to inspect further you can write a quick class to open up your Jar file with java.util.jar.JarFile and programatically inspect the manifest. This will indicate whether the issue is somehow in the way you wrote your manifest (maybe a space in the wrong place or something) or the way it's getting loaded (Maybe there is a typo in the specification of the premain class?).