the question might be a bit vague because i'm not sure how to put the scenario into context.
I'm trying to implement a factory pattern for object creation on my current Java program, which is a standalone app. I tried to use the self-registering way of creating the object list in the factory, as detailed in here
I encountered an error along the way though, that the static block in the object was never executed, and the list remained empty. I did a bit of research and found that the static block will only be executed one time, during the time when the class is loaded by the JVM.
That wonders me though, because i'd used the same method on a Android application before, and it worked without an issue. The static block will just execute to register the object itself to the factory.
Is there a difference between these 2 VM that is causing this behavior?
Thank you
Related
Let's say I have a class which looks like this:
public class Initializer {
static { /* a bunch of stuff happens here that's useful */ }
}
basically it registers a bunch of other classes in a lookup table; it's connected to an annotation processor. Is it a weird design? I don't know, I don't have a good point of reference, I didn't write it, it's just how it is. If this class is loaded, then the initialization happens and we're good, and if it isn't, we're not good.
The problem is, there's no normal reason you would ever refer to this class, so the "normal" way you would make sure this class gets loaded is to execute Class.forName("a.b.c.Initializer"); somewhere in your app's initialization logic. That's not hard to do (I think SQL drivers are initialized similarly, unless they're wrapped in a helper function call).
But unfortunately it is sort of a strange step, and it's easy to forget, and it has opaque errors. Outside of providing a nicely named helper function MyLibrary.initialize() so you don't have to do an arcane Class.forName("darkest.magic") call, is there a way to make this completely automatic?
For instance, is there a way to either
Somehow rig up in the build.gradle file (of the package that needs initializing, or less desirably, the downstream package that uses it) that this class needs to be loaded?
Somehow set up code that must be run when this package is loaded?
Would appreciate any suggestions or workarounds so that users don't have to explicitly initialize "my" library. Thanks.
I've inherited a Struts2 project which needs some functionality addition. When I ran into de code to guess how the previous guy did things, I found out that if he wants a class to instantiate only once when the Tomcat server starts (because it has to read heavy loads of data from disk, but only once to get its config, for instance), he did this in the following way:
public class ExampleClass {
public ExampleClass(){//Read files and stuff to initialize}
public Object method(Object[] args){//The job to do}
}
And then, in the struts action which uses it he instantiates it this way:
public class SomeAction extends ActionSupport {
ExampleClass example = new ExampleClass()
public String execute() {
//Do stuff every time the action is called
Object result = example.method(args);
// Do stuff with results
}
}
I know from servlet times that this does the trick, however, I feel like the guy who handled this before was as inexperienced in Struts2 as I am, so here comes my question:
Is this the proper way to do so according to style recommendations and best practices? Does struts2 provide a more controlled way to do so?
I found some answers related to simple parameters here, but I'm not sure if this is the proper way for objects like those? What would happen if ExampleClass instance is really heavy? I don't want them to be copied around:
How to set a value in application scope in struts2?
Some background about ExampleClass: When the constructor is called, it reads large sets of files and extracts it's configurations from them, creating complex internal representations.
When method() is called, it analyzes it's parameters using the rules, and outputs results to the user. This process usually takes seconds, and doesn't modify the previously initialized rule values.
This is running in Tomcat 7, however, I'm planning to upgrade to Tomcat 8.5 when everything is in place. I'd like to know if there are known issues about this regarding to this setup aswell (there are no other incompatibilities in the code).
BTW: He's not checking if ExampleClass is broken or anything like that, this definetly looks like a recipe to disaster xD. In fact, If I remove the source files, it is still trying to execute the method()... Poor soul...
Ideally, I need a way to instantiate all my application-level objects on start-up (they're the application itself, the rest is just a mere interface) in a way that if they fail Struts2 will tell Tomcat not to start that war, with the corresponding error logging and so on.
If Struts2 doesn't support this, which is the commonly accepted work-around? Maybe some Interceptor to check the object status and return to a error page if it hasn't been correctly instantiated? Execute a partial stop of tomcat from within?
All the objects of this project are thread safe (the only write operation inside them is performed on initialization), but I'd like to know best practices for Struts2 when objects are not so simple. What happens if a user can actually break one? (I know I should by any means avoid that, and I do, but mistakes happen, so I need a secure way to get through them, and get properly alerted, and of course I need a way to reinstantiate it safelly or to stop the whole service).
Right now, I can manually execute something like:
public class SomeAction extends ActionSupport {
ExampleClass example = new ExampleClass();
private boolean otherIsBuildingExample = false;
public String execute() {
if(otherIsBuildingExample) return '500 error';
if(example==null || example.isBroken()){
otherIsBuildingExample = true;
example = new ExampleClass();
otherIsBuildingExample = false;
}
Object result = example.method(args);
// Do stuff with results
}
}
Indeed, this would be cleaner with Interceptors, or so, however, this sounds like a pain in the *** for concurrency, specially taking into consideration thay example takes several seconds to start, and that more requests can come, so more concerns to take into consideration, like: what if two people call if(otherIsBuildingExample) and the second one gets the value before the first one performs otherIsBuildingExample=true? Nothing good... If the class is simple enough, both will instantiate and the slower one will prevail, but if one instantiation blocks the other's resources... well, more problems.
The only clean solution I can think of is to make ExampleClass robust enough so you can repare it using its own methods (not reinstantiating) and make those thread safe in the common way (if 10 people try to repair it, only one will proceed, while the others are just waiting for the first to end to continue, for instance).
Or maybe everytime you call execute() you get a copy of example, so no worries at all about this?
I'm digging into struts documentation
Thanks in advance.
We are building xPages applications on Domino 8.5.2 that use custom Java Beans, and from time to time the dev server encounters a java/lang/OutOfMemoryError. It all works fine again after the http task is restarted, but of course this is an absolute killer if it happens on a customer's server. So I had a look at the heapdumps in Eclipse Memory Analysis, and checking for the top consumers I get this:
screenshot 1
Obviously the class BCCPropertyStore is instanciated so often that it makes up 20% of the entire heap, although it is supposed to be singleton. The class begins like this:
public class BCCPropertyStore {
// Constants
private static final String CLASS_NAME = "BCCPropertySynch ";
private static BCCPropertyStore instance = new BCCPropertyStore();
...
public static BCCPropertyStore getInstance() {
return instance;
}
And every time it is used we call it with BCCPropertyStore.getInstance(), which is static, so my understanding is that there should not be multiple instances of it (the Java beans usually are in application scope, so I don't see why they should have multiple instances either).
However, if I look at the duplicate classes it is striking that there also a lot of xPages-classes appearing much more often than they should:
screenshot 2
There are no thousands of users logging into the application for whom all these instances could have been created, just me and a fellow developer. HTTPJVMMaxHeapSize is set to 256M, which in theory should be more than sufficient for an application of the size of this one.
Why is the JVM creating so many useless instances of classes until it runs out of memory, and why are they not snuffed out by the garbage collector? Is this an xPages-specific issue or did I miss something?
UPDATE
Today the error occured again and I am no wiser. I changed BCCPropertyStore into enum as suggested below, obviously that didn't change anything as the heap dump looks pretty much the same as in the screenshots I posted before.
Is there any tool with which we can monitor the memory usage of the JVM while it is running, or something similar which helps us to determine if the fixes and suggestions are working or not?
Here is the stacktrace:
2013-05-07T10:44:32.441+02:00
java.lang.RuntimeException: com.ibm.xsp.FacesExceptionEx: java.lang.OutOfMemoryError
at com.ibm.designer.runtime.domino.adapter.ComponentModule.initModule(ComponentModule.java:433)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.initModule(NSFComponentModule.java:427)
at com.ibm.domino.xsp.module.nsf.NSFService.loadModule(NSFService.java:561)
at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:521)
at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:342)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:304)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:261)
at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:291)
Caused by: com.ibm.xsp.FacesExceptionEx: java.lang.OutOfMemoryError
at com.ibm.xsp.config.CLBootStrap.initContext(CLBootStrap.java:73)
at com.ibm.xsp.config.BootStrap.init(BootStrap.java:60)
at com.ibm.xsp.config.ConfigureCoreListener.contextInitialized(ConfigureCoreListener.java:58)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.initModule(ComponentModule.java:425)
... 7 more
Caused by: java.lang.OutOfMemoryError
at java.util.Hashtable.newEntry(Hashtable.java:91)
at java.util.Hashtable.put(Hashtable.java:766)
at java.util.PropertyPermissionCollection.add(PropertyPermissionCollection.java:40)
at java.security.Permissions.add(Permissions.java:98)
at org.apache.harmony.security.fortress.PolicyUtils.toPermissionCollection(PolicyUtils.java:541)
at org.apache.harmony.security.fortress.DefaultPolicy.getPermissions(DefaultPolicy.java:242)
at org.apache.harmony.security.fortress.DefaultPolicy.implies(DefaultPolicy.java:365)
at java.security.ProtectionDomain.implies(ProtectionDomain.java:159)
at java.security.AccessController.checkPermission(AccessController.java:98)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:533)
at org.eclipse.osgi.framework.internal.core.Framework.checkAdminPermission(Framework.java:1299)
at org.eclipse.osgi.framework.internal.core.BundleHost.getResource(BundleHost.java:266)
at com.ibm.domino.xsp.module.nsf.Activator.findResource(Activator.java:84)
at com.ibm.domino.xsp.module.nsf.Activator.findResource(Activator.java:103)
at com.ibm.domino.xsp.module.nsf.Activator.findResource(Activator.java:103)
at com.ibm.domino.xsp.module.nsf.Activator.findResource(Activator.java:67)
at com.ibm.domino.xsp.module.nsf.NotesClientClassLoader.getResource(NotesClientClassLoader.java:130)
at java.lang.ClassLoader.getResource(ClassLoader.java:438)
at com.ibm.domino.xsp.module.nsf.ModuleClassLoader.getResource(ModuleClassLoader.java:117)
at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:503)
at javax.xml.parsers.SecuritySupport$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(AccessController.java:202)
at javax.xml.parsers.SecuritySupport.getResourceAsStream(Unknown Source)
at javax.xml.parsers.FactoryFinder.findJarServiceProvider(Unknown Source)
at javax.xml.parsers.FactoryFinder.find(Unknown Source)
at javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source)
at org.apache.commons.digester.Digester.getFactory(Digester.java:512)
at org.apache.commons.digester.Digester.getParser(Digester.java:686)
at org.apache.commons.digester.Digester.getXMLReader(Digester.java:902)
at org.apache.commons.digester.Digester.parse(Digester.java:1548)
at com.sun.faces.config.ConfigureListener.parse(ConfigureListener.java:1229)
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:328)
at com.ibm.xsp.config.CLBootStrap.initContext(CLBootStrap.java:65)
... 10 more
2013-05-07T10:44:33.879+02:00
java.lang.OutOfMemoryError
at java.util.HashMap.newElementArray(HashMap.java:282)
at java.util.HashMap.rehash(HashMap.java:686)
at java.util.HashMap.rehash(HashMap.java:730)
at java.util.HashMap.putImpl(HashMap.java:611)
at java.util.HashMap.put(HashMap.java:605)
at com.ibm.domino.xsp.module.nsf.RuntimeFileSystem.refresh(RuntimeFileSystem.java:269)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.initNSFData(NSFComponentModule.java:565)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doInitModule(NSFComponentModule.java:439)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.initModule(ComponentModule.java:412)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.initModule(NSFComponentModule.java:427)
at com.ibm.domino.xsp.module.nsf.NSFService.loadModule(NSFService.java:561)
at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:439)
at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:342)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:304)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:261)
at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:291)
2013-05-07T10:46:17.582+02:00
java.lang.OutOfMemoryError
at java.util.HashMap.newElementArray(HashMap.java:282)
at java.util.HashMap.rehash(HashMap.java:686)
at java.util.HashMap.rehash(HashMap.java:730)
at java.util.HashMap.putImpl(HashMap.java:611)
at java.util.HashMap.put(HashMap.java:605)
at com.ibm.domino.xsp.module.nsf.RuntimeFileSystem.refresh(RuntimeFileSystem.java:269)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.initNSFData(NSFComponentModule.java:565)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doInitModule(NSFComponentModule.java:439)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.initModule(ComponentModule.java:412)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.initModule(NSFComponentModule.java:427)
at com.ibm.domino.xsp.module.nsf.NSFService.loadModule(NSFService.java:561)
at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:439)
at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:342)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:304)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:261)
at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:291)
This is a long shot but I have heard that many java enterprise servers have problems with memory leaks connected to classloaders, static objects and application redeployment.
Could You possibly check if it is possible to recreate java/lang/OutOfMemoryError through repeating clean/run application cycle?
To make this problem lesser You could try to move your static objects to application scope.
Why is the JVM creating so many useless instances of classes until it
runs out of memory?
It must not think they are useless.
why are they not snuffed out by the garbage collector?
Because something still carries a reference to them. Since the class carries it's own static reference, I suspect it's that.
Is this an xPages-specific issue or did I miss something?
The code provided here is inadequate to determine the cause, since we don't see the constructor for the BCCPropertyStore. Also we don't know whether in addition to making this class a Singleton, you have also put it in a scope that could cause it to be serialized.
The very first suggestion I would offer is to switch to the enum pattern for defining a singleton.
public enum BCCPropertyStore {
INSTANCE;
public static BCCPropertyStore getInstance() {
return INSTANCE;
}
}
Is there a reason for not using a managed bean instead of an unmanaged one? If you have a managed bean scoped to application, you can still access it from Java using ExtLibUtil.resolveVariable(). That way it will only create one instance, the JVM (specific to the NSF) will create it when needed and remove it for you when unloaded. So you won't need a static reference to the class inside itself.
If you don't have the Extension Library, looking at the code for that will give you what you need for a static method.
Over and above Nathan's comments above.... You should also use Disk Persistence (ie: Save pages to disk) instead of the in-memory options for heavy-weight custom Java objects - particularly important if high-end scalability is required. In doing so, ensure your bean and it's members are either serializable and/or transient accordingly. This approach will radically reduce heap space usage - disk space is cheaper then RAM too!
I have created a Singleton for my class which contains an instance of MemcachedClient (this could be any object that requires making a connection to a server but I am providing a concrete example). I initialize the MemcachedClient in a static init block. If the MemcachedClient cannot create an instance due to a connection error, this now means my class is worthless because it has a null MemcachedClient instance.
My question: What is the best solution for this type of situation? How are other people handling this situation?
The question (as stated in the title) is too broad, it depends of what the singleton is for.
In your case, the obvious question: if the initialization fails, can you expect that the issue will be solved in the near future? What is the cost of keep trying (redesign so your app does not crashes downward in weird ways) instead of just rebooting your app?
If you do not expect the error to be solved easily, just crash your application (with the proper logs/alerts/notifications). If you want it to keep running until the issue resolves, then the steps would be:
1) Pass the initialization to the constructor of the singleton (why put it in a static block if you can control access to the constructor).
2a) While the constructor fails, calls to getInstance will return null. Modify your application to be able to handle it.
2b) If the issue is present, create a singleton without the proper initialization. Calls to the methods of this objects will do nothing until the initialization issue has been solved / the object has been initialized. Modify your application to be able to handle these dummy methods. This method is swifter but way more complicated.
3) When a new instance is requested (if 2a) or a method is called (if 2b), check again if the object can be initialized.
Compare the cost of all the previous with the cost of just restarting your app after the issue has been solved.
I am looking for a way to remove all uses of a particular class, including the class itself, at compile time. Basically a form of pre-processing, but I'd like to do it without having to surround all the instances with #ifdebug ... #endif.
Is there any ant-based tool out there that can do this? If not, can anyone point me in the right direction for how to write such a tool? (not a minor undertaking I know, but if its the only option...)
The situation is I have a helper class for debugging function calls. This is instantiated at the beginning of a function and a call is made at the end. This is a JavaME application so I'm nervous about the overhead this is adding to performance. I already have a release and debug build that have pre-processor directives using ProGuard, so I would like to exclude the use of this helper class from the release build. It doesn't appear this can be done with ProGuard.
"This is instantiated at the beginning of a function and a call is made at the end. "
If this is all over your code maybe you need to look at AOP.
or a state design pattern for the helper class, in test mode it does one thing but in prod it does another(like nothing)
Do you know that this debug code will make the JavaME app slow? You could also try creating a way to conditionally call these debug methods.
A few more ideas ... I've never written a JavaME app, but I assume there is way to run/test with running on the actual device. Given this way of running/testing, perhaps you can use Eclipse/Netbeans to debug your code and use proper breakpoints instead of programmatically tracing method calls. No harm to compiled code in this case. Also consider using AspectJ to trace method calls, this can be conditionally done after code is compiled since AspectJ alters bytecode directly (not sure how this plays with JavaME). Lastly, I've heard of people using the standard GNU C/C++ preprocessor on Java. I have no idea if it works, google will help you.
Not exactly what you want but...
You could separate your code to modules (core and debug, in your case), then make sure modules call each other via reflection: use an interface available in core, create a wrapper class in core that will hide object instantiation via reflection detail/
Then, on production, just omit the debug code and have the wrapper "do nothing" if the instantiation fail / when you set a specific flag.
This way your debug classes won't make it into production and you won't have to "statically link" to them so your core production code won't care.
Of course, this is only possible if your debug code has no side effects visible to core code, but it seems that's your case (from your problem description).
Is it possible to just create the class once, on application startup, instead of creating an instance for each method? Your debug class could then look like this:
public class Debug // maybe make this a *gasp* singleton?
{
public static void start(); // called at start of method
public static void end(); // called at end, probably should be in a finally block
public static void setDebugMode(boolean debugOn); // turn off for production mode
}
Set debug mode to "true" in testing but "false" in production. When debug mode is off, none of the methods do anything (except check the state of debug mode, of course).
You don't avoid the overhead of the function call, and you do need to check the state of that boolean, but you do get to avoid jumping through hoops trying to avoid load the class at all.
This will need more work if you have a multithreaded application, too.