I have this code here using my API:
package org.midnightas.os.game.dots;
import java.awt.Graphics2D;
import org.midnightas.os2.Key;
import org.midnightas.os2.MidnightasOS;
import org.midnightas.os2.gameapi.Game;
public class Dots extends Game {
public Dots(MidnightasOS midnightasos) {
super(midnightasos);
}
#Override
public void init() {
}
#Override
public void keyPressed(Key arg0) {
}
#Override
public void render(Graphics2D arg0) {
}
#Override
public void tick() {
}
static {
System.out.println("MOS Dots crashed.");
MidnightasOS.setGame(Dots.class);
}
}
The static block is supposed to be ran calling MidnightasOS.setGame(Class);
However that is not happening.
I have also debugged using System.out to no avail.
Is the problem within MidnightasOS? I will post it's code if necessary.
I'm doing this because I'm trying to create an artificial operating system with Linux and the Raspberry PI.
This shall be a game console like the Game Boy.
I'm trying to load all Game classes so at least one of them would use MidnightasOS.setGame(Class);
Thanks for reading.
When is Dots class loaded by classloader. It will be loaded on the first reference of this class. See if you ever refer to this class
You can even dynamically load the class
And to find all the subtypes of a class and load them all you can use this library
public class MainClass {
public static void main(String[] args){
ClassLoader classLoader = MainClass.class.getClassLoader();
Reflections reflections = new Reflections("org.midnightas");
Set<Class<? extends Game>> subTypes = reflections.getSubTypesOf(Game.class);
for(Class<? extends Game> subType : subTypes){
try {
Class aClass = classLoader.loadClass(subType);
System.out.println("subType.getName() = " + subType.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
The static blocks in a class are executed as soon as the classloader loads the class for the first time. There are several possibilities to achieve this. Consider the following class:
public class SomeClass {
static {
System.out.println("static block in SomeClass");
}
static void someMethod() {
System.out.println("some static method");
}
}
Loading it by creating an object:
SomeClass foo = new SomeClass();
Loading it by calling a static method:
SomeClass.someMethod();
Loading it directly:
Class.forName("SomeClass");
These are only some of the possibilities you have! Please remark that you'll have to include the package structure into the third approach (if the class is in the package some.package it'll be: Class.forName("some.package.SomeClass");
Related
I want to have a class to run other classes in java, like constructor parameterized with a class to run that class later on, similar to this
class MyClass{
Class classToRun;
public MyClass(Class c) {
super();
this.classToRun = c;
}
public void runClass(){
classToRun.someStaticMethod();
}
}
where classToRun possible classes doesn't have a common ancestor, but all have method someStaticMethod, and have no idea about MyClass, which runs them.
But there are problems, like inner classes cannot have static methods, classes cannot be cast Class, etc.
There are solutions for parameterized with class methods, like
How do I pass a class as a parameter in Java?
Passing a class as an argument to a method in java
but not for constructors.
What is the proper solution to do this?
Use lambdas and pass the method reference: they match on the method signature. For void someStaticMethod() you can use Runnable.
class MyClass{
private final Runnable methodToRun;
public MyClass(Runnable someStaticMethod) {
methodToRun = someStaticMethod;
}
public void runClass(){
methodToRun.run();
}
}
new MyClass(SomeClass::someStaticMethod).runClass();
You cannot enforce that the method passed has the right name, but looks even neater IMHO.
You need to understand what generics are.
interface
public interface SomeInterface {
void someStaticMethod();
}
use
class MyClass<T extends SomeInterface>{
T classToRun;
public MyClass(T c) {
super();
this.classToRun = c;
}
public void runClass(){
classToRun.someStaticMethod();
}
}
As 2 of 3 answers were not to the point, I decided to publish fixed versions of both answers as far as they can be fixed.
The f1sh version from the above should like follows:
public class ClassToRunOthers {
Class classToRun;
public ClassToRunOthers(Class c) {
this.classToRun = c;
}
public void runClass() throws Exception {
Optional<Method> method = Arrays.stream(classToRun.getDeclaredMethods()).filter(m -> m.getName().equals("someStaticMethod")).findFirst();
if(!method.isPresent()) {
throw new RuntimeException();
}
method.get().invoke(null);
}
public static void main(String[] args) throws Exception {
ClassToRunOthers mc = new ClassToRunOthers(SomeClass.class);
mc.runClass();
}
}
class SomeClass {
static void someStaticMethod() {
System.out.println("test");
}
}
The zwei solution above can not be fixed without reflection, as generics is not to the point. Evan if you try to parametrize not with SomeInerface (because SomeClass does not extend a common SomeInterface), but with Object, it is still won't solve the problem:
public class MyClass<T extends Object> {
T classToRun;
public MyClass(T c) {
super();
this.classToRun = c;
}
public void runClass() {
// classToRun.someStaticMethod(); // Cannot resolve method 'someStaticMethod' in 'T'
}
public static void main(String[] args) {
MyClass mc = new MyClass(SomeClass.class);
}
}
class SomeClass {
static void someStaticMethod() {
System.out.println("test");
}
}
This can be fixed like the above, via reflection.
I believe, it can be done with annotations in some elegant way, and may be someone will share us with such a solution or I will do it by myself as time permits.
By now for myself, a solution with saving class name in the String in constructor next day after the question been asked did the trick.
You will have to use reflection if you want to execute a method when you only have the Class instance.
In the code below, runClass finds the method of the class using it's name as a String, then executes it. This code assumes that the method is static, also ignoring any Exception handling.
The following code prints "test":
class MyClass {
Class classToRun;
public MyClass(Class c) {
this.classToRun = c;
}
public void runClass() throws Exception {
Optional<Method> method = Arrays.stream(classToRun.getDeclaredMethods()).filter(m -> m.getName().equals("someStaticMethod")).findFirst();
if(!method.isPresent()) {
throw new RuntimeException();
}
method.get().invoke(null);
}
}
class Main {
public static void main(String[] args) throws Exception {
MyClass mc = new MyClass(Main.class);
mc.runClass();
}
static void someStaticMethod() {
System.out.println("test");
}
}
I'm trying to get object from another class from another package
package processManager;
public class PCB {
public int vruntime;
public int nice_value=0;
}
in the same package
package processManager;
public class Process {
public Process(PCB pcb) {
this.pcb = pcb;
}
public Process() {
}
public PCB pcb;
int a;
}
usage of object
package processManager.newpackage;
import processManager.Process.*;
public class NewClass {
public static void main(String[] args) {
Process proc=new Process();
}
}
and I don't know why but then I've got "Process is abstract; cannot be instantiated"
Please look closer at your code:
A) You have defined a class processManager.Process which is not abstract.
B) Next in the next file you are importing
import processManager.Process.*;
Which actually defines an import of all sub-classes of processManager.Process class (you have none) but the class itself is not considered an import.
C) This means that in the next piece of code
Process proc = new Process();
You are trying to create an instance of java.lang.Process class which is abstract.
This is a source of your error.
I am trying to provide a callback to a class function written in Java by means of an anonymous abstract class instance, but from a groovy class. The code below illustrate my issue.
//Java Code
abstract class CallBackWrapper
{
int someAttr, someOtherAttr;
public abstract void execute();
public int getAttr()
{
return someAttr;
}
}
class Delegator
{
public void callExecute(CallBackWrapper w)
{
w.execute();
}
}
//Groovy Code
class GroovyClass
{
private void foo()
{
//Doesn't work
Delegator d = new Delegator();
d.callExecute(new CallBackWrapper() {
public void execute() {
System.out.println("Hello World");
}
});
//Also doesn't work
Delegator d = new Delegator();
d.callExecute([execute:{println "HELLO from Groovy"}] as CallBackWrapper)
}
}
The closest I got to getting it to work is by changing CallBackWrapper to an interface AND declaring it inside the Groovy class. However, I need an abstract class. My question is, how can I implement this callback behavior from "Groovy Land" so that the Java class understands? Currently I get Groovy runtime errors that are not very helpful in explaining the true nature of the issue.
You haven't specified your error, but I tried your code here and got the following error:
$ javac *.java && groovy GroovyClass.groovy && rm *.class
Caught: java.lang.IllegalAccessError: class GroovyClass$1 cannot access its superclass CallBackWrapper
java.lang.IllegalAccessError: class GroovyClass$1 cannot access its superclass CallBackWrapper
It happened due to Groovy's generated inner class being unable to access CallBackWrapper. I added the public modifier and it worked fine:
// Delegator.java
class Delegator {
public void callExecute(CallBackWrapper w) {
w.execute();
}
}
// CallBackWrapper.java
public abstract class CallBackWrapper {
int someAttr, someOtherAttr;
public abstract void execute();
public int getAttr()
{
return someAttr;
}
}
// GroovyClass.groovy
class GroovyClass
{
private void foo() {
def d = new Delegator()
d.callExecute { println "Hello from groovy" }
}
static main(args) {
new GroovyClass().foo()
}
}
Out of curiosity, I added Delegator::me() to Java code, invoked it from Groovy and it worked:
class Delegator {
public void callExecute(CallBackWrapper w) {
w.execute();
}
void me() {
new CallBackWrapper() {
public void execute() {
System.out.println("Echo");
}
}.execute();
}
}
Seems to me like a bug similar to this one. You could fill a jira.
I'm in bit of a fix with this problem. Hoping for a silver bullet.
I have a few singletons(~10) which all have a few functions (~10 each). My function calls look like this (as they should). Note: Most of these calls are async and do not return anything. Only a handful are synchronous
SingletonClassGorrilla.getInstance().methodSwim(swimmingPool, lifeJacket, whistle);
SingletonClassRacoon.getInstance().methodBark(thief, owner);
I need to put all these calls in a sandbox:
Sandbox.runThisInSandboxMode(new Runnable{
#Override
public void run(){
SingletonClassGorrilla.getInstance().methodSwim(swimmingPool, lifeJacket, whistle);
}
});
As the number of places where they are being called is huge, I am hoping that the sandboxMode can be achieved at the Singleton end.
Possible solution (but infeasible because of the number of functions I will have to wrap like this):
public class SingletonClassGorrilla{
public void methodSwim(WaterBody waterBody, Instrument instrument,
EmResponse emResponse){
Sandbox.runThisInSandboxMode(new Runnable{
#Override
public void run(){
methodSwim(swimmingPool, lifeJacket, whistle, true);
}
});
}
private void methodSwim(WaterBody waterBody, Instrument instrument,
EmResponse emResponse, boolean fromSandbox){
// Do your thang.
}
}
Is there anyway, through use of reflection / annotations / any other thing in the language, which can reduce the amount of changes required?
You can use a Proxy with a suitable InvocationHandler (though you'd have to pull out an interface for each of your singletons). Disclaimer: I haven't tried to actually compile/run this code, but it should give you the general idea. If you care about return values from your singleton, you may have to use Callable instead of/in addition to Runnable in your sandbox interface.
public class SingletonGorilla implements GorillaInterface {
private static SingletonGorilla theRealGorilla;
public static GorillaInterface getInstance() {
//In reality, you'd want to store off the Proxy as well
return Proxy.newProxyInstance(SingletonGorilla.class.getClassLoader(), GorillaInterface.class, new SandboxingHandler());
}
private static class SandboxingHandler implements InvocationHandler () {
public Object invoke(Object proxy, Method method, Object[] args) {
return Sandbox.runInSandbox( new Runnable() {
public void run () {
method.invoke(proxy, args));
}
}
}
}
I'm thinking about something along the following lines:
First, you'll need an interface for each of your singletons:
Interface:
package org.test.proxywrapper;
public interface IGorilla {
public void methodSwim();
}
Implementing class:
package org.test.proxywrapper;
public class Gorilla implements IGorilla{
public void methodSwim()
{
}
}
Then, implement an InvocationHandler that factorize the code that will be common to each call to the methods of Gorilla:
package org.test.proxywrapper;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class WrapperInvocationHandler implements InvocationHandler {
#Override
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
Sandbox.runThisInSandboxMode(new Runnable() {
#Override
public void run() {
Object params = new Object[0];
try {
arg1.invoke(arg0, new Object[]{});
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
});
// return something if you need to
return new Object();
}
}
At this point, in a central place in your application/system, wrap each singleton with a Proxy, and pass the proxy reference around instead of the original wrapped object:
package org.test.proxywrapper;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String argv[])
{
WrapperInvocationHandler wrapperInvocationHandler = new WrapperInvocationHandler();
Class<?>[] implementedTypes = new Class<?>[1];
implementedTypes[0] = IGorilla.class;
IGorilla proxy = (IGorilla) Proxy.newProxyInstance(Main.class.getClassLoader(), implementedTypes, wrapperInvocationHandler);
proxy.methodSwim();
}
}
This simple example compiles and runs as I would expect.
I cut some corners here, skipped the getInstance method, etc, but I guess it gives an idea of how it can be done.
I'm experiment with Generic Classes, and I've run into a hurdle which I cannot overcome. In short, I'm encountering an error which I do not understand why it is being thrown: InstantiationException
In the documentation it defines this exception as:
Thrown when an application tries to create an instance of a class using the newInstance method in class Class, but the specified class object cannot be instantiated because it is an interface or is an abstract class.
Now the problem that has me scratching my head is that I do not use the abstract or interface keyword. I've also heard that it could be due to not having a default constructor (which I have). Just to be sure, I reduced my code to the minimal possible, but still gives an error:
package Sandbox;
public class Sandbox {
public static void main(String[] args) {
Sandbox box = new Sandbox();
}
public Sandbox() {
aMethod(subThread.class);
}
public void aMethod(Class<? extends superThread> type) {
try {
System.out.println("isInterface: "+type.isInterface());
System.out.println("isAssignableFrom of subThread: "+type.isAssignableFrom(subThread.class));
superThread t = type.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private class superThread { // implements Runnable {
public superThread() {}
public void run() {}
}
private class subThread extends superThread {
public subThread() {
super();
}
public void run() {
// more stuff
}
}
}
The Output:
isInterface: false
isAssignableFrom of subThread: true
java.lang.InstantiationException: Sandbox.Sandbox$subThread
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at Sandbox.Sandbox.aMethod(Sandbox.java:20)
at Sandbox.Sandbox.<init>(Sandbox.java:11)
at Sandbox.Sandbox.main(Sandbox.java:7)
I'm sure it's quite simple, but I cannot figure this one out. I've tried several things, but nothing has helped. Any and all help is appreciated.
Thanks,
Jon
It's because your inner classes are private. Simple fix:
public static class superThread { // implements Runnable {
public superThread() {}
public void run() {}
}
public static class subThread extends superThread {
public subThread() {
super();
}
public void run() {
// more stuff
}
}
The reasoning is because Class.newInstance must be able to access the constructor for the class you want to create.
Since the class is private, it's not accessible. Also, in order to access a non-static inner class, you essentially have to have an existing instance of the outer class (Sandbox), which newInstance doesn't have. As a result, having either public non-static or private static wouldn't work.
After zjagannatha pointed to the real problem, I also found a fix to my own code that allows me to keep the methods as non-static... essentially I discovered that even though the constructor had zero parameters, Constructor treated it as if it had one. I got it to list the parameter and found it odd that it needed a Sandbox class (I assume the one I'm currently working in) To allow a non-static class, I would need to change my newInstance code to this:
type.getConstructor(this.getClass()).newInstance(this);
and this works as well