Accessing Inherited subclass in a different package - java

package 1; // this is a dependency library
public class A{
public String getName(){
return "In func getName, class A";
}
}
-------------------------------------------
package 2; // this is the library which I am building
import 1;
public class B extends A{
}
----------------------------------------------
package 3; // this is the app which is using the library which I am building
import 2;
public class C {
B b = new B(); // throws error here, says "Cannot access A"
b.getName();
}
this throws an error B b = new B();
I am not sure what is the issue here, this should work fine right?
I am working on building a library where I am extending a class from dependency library class. Now I am using the library which I built in an app and when I try to access the inherited class it throws an error.
I added dependency library as following in the library I am building
implementation ':dependencyLibrary'
In the app using my library
include ':mylibraryName'
implementation project(':mylibraryName')
I just don't want the 'dependencyLibrary' accessible to the app

You are seeing this error because you have not linked your library to your current project.
You need to link the library project to your current project so that the import statement works.
One way of doing this is by:
Go to File -> New -> Import Module ->
Add library to include section in settings.gradle file and
sync the project (After that you can see new folder with library
name is added in project structure)
include ':mylibraryName'
Go to File -> Project Structure -> app -> dependency tab -> click on
plus button
List item
Select module dependency -> select library (your library name should
appear there) and put scope (compile or implementation)
Add this
line in build.gradle in app level module in dependency section
implementation project(':mylibraryName')

Related

calling a function from a project without import that project

I have some major issue here. This will be a little bit complex situation. I have 3 java project namely A, B and C. Projects A and C have B as the .jar file, means that, B act as a library for these A and C projects. What I want to do is, I want to get a function from any java file in A project and use it in java file in C project without import the java file to C. And the only way to connect between these two project is via project B. can some one help me solve this? let me give an example:
there is aa.java in project A, and the function in it is:
private static boolean keyBlocking = false;
public static boolean iskeyBlocking() {
return keyBlocking;
}
i want to use this function in cc.java in the C project without import this aa.java to C project. I hope this example helps to understand my question.
If I understand your question correctly, you want to use a class from another project without linking the project as dependent project/jar.
It is not possible.
In your scenario, you have common project(helper/utility) which is linked to both the projects A and C.
May be you can move the current class 'aa.java' to the project B.
**"I want to get a function from any java file in A project and use it in java file in C project without import the java file to C" **
Taking the statement literally "without import the java file to C", you can directly use it without import as below.
If the package is 'com.app.test', class is AA.java.
Using import:
import com.app.test.AA
public void someMethod()
{
AA.iskeyBlocking();
}
Without using import:
// NO IMPORT
public void someMethod()
{
com.app.test.AA.iskeyBlocking();
}

Maven Project class file not being found by eclipse

I have couple of maven projects let's say A & B. I have mvm installed them both before loading them inside eclipse.
One of the class in project A runs a class from project B. This class is trying to create a instance of a another class in B using the newInstance method.
Class clazz = Class.forName(className);
Constructor construct = clazz.getConstructor(new Class[] { String.class, ThreadFactory.class });
ResultClassFromB api = (ResultClassFromB) construct.newInstance(new Object[] {file, threadFactory });
I get InvocationTargetException for above code. On the surface, I understand eclipse can't find class file for ResultClassFromB. I've tried adding the parent folder of ResultClassFromB in the class path of project A but I still see the issue. How do I get past this?
info: file is mostly with comments.

Double bind jar dependency

I have one Java project (Project A) in which I load other jars. These jars (Project B) all have one class implements an application interface. In order to know that interface, project b has to have project A as library.
Now, when starting project A, it loads the jar of project B, looks for the application class, gets the constructor and trys to create an object, but this fails:
The constructor from B's class creates an object implementing the interface which is known to project B, ALTHOUGH this is the same interface as in project A, but it seems that these two are not seen as being equal.
How can I solve this double bind dependency?
Edit:
This is how I try to create an application in project A:
clazz = Class.forName(className, true, loader);
ctor = (Constructor<? extends Application>) clazz.getConstructor();
Application app = ctor.newInstance();
The exception occurs in the third line where it says app is of type SpecificApplication (which is defined in the loaded jar and implements the Application interface) and thus cannot be cast to Application.
Put the interface in another jar, which is referenced by projects A and B.

How to build automatically different JARs from same code using Eclipse?

I have many more classes in the project but for now please consider only A, B and C classes.
abstract public class A {...}
public class B extends A {...}
public class C extends A {...}
Then later I have a code, say in class D, like this
A a = new B();
//A a = new C();
//use a's methods
So my question now is how to easily configure in Eclipse building of two separate JARs. First one should have B.class included and C.class excluded and code as A a = new B(); The second one should have C.class included and B.class excluded and code as A a = new C();
I do not know many things about Ant and Maven. Do I need to use them in this case?
Maybe, something wrong with my design, if so, please let me know.
What you want to is mainly a code loading problem, not an Ant problem.
Just the two statements you presented for creating a new class instance:
A a = new B();
A a = new C();
The constructors are called using static code. Ant can not change the code, therefore the only way with Ant I see is generating a Factory class with Ant as part of the build process, depending if A or C is included into the JAR
But that would result in a project that can no longer be used directly in Eclipse as the original source code in the Eclipse project misses the factor class.
A IMHO better approach is dynamic class loading (may be combined with reflection). You can automatically search for classes that extend A or you add a configuration file/info to the JAR specifying which class to create (e.g. properties file).
Place the properties file in the src folder with the Java file and load it via this.getClass().getResource("myclass.config");
The config file can contain the class name that should used for creating a new instance.
The following code snipped assumes that B and C both have a public constructor that does not take any argument:
String classNameToLoad = ... // loaded from config file example "mypackage.B"
final Class<?> c = Class.forName(classNameToLoad);
final Class<? extends A> ac = c.asSubclass(A.class);
final Constructor<? extends A> a_ctor = ac.getConstructor();
final A a = a_ctor.newInstance();
In your eclipse you if you right click your project, you will have an option Export
Click on that, and select jar, then name the jar, select the classes you want in it.
Repeat this for the other jar.
check this http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftasks-33.htm
The easiest way to do this would be to have 3 separate Java projects in Eclipse. Based on your example, that would be
B code project
C code project
A common code
Eclipse allows you to reference the bin directory of another project from your project in the build path.
Then you can export (or use Ant) the B and C projects as separate projects.

Scala+Android+Roboguice: ClassNotFoundException in loader

I'm evaluating Scala on Android by starting with the NotesList demo. I was able to replace the NotesLiveFolder.java file with its Scala equivalent without problem.
Next, I introduced Roboguice, creating a simple NotesListApplication.java that sets up the Guice modules, and successfully injected a resource into the NoteEditor.java activity.
Finally, I when I tried to replace NotesListApplication.java with its Scala equivalent, I get the following runtime error before the application finishes booting:
java.lang.ClassNotFoundException: com.example.android.notepad.NotesListApplication in loader dalvik.system.PathClassLoader[/data/app/com.example.android.notepad-1.apk]
I created a Google Code project containing the complete Eclipse project and source. The original functioning NotesListApplication.java is:
package com.example.android.notepad;
import java.util.List;
import roboguice.application.RoboApplication;
import com.google.inject.Module;
public class NotesListApplication extends RoboApplication {
private Module module = new BindEverything();
public void setModule(Module module) {
this.module = module;
}
#Override
protected void addApplicationModules(List<Module> modules) {
modules.add(module);
}
}
and the Scala equivalent that causes the error is:
package com.example.android.notepad
import roboguice.application.RoboApplication
class NotesListApplication extends RoboApplication {
val module : Module = new BindEverything()
override protected def addApplicationModules(modules:java.util.List[Module] ) {
modules.add(module)
}
}
I'm building in Eclipse with the ScalaIDE plugin. I'm not running any treeshaker/proguard/etc.
The disassembly shows the Scala classes as expected:
Class descriptor : 'Lcom/example/android/notepad/NotesLiveFolder;'
...
Class descriptor : 'Lcom/example/android/notepad/NotesListApplication;'
Any ideas what could cause this?
Upgrade to 2.0-SNAPSHOT of RoboGuice and then you dont have to use RoboApplication and it all binds automatically. For more how to bind check out the slides from Mike Burtons presentations about RoboGuice at AnDevCon 2 and check out the 2.0 section on the wiki.
Like I posted on the mailing list maybe check out the apk with dedexer and see if the class was actually removed e.g. by Proguard or renamed so it cant be found as a next step.

Categories

Resources