When I import a package to my MyLib class (which requires -cp to javac) I can no longer compile my MyMain class.
MyMain.java:
class MyMain
{
public static void main (String [] args)
{
MyLib.do_stuff ();
}
}
MyLib.java:
import com.google.gson.JsonElement;
class MyLib
{
public static void do_stuff ()
{
System.out.println ("Hello.");
}
}
When I javac MyLib.java I have do do it like this
javac -cp GSON_JAR_PATH MyLib.java
That works but if I
javac MyMain.java
I get
./MyLib.java:1: error: package com.google.gson does not exist
import com.google.gson.JsonElement;
but if I add -cp to the compilation command
javac -cp GSON_JAR_PATH MyMain.java
I get
MyMain.java:5: error: cannot find symbol
MyLib.do_stuff ();
^
symbol: variable MyLib
location: class MyMain
Use "-cp path1:path2" - colon separated. (semicolon works on windows) (the parameter to cp is quoted....
javac -cp path1:path2 //or ; for windows.
Note 1 - setting -cp overrides any existing CLASSPATH environment or default
path setting.
Note 2 - if no CLASSPATH setting then default is '.' - until the -cp overrides that.
So in the posted case - the "." was set for path (either CLASSPATH or default) up until the -cp was used which overrode that default - so it needs to be added back in.
Related
I am using spring framework.
I have an interface And a class In the same package.
My interface is
package soundsystem;
public interface CompactDisc{
void play();
}
My class is
package soundsystem;
import org.springframework.stereotype.*;
#Component
public class Sgtpeppers implements CompactDisc{
private String title = "A Movie";
private String artist = "The Movie is Being Played";
public void play(){
System.out.println("The CD is Played \n"+title+"\n"+artist);
}
}
On Compilation it gives me this error
Sgtpeppers.java:5: error: cannot find symbol
public class Sgtpeppers implements CompactDisc{
^
symbol: class CompactDisc
1 error
The Interface is Compiled First and the .class file is also stored the soundsystem package.
I Think there is something wrong with the javac Command.
The command i used is
javac -d . -cp "spring-framework-5.0.1.RELEASE/libs/*" Sgtpeppers.java
Is this because i changed the classpath?
1) As a general rule, to compile classes, don't perform the task from the directory of a specific package.
Instead, use the root of the application source code as base to run the javac/java command.
By following this simple rule :
2)To compile all classes located in a same package, just specify the package as "source files" :
javac soundsystem/*.java
3)To compile a specific class depending on another compiled class of your source code (in the same package or not), you don't need to specify "." (that represents the current directory) in the classpath as it is the default value.
Java documentation states indeed that :
The default class path is the current directory. Setting the CLASSPATH
variable or using the -classpath command-line option overrides that
default, so if you want to include the current directory in the search
path, then you must include a dot (.) in the new settings.
But if you explicitly set the classpath with another value, the default value is not more used.
And here you did it :
javac -d . -cp "spring-framework-5.0.1.RELEASE/libs/*" Sgtpeppers.java
So you should add explicitly "." in the classpath too.
From the source code root, it would give on Windows :
javac -d . -cp ".;spring-framework-5.0.1.RELEASE/libs/*"
soundsystem/Sgtpeppers.java
For Unix, separator char is :, so it would give :
javac -d . -cp ".:spring-framework-5.0.1.RELEASE/libs/*"
soundsystem/Sgtpeppers.java
I'm not sure if this is a classpath problem, a syntax problem, or an access modifier problem. I'm trying to implement packages for the first time in Java and having with the compiler not finding classes in the parent package.
I understand there isn't any hierarchical relationship in package structures and I am explicitly importing parent package classes in the child package class.
The parent package classes' constructors are public.
I am under the impression both directories need to be on the classpath but not sure about it. Either way, I have both dirs on the classpath to be sure.
Directory Structure
home
|
|---java
|
|---src
|
|---com
|
|---inv
|
|---mail
|
|---SendMail.java
|
|---TeradataCon.java
|
|---ExcelWriter.java
CLASSPATH
(mdexter#server) /home/mdexter/java/src/com/inv/mail # echo $CLASSPATH
.:/storage/mdexter/java/lib/*:/usr/java6_64/jre/lib/*:/usr/java6_64/lib/*:/home/mdexter/java/src/com/inv/*:/home/mdexter/java/src/com/inv/mail/*
SendFile.java (stripped down)
package com.inv.mail;
import com.inv.TeradataCon;
import com.inv.ExcelWriter;
public class SendMail
{
public static void main(String[] args)
{
TeradataCon teradata = new TeradataCon(some, args, here);
ExcelWriter xls = new ExcelWriter(some, args, here);
}
}
TeradataCon.java (stripped down)
package com.inv;
public class TeradataCon
{
public TeradataCon()
{
// stuff
}
}
ExcelWriter.java (stripped down)
package com.inv;
public class ExcelWriter
{
public ExcelWriter()
{
// stuff
}
}
Error output
(mdexter#server) /home/mdexter/java/src/com/inv/mail # javac *.java
StrategyVolumes.java:3: cannot find symbol
symbol : class TeradataCon
location: package com.inv
import com.inv.TeradataCon;
^
StrategyVolumes.java:4: cannot find symbol
symbol : class ExcelWriter
location: package com.inv
import com.inv.ExcelWriter;
^
StrategyVolumes.java:14: cannot find symbol
symbol : class TeradataCon
location: class com.inv.mail.StrategyVolumes
TeradataCon teradata = new TeradataCon(
^
StrategyVolumes.java:14: cannot find symbol
symbol : class TeradataCon
location: class com.inv.mail.StrategyVolumes
TeradataCon teradata = new TeradataCon(
^
StrategyVolumes.java:32: cannot find symbol
symbol : class ExcelWriter
location: class com.inv.mail.StrategyVolumes
ExcelWriter xls = new ExcelWriter(;
^
StrategyVolumes.java:32: cannot find symbol
symbol : class ExcelWriter
location: class com.inv.mail.StrategyVolumes
ExcelWriter xls = new ExcelWriter(;
^
6 errors
What I have tried
import com.inv.*; (Shouldn't matter right?)
Compiled parent classes from /home/java/src/com/inv - works
Compiled mail/*.java from /home/java/src/com/inv - doesn't work
I think you've misunderstood the classpath, for starters. You don't put package directories on the classpath - you only put the root of output directories there.
I suggest you compile from the src directory, with the output going to a bin or classes directory. For example, get rid of your CLASSPATH environment variable entirely (it's rarely useful, IME - better to specify it as a command-line option where necessary) and then use something like:
/home/mdexter/java/src # javac -d ../bin com/inv/mail/*.java
Or better, compile everything together, as JB Nizet suggests:
/home/mdexter/java/src # javac -d ../bin `find . -name '*.java'`
(Or use an IDE and/or build tool.)
Running into an interesting problem
When I run:
$cd /projects/MyProject/
$java -cp . S3Sample
This works fine. However if I run:
$java -cp /projects/MyProject /projects/MyProject/S3Sample
Error: Could not find or load main class .projects.MyProject.S3Sample
Why is that. Did a quick look and can't find the answer. Thanks!
I have this folder structure:
- home
- org
- test
+ Foo.java
+ Foo.class
And the code in Foo.java is a simple hello world application:
//Note the usage of the package statement here.
package org.test;
public class Foo {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
Then, in command line, in order to execute Foo.class, I should provide the complete name of the class (I'm in "/home" folder in cmd):
$ java -cp "org/test;." Foo
Exception in thread "main" java.lang.NoClassDefFoundError: Foo (wrong name: org/test/Foo)
$ java -cp "org/test;." org.test.Foo
Hello world
Now, I edit the class above and remove the package sentence:
//no package specified
public class Foo {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
After recompiling the class and executing the same command lines:
$ java -cp "org/test;." Foo
Hello world
$ java -cp "org/test;." org.test.Foo
Exception in thread "main" java.lang.NoClassDefFoundError: org/test/Foo (wrong name: Foo)
TL;DR
Make sure to always specify the full name of the class. Check if your class belongs to a package. Specifying the path of the class to execute is the same as writing the full name of the class, java program will replace / by ..
You should run
$ java -cp /projects/MyProject S3Sample
The path for class is already CLASSPATH-relative
With java, you specify the fully qualified name of a class containing the main method you want executed. (The launcher will replace / with .). This class needs to be in the classpath. The argument is not a path to a file.
I am trying to import a Java Class in Jruby
$ ls
bin src
$ ls bin/com/practice
Test.class
$ ls src/com/practice
Test.java
$ cat src/com/practice/Test.java
package com.practice;
public class Test {
public static String foo(){
return "Java!!";
}
public static void main(String args[]){
System.out.println(Test.foo());
}
}
$ jirb -Ibin
jruby-1.7.10 :001 > java_import 'com.pratice.Test'
NameError: cannot load Java class com.pratice.Test
from org/jruby/javasupport/JavaClass.java:1250:in `for_name'
from org/jruby/javasupport/JavaUtilities.java:34:in `get_proxy_class'
from file:/Users/gaurish/.rvm/rubies/jruby-1.7.10/lib/jruby.jar!/jruby/java/core_ext/object.rb:26:in `java_import'
from org/jruby/RubyArray.java:2409:in `map'
from file:/Users/gaurish/.rvm/rubies/jruby-1.7.10/lib/jruby.jar!/jruby/java/core_ext/object.rb:22:in `java_import'
from (irb):1:in `evaluate'
from org/jruby/RubyKernel.java:1119:in `eval'
from org/jruby/RubyKernel.java:1519:in `loop'
from org/jruby/RubyKernel.java:1282:in `catch'
from org/jruby/RubyKernel.java:1282:in `catch'
from /Users/gaurish/.rvm/rubies/jruby-1.7.10/bin/jirb:13:in `(root)'
What am I doing wrong here?
You have a number of problems:
You've misspelled "practice" in irb: java_import 'com.pratice.Test'
Your class isn't actually in the correct package. You need to add package com.practice; to the Java code.
You need to add "bin" to your classpath so that the JVM can find the classes: $CLASSPATH << 'bin'
Altogether, I was able to run this in IRB:
$CLASSPATH << 'bin'
com.practice.Test.foo
# => "Java!!"
EDIT: I failed to copy your package line, that's my fault, not yours. :-)
So when i try to open a java class that's not in a package from the command prompt it all works fine, but when I try to open a class that's in a package it gives me NoClassDefFoundError.
And when I list the package when I try to open the class (java somepackage/someclass) it says that it can't load or find the main class.
Any help?
What I can infer is, you have two classes:
Test.java:
// no package defined here
class Test{
public static void main(String[] args){
System.out.println("Test");
}
}
so you can compile and run it using:
javac Test.java
java Test
Another class:
Test.java:
package test; // package defined here
class Test{
public static void main(String[] args){
System.out.println("Test");
}
}
And thus doing same thing gives you error.
For this you need to be in the parent directory of 'test' folder in your terminal or cmd and use:
java test.Test
No problem with compiler. You can compile as usual using javac Test.java from inside 'test' folder.
NoClassDefFoundError means that your JVM can't find your class at runtime. This could be because it's not visible (set to private or protected, or just no access modifier).
It could also be missing from your build path
package pkg1;
public class Dataguise{
public static void main(String [] args){
System.out.println("My name is Maninder Singh");
}
}
Suppose this is my code. My package name is pkg1.
1. First you need to create pkg1 dirrectory if not existed.
2. Run "javac Dataguise.java" command
3. It will generate the "Dataguise.class" file and move this file to "pkg1" folder
4. Now run "pkg1.Dataguise" command it will work.
I was having the same issue so sharing my experience.
What I assume is, you are creating a package and a class inside it, for example.
package com.vishwa.hello.commandLineArgs;
public class ComandLineArguments {
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 0; i < args.length; i++) {
System.out.println("Command line arg is "+args[i]);
}
}
}
When I try to compile and run the above code in command prompt (from the package folder) as
javac ComandLineArguments.java.
java ComandLineArguments 123 456.
You get the below error:
Error: Could not find or load main class ComandLineArguments
Caused by: java.lang.NoClassDefFoundError: com/vishwa/hello/commandLineArgs/ComandLineArguments (wrong name: ComandLineArguments)
There are 2 ways to solve this:
Go to the root path of your project and then run.
java com/vishwa/hello/commandLineArgs/ComandLineArguments 123 456
789.
Command line arg is 123.
Command line arg is 456.
Command line arg is 789.
If you want to run the program from the package directory, you need to specify the class path along with the complete package
reference.
java -cp
/Users/16399/Documents/workspace-spring-tool-suite-4-4.12.1.RELEASE/CoreJava/src/
com/vishwa/ hello/commandLineArgs/ComandLineArguments 123 456 789.
Command line arg is 123. Command line arg is 456. Command line arg is 789.