To be clear: I have an object which is continiously changing its values during the runtime and I want to save the created and modified object on a file.
I found how to that and I found also how to read back the object saving it into one another. But the question is: is it possible to call the class constructor of my object with the only parameter of the file in which the object I want to retrieve is stored?
NeuralNetwork(File fs){
ObjectInputStream ois;
changeFileSave(fs); //just sets the file as savefile for the future
try{
ois = new ObjectInputStream(new FileInputStream(_saveNet)); //_saveNet = fs
this = (NeuralNetwork) ois.readObject();
}
catch(Exception e){
//error message
}
}
It gives me an error on 'this ='
If it's possible how do I do something like this?
Thank you
The keyword this is a read-only reference, you can never write this = even in the constructor. Moreover, the constructor in java does not return anything.
You would have to take the object you've read and map its properties one by one (or using reflection) to the properties you have in the object you're instantiating.
However, I would submit that by passing a file to a constructor and doing the IO in it you are violating separation of concerns. By writing things this way, you have forever tied a neural network to a File, with a whole host of attendant issues, including (not limited to) the fact that you may be storing your values elsewhere at some point.
IMO you are better off using a factory pattern to build your object and making your NeuralNetwork object a plain object. Then the ambiguity disappears because your factory method can simply return (NeuralNetwork) ois.readObject();
this = (NeuralNetwork) ois.readObject();
Consider this as a hidden final argument that points to the instance that is executing the method. Its value cannot be changed. If you want to make a variable point to an instance, there's no problem with that, as long as you don't use this.
What you want to do is more appropriate for a factory or factory method than for a constructor. Use one of this patterns (or a static method if you want to keep it very simple) to create your instance from the file. Not sure if you need many instances of that class, but if you only need one, you should consider using a Singleton getInstance() method instead the previously mentioned.
You can't assign this, since it is readonly. this always points to the instance itself and is used throughout the life of the object to access its methods and attributes.
If you want to create an instance of your NeuralNetwork class by reading data from a file, you could use a factory method:
public class NeuralNetwork {
private NeuralNetwork() { // private constructor forces us to use the
} // factory method to create instances
public static NeuralNetwork loadFromFile(File fs) {
ObjectInputStream ois;
this.changeFileSave(fs); // just sets the file as savefile for the future
try {
ois = new ObjectInputStream(new FileInputStream(_saveNet));
return (NeuralNetwork) ois.readObject();
}
catch(IOException e){
throw UncheckedIOException(e);
}
}
// other methods and attributes
}
Then, wherever you use your NeuralNetwork class and need an instance, use:
NeuralNetwork network = NeuralNetwork.loadFromFile(someFs);
// use network instance and have fun with it here
Note 1: I've defined a private constructor to force everyone use the loadFromFile factory method to create an instance. This means that this class can only be created from within a static method of this class.
Note 2: I've also rethrown the exception with an unchecked exception. This is personal taste. I wouldn't just log the exception and go on. Instead, I would throw the exception so that the caller handles it properly, because it doesn't make any sense to go on if an instance of the class hasn't been created. If you don't want to rethrow the exception as an unchecked one, just don't catch the original IOException and add a throws IOException clause to your factory method. This would force the callers of loadFromFile to catch the IOException and handle it.
Related
I have two ClassLoaders which loads the same class. So, obviously these can't cast to one another. But I need to access an object created in the other ClassLoader.
I have access to both ClassLoaders. How can I use that object in the other class? I don't need to cast the object to match to the current ClassLoader.
But the issue is that the returned object's type is Object. So, I have to cast down that object to access some methods. How can I do that? Normal cast like the following causes ClassCastException, which I already know.
Mojo mojo = (Mojo) descriptor.getMojo();
descriptor#getMojo() returns an object of type Mojo but the method returns Object. How can do this?
Let me know if you need further info.
I've read all the theories about classloading, but none has specified a proper solution for this.
AFAIK, no, you can't cast an object of a class loaded by one class-loader in another class loader.
One solution would be to create a "common" class-loader which loads the classes to be used by your custom classloaders. So in your case, you'd have a new classloader which would load the given class and your custom classloaders would extend this classloader.
Another solution would be to pass around the "serialized" state between the two classloaders. Serialize one instance to a byte array and reconstruct the object in the other classloader by de-serializing the object stream.
Reflection isn't that bad, and is appropriate here.
Is this a Maven plugin, BTW?
You'll want something like:
Mojo mojo = (Mojo)descriptor.getClass().getMethod("getMojo").invoke(descriptor);
I'm leaving out a lot - particularly exception handling - but this should lead you to the Javadoc you need. It's quite good, but read carefully.
If you also have two Mojo classes, the cast will break, and you'll have to do more reflection to do whatever you need to do with the evil-twin Mojo.
I think better option to just store byte array instead of object. While deserliazing, get byte array back and convert into object.
I had the same issue and byte array approach worked.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(cachedValue);
byte b[] = bos.toByteArray();
//Store in DB, file wherever here using b[]. I am not writing code to store it as it may vary in your requirement.
} catch (IOException e) {
e.printStackTrace();
}
Read from byte array:
ByteArrayInputStream bis = new ByteArrayInputStream(<<read byte[] where you stored earlier>>);
ObjectInput in = null;
try {
in = new ObjectInputStream(bis);
<Your Class >cachedRes = ( Your Class) in.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Why you have 2 CloassLoaders, which loads the same class? This could be a programatic issue. It sounds like you are caching ClassLoader somewhere and re-use them in a wrong way. If this is not the case try a MultiClassLoader.
Create a MultiClassLoader which includes multiple other classloader. These MultiClassLoader you can use to load all Classes you wish. But you have to create these MultiClassLoader at the very beginning and not when the classes are loaded.
public class MultiClassLoader extends ClassLoader
You would have a collection of classloaders and in the findClass(...) you iterate over all these registered loaders.
protected Class findClass(String aName) throws ClassNotFoundException {
for (Iterator iter = multiLoaders.iterator(); iter.hasNext();) {
ClassLoader tmpLoader = (ClassLoader)iter.next();
try {
return tmpLoader.loadClass(aName);
} catch (ClassNotFoundException e) {
}
}
throw new ClassNotFoundException(aName);
}
The easiest way is to use reflection. This allow you to dó anything you Can dó in "normal" code.
I solved this issue by loading the fully qualified class using Thread's parent context loader.
As an example, using AbstractMojo here.
Thread
.currentThread
.getContextClassLoader
.getParent
.loadClass("org.apache.maven.plugin.AbstractMojo")
Within a method, I have an exception being caught which I want to mock.
I know how to mock an object to throw an exception using mock.doSomething(), but I need to throw a remote exception when a class makes a new instance of itself.
transient Bicycle bike = null;
public Bicycle getBicycle() {
if (bike == null) {
try {
bike = new Bicycle(this);
} catch (RemoteException ex) {
System.out.println("No bikes found");
}
}
return bike;
}
I want to be able to mock everything in the try block, but I don't understand how you mock the creation of a new class, the following line to be specific:
bike = new Bicycle(this);
I have tried many different Mockito tests, such as:
Bicycle b = mock(Bicycle.class);
Mockito.doThrow(new RemoteException()).when(b = new Bicycle());
Although I understand this will and is not working, I want to do something similar.
I have read the Mockito docs and haven't found anything useful:
http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html
You don't generally mock constructors. You can do with tools like PowerMock, but I'd generally suggest you don't.
Currently, your code isn't actually testable, if you want to control what happens when a new Bicycle is constructed. Is constructing a Bicycle actually a complex operation? Perhaps you want a BicycleFactory, which can be passed into your class as a dependency, for example - then you could mock BicycleFactory.createBicycle or whatever you call it.
Constructors are like static methods - when you use them, you're tightly bound to the specific code you're calling; there's no clean way to inject other behaviour without approaches like PowerMock's.
You can use a Mockito extension, PowerMock, in cases like this. It allows constructors to be mocked (see https://code.google.com/p/powermock/wiki/MockConstructor).
In this case, you would write something like the following test:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ClassUnderTest.class, Bicycle.class})
public class ConstructorMockingTest
{
#Test
public void getBicycle()
{
ClassUnderTest tested = new ClassUnderTest();
whenNew(Bicycle.class).withArguments(tested).thenThrow(new RemoteException());
Bicycle bicycle = tested.getBicycle();
assertNull(bicycle);
}
}
More examples can be found at: https://code.google.com/p/powermock/source/browse/trunk/modules/module-test/mockito/junit4/src/test/java/samples/powermockito/junit4/whennew/WhenNewTest.java
Your getBicycle() now does at least two things. It retrieves ("gets") a Bicycle, and it creates a Bicycle. Ideally a method or class should do only one thing, and do it well.
Put the creation of the object in a separate method createBicycle() or separate BicycleFactory and mock that.
I'm making a Java application that has basic Saving / Opening capabilities. All I need to save is the instance of my class ModeleImage which is a Singleton. My saving apparently works and looks like this:
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(ModeleImage.getInstance());
outputStream.flush();
outputStream.close();
Now I'm trying to open that file with ObjectInputStream. I'm not sure if there's a way to simply replace my Singleton (ModeleImage) with the saved one but right now I'm only trying to copy and replace each attribute. My opening looks like this:
FileInputStream fis = new FileInputStream(fileChooser.getSelectedFile());
ObjectInputStream ois = new ObjectInputStream(fis);
//Get each attribute from the file and set them in my existing ModeleImage Singleton
ModeleImage.getInstance().setImage(((ModeleImage) ois.readObject()).getImage());
ModeleImage.getInstance().setLargeurImage(((ModeleImage) ois.readObject()).getLargeurImage());
ModeleImage.getInstance().setHauteurImage(((ModeleImage) ois.readObject()).getHauteurImage());
ModeleImage.getInstance().setxImage(((ModeleImage) ois.readObject()).getxImage());
ModeleImage.getInstance().setyImage(((ModeleImage) ois.readObject()).getyImage());
I also put try/catch around each. The problem is that my opening part catches an IOException when trying to replace attributes.
ModeleImage.getInstance().setImage(((ModeleImage) ois.readObject()).getImage());
//This catches an IOException
What am I doing wrong?
Is it because it's a Singleton or am I misunderstanding how ObjectInputStream and readObject() work?
By using a built-in feature of the serialization mechanism, you can enhance the normal process by providing two methods inside class file. Those methods are:
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
Implement this methods by ModeleImage class and you will control all aspects of serialization and have access to internal state of singleton.
You should only be calling readObject() once since you only wrote one object:
ModeleImage image = ois.readObject();
ModeleImage.getInstance().setImage((image.getImage());
ModeleImage.getInstance().setLargeurImage(image.getLargeurImage());
ModeleImage.getInstance().setHauteurImage((image.getHauteurImage());
ModeleImage.getInstance().setxImage(image.getxImage());
ModeleImage.getInstance().setyImage(image.getyImage());
What you should do is have a static block that checks an instance of your class that you serialized. If it can, find it, it sets it to your singleton instance (thus making sure you load the one from the file). If it can't find it (perhaps first time your program is launching), then it should create an instance and assign it to your singleton variable.
You could create a save method or what not, or override the finalize method to save off your singleton so that way you can check for it in the static block on next time it is class loaded.
Make sense?
Implement readResolve on your serializable Singleton class to ensure there is only ever a single instance and override the properties there, i.e.
private Object readResolve() throws ObjectStreamException
{
instance.setImage(getImage());
instance.setLargeurImage(getLargeurImage());
...
return instance;
}
this concept is described nicely on http://www.javalobby.org/java/forums/t17491.html or check out http://docs.oracle.com/javase/1.3/docs/guide/serialization/spec/input.doc6.html for more on readResolve(). Hope that helps.
I'm working on a simple plugin system, where third party plugins implement a Plugin interface. A directory of JARs is scanned, and the implementing classes are instantiated with Constructor#newInstance.
The thing is, these plugins call back into register* methods of the plugin host. These registrations use the Plugin instance as a handle. My problem is how to clean up these registrations if the constructor decides to fail and throw halfway through.
InvocationTargetException doesn't seem to have anything on it to get the instance. Is there a way to get at the instance of an exception throwing constructor?
P.S.: It's typically strongly advised to users that the constructor not do anything, but in practice people are doing it any ways.
What you are in effect asking is whether there is a way to get hold of the (partial) instance when a constructor throws an exception.
The answer is No. But it is not because the instance is "dead". In fact the reference to the instance could still be reachable and usable by other parts of the application ... if it has been "published" before the constructor completed.
The real reason is that neither creating or throwing an exception records the instance associated with the method or constructor doing the creating / throwing.
You will need to solve this some other way. My suggestion is you make it a rule that these plugin classes must only register the instance as the last statement of the constructor; i.e. when no more initialization-related exceptions could be thrown.
Is it possible to do the registration through a holder object which is then used for actual plugin registration after the plugin class has been constructed successfully? I'm thinking of something like this:
public class MyPlugin extends BasePlugin {
public MyPlugin(PluginRegistry registry) {
super(registry);
// here be things which may cause an exception
// to be thrown, among other things
}
}
public interface PluginRegistry {
// method(s) for registration
}
public class PluginRegistryHolder implements PluginRegistry {
// implementations of the required method(s) for registration
// also a method for getting temporary registration data from within the class
}
// Actual usage in your code
public void registerPlugin(final String className) {
PluginRegistryHolder h = new PluginRegistryHolder();
Constructor c = /* acquire correct constructor, omitted for clarity */
try {
Object o = c.newInstance(new Object[] {h});
this.actualRegistry.register(o, h.getRegistrationData());
} catch (Throwable t) { /* die */
}
}
So basically handle the registration gracefully and never let the plugin class register directly but instead through a managed proxy.
In Java, it is possible to get the class and method that called the current method (the method in which you get the StackTrace).
Can I get the arguments that were passed to the method that called this method?
I need this for debugging purposes.
Eg:
baseClass {
initialFunc(input) {
var modifiedInput = input + " I modified you";
otherClass.doSomething(modifiedInput);
}
}
otherClass {
doSomething(input) {
//GET THE ARGUMENTS PASSED TO THE METHOD OF THE CLASS THAT CALLED THIS METHOD
}
}
Can one get this information from the stacktrace, or are there other means?
(Note that I need to be able to do this in runtime and cannot actually change the source of baseClass, this is going to be a feature of my debugging class that does not know the source beforehand)
I don't believe this is possible using the standard Java API.
What you could do is to use AspectJ, place a point-cut at the calling method, save the arguments, place a point-cut at the called method and pass on the arguments.
Another option (slightly more advanced) is to use a custom, bytecode-rewriting, class loader that saves the original arguments, and passes them on as extra arguments to the next method. This would probably take a day or two to implement. Suitable frameworks are BCEL or ASM.
I think this could be possible, because input is out of scope but isn't yet accessible for garbage collection, so the value still exists, but unfortunately I don't believe there is an default API way to access it. This could be maybe possible with a custom implemented NDC (nested diagnostic context) for the logging approach.
I'm not sure why you'd ever want to do this in Java?
The only way I can think of is to create a custom wrapper object for the passed string, thus sending the reference to the wrapper instead of a new string each time.
I'd advice against it, though, since it clutters your original code, and makes it even more error prone.
Might this problem not be solved using a debugger, like the one built into eclipse, to inspect your state?
In my case, I needed to get a parameter value has been passed to a method in a certain stack frame to be used later within the execution flow
I used ThreadLocal to store it and when I needed it I was able to retrieve it at any point in code as I declared it as public static
here is a skeleton example
public static final ThreadLocal<SomeType> IMPORTANT_THREAD_LOCAL_FOR_BLA = ThreadLocal.withInitial(whatever);
methodWithImportantParam(SomeType importantValue){
// save it in the static threadLocal Field
this.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()=importantValue;// code to set the value
// continue method logic
}
and somewhere in code where you need that value
YourClass.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()
but make sure the execution flow that you set the value then you retrieve it
hope my answer add something valuable to this question
You can get name of caller method and its class, but you have to add some code in current method:
public static void main(String[] args) throws Exception {
call();
}
private static void call() {
Exception exception = new Exception();
for(StackTraceElement trace : exception.getStackTrace()){
System.out.println(trace.getMethodName());
}
}
This will print "call" and "main", methods name in called order (reverse).
This is possible using Reflection API !
public class StackTrace {
public static void main(String args[]) {
StackTrace st = new StackTrace();
st.func();
}
public void func() {
OtherClass os =new OtherClass();
os.getStackTrace(this);
}
}
class OtherClass {
void getStackTrace(Object obj) {
System.out.println(obj.getClass());
}
}