How to access a public class method in a Jar file - java

This might be a dumb question, but somehow i am unable to crack it.
I have create a maven project(Project 1) and defined a public method. I have created the jar(foo.jar) file using mvn verify.
package com.aaa.bbb;
public class FooClass{
public void fooMethod(){
System.out.print("Hello World");
}
}
In another project(Project 2) i added this jar in Eclipse configure build path -> libraries.
I cleaned this project and updated it.
When i wanted to access FooClass and its method it is saying FooClass cannot be resolved as type.
package com.iii.jjj;
import com.aaa.bbb; //Throwing an error saying the import com.aaa.bbb cannot be resolved
public class TestClass{
public void printMsg(){
FooClass obj=new FooClass(); //throwing error here FooClass cannot resolved to a type
}
}
But when i create another class extends FooClass, it is properly identifying.
package com.iii.jjj;
public class TestClass2 extends FooClass{ //It is working fine here
}
Tried different solutions, but no luck yet. Can someone help?

Related

Interface implementation getting lost

I have a class like that:
public class ClassA implements InterfaceA {}
but when I compile this using Maven and decompile the file ClassA.class using JAD i got only this.
public class ClassA {}
In another project package this don't happenig...
Someone knows why this is happening?

Java, Import Class From File

I'm writing a java program and wanted to make a class that can be called on to make a quick log to the cmd (I'm still in my testing phase, figuring stuff out). I have a file and a folder with another file in it.
LaunchProgram.java
helping
Dbg.class
Dbg.java
The summarized contents of LaunchProgram.class (the stuff that is relevant):
import helping.Dbg;
public class LaunchProgram{
public static void main(String[] args){
Dbg("Testing");
}
}
The contents of Dbg.class:
package helping;
public class Dbg{
public static void main(String message){
System.out.println(message);
}
}
When I do javac Dbg.java in cmd, it runs without any error, producing Dbg.class.
When I do javac LaunchProgram.java in cmd, I get the following error:
LaunchProgram.java:5: error: cannot find symbol
Dbg("Testing");
^
symbol: method Dbg(String)
location: class LaunchProgram
I'm not sure what's happened to cause this, and I've looked everywhere about this but can't find a solution. Does anyone know what is causing this issue and how to fix it?
Dbg is a class, not a method, and as it's a helper class it won't have a main() method of its own. Rather it should hav something like a log method that does the logging and is called by the other class.
I suspect you're not compiling the code correctly. You need to do this, in the directory that contains both LaunchProgram.java and the directory helping:
javac helping/Dbg.java
javac LaunchProgram.java
Actually you don't need the first line at all. The second line will compile both classes. Both commands will put the corresponding .class files into the right directories. Then to run it:
java LaunchProgram
Basically you should always be in the directory that is at the head of the package structure.
Here is corrected code for what you were trying to do:
public class LaunchProgram {
public static void main(String[] args){
Dbg.log("Testing");
}
}
public class Dbg {
public static void log(String message){
System.out.println(message);
}
}
But Apache log4j is a much better way to do logging in your application. Here is a skeleton code for your LaunchProgram class which uses log4j to log a message:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class LaunchProgram {
static final Logger logger = LogManager.getLogger(LaunchProgram.class.getName());
public static void main(String[] args){
logger.info("Testing");
}
}
Note that you don't need a separate class to log, but rather you can log directly from the class you need to record a message.

javac gives no warning when a class with default access contains public members

Regarding the example code below, although the Test() constructor inside the class Test is public, the class Test itself isn't public, and so the Test() constructor can't be called from outside its own package.
Does that make the public keyword redundant? If so, I wonder why javac doesn't issue a warning about the redundant use of public, when used inside a class whose access is implicitly declared as default ("package private")?
Test.java, package test -
package test;
class Test {
public Test() {}
}
Main.java, package main -
package main;
class Main {
public static void main(String[] args) {
new test.Test(); // Expected error
}
}
EDIT:
Just to be clear: it's when I compile Test.java, that I get no warning.
The user comments made to my original post have helped me solve this problem: I now realise that an IDE will give me the information that I was after, and that just using javac on its own will not. Thanks.

about same class names and interface names in a package

I am little bit confused of classes names.This is my problem ...i tried to give same class name in two different files and in the same package with default access modifier and even i tried with interfaces even then it is not showing any errors.i want to how they are actually accessed.
i dont understand how these classes are interface will be used...whether a class in a file checks for presence of class or interface (if it want to use ) first in local file and then check in outside with in the package or any thing else.i am not getting any clarity.If any one understand the trouble what i am facing,i hope will help me.....
// This is InterfaceTest
package Practice;
interface t{
public void h();
public void h1();
}
abstract class InterfaceTest implements t{
public void h(){
}
public void h1(){
}
public abstract void t();
}
//This is other file InterfaceTest1
package Practice;
interface t{
public void h();
public void h2();
}
public class InterfaceTest1 {
}
//This is TestStack file
package Practice;
public class TestStack {
Test t=new Test();
public static void main(String[] args){
TestStack t1=new TestStack();
InterfaceTest it=new InterfaceTest();
}
}
interface t{
public void h3();
}
class Test implements t{
public void h3(){
}
public void h1(){
}
public void h2(){
}
}
class InterfaceTest{
}
These three files used in the same package but i am not getting any errors in name collision
It isn't very clear what you are saying but I'll take a stab at it - leave a comment if I'm not understanding you.
In Java, a class is identified by its fully qualified name. The fully qualified name is .classname.
For example, if a class is in the com.foo.bar package and is named MyClass, the fully qualified name would be com.foo.bar.MyClass. If you have more than one class with the same fully qualified name, you will have a collision and the JVM won't know which class to use. In order to use a class in a different package, you have to import it. You would import the above class with a statement at the top of your java file lie import com.foo.bar.MyClass or, if you wanted to import the entire package, you would use import com.foo.bar.* although that is considered bad practice. Interfaces behave in the same manner. Classes in the same package as a given class do not need to be imported. So, another class in the com.foo.bar package that wishes to use MyClass, would not need to import it.
Does that help you at all? If you can clarify your question, I can try to help you more.
Edit To address your clarification, you can only have one top level, public class per java file. If you wish to define additional public interfaces or classes in a file, they must be nested inside the top-level class. If you use a class and don't fully qualify it, the compiler will first look for a nested class with that name and then look for a class in the same package with that name. If it still can't find it, and you haven't imported it, then it will fail with a class resolution error.
Edit 2 Ah I think I understand. Are you attempting to use those classes in a different class? The compiler won't complain until it attempts to resolve the class that has a name collision. If that class isn't referenced anywhere, the compiler won't care. If you have two MyClass classes, but neither is used anywhere, then the compiler won't bother trying to resolve the class and won't notice the collision. Yes, inside of MyClass if you attempt to reference MyClass it's going to assume that you are referring to the class you are in.
Edit 3 One last try, if you have MyClass and then have another class nested inside it, MyClass1, the fully qualified name for MyClass1 is com.foo.bar.MyClass$MyClass1 because it is nested as part of MyClass
Interface and class names within a package have to be unique:
package foo;
public interface Bar
{
void print();
}
class Bat implements Bar
{
public void print() { System.out.println("Hi there"); }
}
You can have duplicate interface or class names if the packages are different. Fully-resolved class names must be unique.
package other;
public class Bat
{
public void doSomething()
{
System.out.println("And now for something completely different");
}
}
UPDATE:
The example code you present is preposterous. Bad naming conventions aside, you have interface t defined in two separate files. What made you think that you needed to copy and paste it into the second file once you had the first one? Remove interface t from the file containing the definition for InterfaceTest1.
All these are in the same package Practice. What makes you continue to define interface t again and again and again? You also have it in that TestStack definition. Please, think of some unique names if the definitions are indeed unique and your problem goes away.

NoClassDefFoundError

I have an issue where NoClasDefFoundError is being thrown. It puzzles me since I am using interfaces, and no class definition should be available. I have read through some posts which point to Classpath, but I don't believe that to be the issue here (although I may be wrong). I am using NetBeans 6.9.1 IDE.
I have created a sample setup to reproduce the issue. Four projects: Interfaces, Objects, Locator and Consumer. Below you will find the implementations.
At runtime consumer coplains about missing SomeObject implementation, which it should not be aware of since it is accepting interface.
Exception in thread "main"
java.lang.NoClassDefFoundError:
objects/SomeObject
What am I missing?
package interfaces;
public interface ISomeInterface { }
package objects;
import interfaces.ISomeInterface;
public class SomeObject implements ISomeInterface{ }
package locator;
import interfaces.ISomeInterface;
import objects.SomeObject;
public class Locator { public static ISomeInterface LocateImplementation() { return new SomeObject(); }}
package consumer;
import interfaces.ISomeInterface;
import locator.Locator;
public class Main { public static void main(String[] args) { ISomeInterface object = Locator.LocateImplementation(); }}
You can get a NoClassDefFoundError exception with interfaces just as you can with classes. Consider the "Class" in the name of the exception to be the .class file that is generated from compiling a class or interface, not a Java class.
This is saying that the class/interface objects.SomeObject isn't visible on your classpath. Check the location of that .class file and ensure that it's on your classpath - if you're positive it's there, give us some screen shots or something that might help to debug the problem.
Think of NoClassDefFoundError as a runtime linkage problem. JRE loaded one class (or an interface) and it references another class (or an interface), but that referenced class isn't found.
The only way this can happen if you have packaging/classpath issues such that your runtime environment doesn't reflect how things are at build time.
If you are launching this from IDE, make sure that you aren't ignoring any errors and launching anyway. Some classes will not be generated that way.
Usually I run into these problems not when a class is missing, but when there is an error in the static initializers.
Try running your code in a debugger, and set the exception breakpoint to break when any exception is thrown, whether caught or not. I bet you have an uncaught exception in the static initializer for some reason.
In the locateImplementation() method you are returning "new SomeObject()",
JVM needs to have its definition when called. I think it is missing.
You should check if your SomeObject class is in class path because -
Well the JVM will be running the below code -
ISomeInterface object = Locator.LocateImplementation();
and when it does that it will call Locator.LocateImplementation(). This code internally tries to instantiate your SomeObject class which it does not find in the classpath.
So your below understanding
It puzzles me since I am using
interfaces, and no class definition
should be available.
Is not really valid.
Any Interface must be declared inside class
public class Calbacks {
public interface IBaseFragmentInterface {
void NotifyMainActivity();
}
}

Categories

Resources