reflection classes keeps on increasing - java

I could see in my application that no of loaded classes keeps on increasing as discussed here.
On using yourkit and help from the stack overflow community ,I was able to conclude that the classes getting increased is because of the reflection classes getting dynamically created as listed below:
GeneratedConstructorAccessorXX
GeneratedMethodAccessorXX
GeneratedSerializationConstructorAccessorXX
where XX is some number.
As per my knowledge and what I have come to know after googling, These are kind of runtime proxies used by reflection to access object information which is stored in the memory.These accessors are cached so that they dont have to be regenerated each time. These class objects are singleton per classloader, and hence we have only one instance of a generated accessor per classloader of a given Class.
If this is the case,why I see the increase of loaded classes when I am running the repeat test.
Update*
On further analysis I have observed that increased load is specifically because of
GeneratedSerializationConstructorAccessor.

I will share my findings below and will accept this as answer unless someone else comes with something better.
On further analysis and checking the stacktraces using your kit I was able to see thatGeneratedSerializationConstructorAccessor was getting created when any EJb bean calls was being made.Though it wasnt for every request that new such class was getting created.
Another observation that found was that another application using EJB beans was also deployed on the same jboss server and was part of the test but we were not facing any such issue there.
One difference I could see was that the later application where no such issue was found was using EJB 3.X and where issue was found was having 2.X.
May be it is the legacy version which is creating issue.
It has been identified not a show stopper and its performance will be watched on the production.

Related

Instancing XMLStreamWriterFactory failed: unsupported property isRepairingNamespaces

In our application we encounter very sporadic run time exceptions which crash our message processors (which are stand-alone java processes running on Java 8). The processors, at the time of this exception, generally try to execute a web service call.
The exception are
java.lang.Error: Failed to create new instance of com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory$1
at com.sun.xml.internal.ws.api.streaming.ContextClassloaderLocal.createNewInstance(ContextClassloaderLocal.java:63)
..
Caused by: java.lang.IllegalArgumentException: Unable to access unsupported property javax.xml.stream.isRepairingNamespaces
at weblogic.xml.stax.ConfigurationContextBase.check(ConfigurationContextBase.java:90)
The strange thing is, the whole application is running without errors 99.9% of the time: the above exceptions happen quite infrequently (ca. every couple of days). After a crash, the processors are restarted automatically, and again operate perfectly fine, until the same exception occurs again after a seemingly random interval.
So far we could not correlate this with any misbehavior on the part of the JVM or the host the application is running on.
Does anyone have any pointers as to why such an unsupported property javax.xml.stream.isRepairingNamespaces exception could appear sporadically?
We're running jdk1.8.0_66 on Red Hat 4.8.5-4. Web service interfaces are generated using JAX-WS.
Edit:
I can't share the classpath (lots of internal info, sorry). We do have the Weblogic full client in there though: wlfullclient-12.1.3.jar. It defines an XML factory via ServiceLoader
META-INF/services/javax.xml.stream.XMLOutputFactory --> weblogic.xml.jaxp.RegistryXMLOutputFactory
Where as xml-apis-1.4.01.jar (also on classpath) contains javax/xml/stream/XMLOutputFactory.class (related to the exception thrown in ConfigurationContextBase).
Could this be part of the problem?
You have to change the class path order. At first point all the axis2 jars and then point the weblogic.jar in class path. Hope it will solve your issue.
I encountered this problem yesterday after making some significant changes to my code. This particular post is the ONLY information I can find by googling this particular error -- always a bad sign. After hours and hours of fruitless deep debugging, comparing the original working version of the code with the new non-working version, I decided to start backing out my code changes to see where/when the problem originated. Well, after backing out pretty much every single code change, the problem was still happening. I finally realized that this problem was perhaps external to the code. It turns out that at some point, I had added an extraneous library: wstx.jar to my lib directory. Once I removed that lib, everything worked great. So apparently it was utilizing the wrong classes to try to perform this operation.
Not sure if that is of any assistance to you, but even if not, I thought someone someday might stumble onto this and find it to be useful.

javax.xml.ws.Service.getPort() continuously invoked leads to OOM in PermGen

Improving java application, we are now facing migration from Axis to Jax-WS.
Currently we encounter the following problem: in our generated service class, inherited from javax.xml.ws.Service there is a call to Service#getPort
#WebEndpoint(name = "SomeServiceSoap")
public SomeServiceSoap getSomeServiceSoap() {
return super.getPort(new QName("http://something", "SomeServiceSoap"), SomeServiceSoap.class);
}
and this method is called each time when we want to execute method on this service. However, in tests it leads to OOM in permgen.
Should I avoid calling it more than once - by creating cache/pool or other storage for returned objects? Or am I missing some other important feature of this implementation.
Though I did not found how exactly jax-ws implementation do this nasty trick, I've discovered instead that to avoid problem I need to change jaxws-rt from version 2.2.6 (which was used in our pom-files, but is almost two year old) to 2.2.8.
This library version change completely fixes the issue. I've tested it both in Java 6 and Java 7.

How do I control which ClassLoader loads a class?

The situation at hand is not as simple as the title seems to indicate.
Java 1.6_17 running via JWS.
I have a class, lets say MyClass and one of its instance member variables is a Type from an errant 3rd party library where during class initialization it dynamically tries loading some of its own classes with Class.forName(String). In one of these cases it happens to dynamically call: Class.forName("foo/Bar").This class name doesn't follow the JLS for binary names and ultimately leads to a java.lang.NoClassDefFoundError: foo/Bar.
We have a custom ClassLoader which I've added a sanitize method to ClassLoader.findClass(String) and ClassLoader.loadClass(String) which fixes this problem.
I can call stuff like:
myCustomClassLoader.findClass("foo/Bar")
Which then loads the class without any problems. But even if I load the class ahead of time, I still get the exception later. This is because during initialization of MyClass which refers to Bar - their code ends up calling Class.forName("foo/Bar") in a static block somewhere. This actually would be OK if the ClassLoader it was trying to use was my custom class loader. But it isn't. It is the com.sun.jnlp.JNLPClassLoader which doesn't do such sanitation, thus my problem.
I've made sure that Thread.currentThread().getContextClassLoader() is set to my custom class loader. But this (as you know) has no effect. I even set it as the first thing i do in main() due to some stuff I read and still, MyClass.class.getClassLoader() - is the JNLPClassLoader. If I could force it to NOT be the JNLPClassLoader and to use mine instead, problem solved.
How can I control which ClassLoader is used to load the class via their static Class.forName("foo/Bar") call made during class initialization? I believe if I can force MyClass.class.getClassLoader() to return my custom class loader, my problem will be resolved.
I'm open to other options if anyone has ideas.
TL;DR: Help me force all Class.forName(String) calls in a third party library which are referenced by MyClass - to use the classloader of my choosing.
This reminds me of an article I read 10 years ago about the classloading arrangements in Java. It's still there on JavaWorld.
The article won't answer your question directly, but it may help understand your problem. You need to cause MyClass to be loaded through your custom class loader and trump the default class loading behavior, which is to first delegate class loading to the parent classloader and only attempt to load a class if that fails.
Allowing MyClass to get loaded by a classloader other than yours will store a relationship from the instantiated class to that classloader (via getClassLoader) and cause Java to use that other classloader to try to discover any referenced classes found at compile time, effectively bypassing your custom class loader by virtue of the class loader hierarchy and the delegation model. If MyClass is instead defined by your class loader, you get a second chance.
It sounds like a job for something like URLClassLoader, overriding loadClass and trumping the delegation model for classes residing in your JARs. You'll probably want to use a bootstrap approach (as suggested by Thomas in a comment above) to force a single entrypoint class to be loaded through your custom class loader, dragging all the others with it.
Also informative is this other JavaWorld article by the same guy, which warns you about the caveats of Class.forName. That too may trip your classloading arrangements.
I hope this helps and proves informative. In any case, it sounds like a difficult solution that is easy to break as your code evolves.
I think everyone gave good solid attempts at answering the problem. However, it turns out that I misdiagnosed the problem.
I had a coworker take over the problem and asked him to get a JDK with debug flags on so we could debug the JNLPClassLoader to see what was going on as I had tried all of the suggestions here + some.
We ended up getting OpenJDK because recompiling the JDK from scratch is a total nightmare (we tried). After getting OpenJDK working with our product and debugging through the JNLPClassLoader - it turns out that it was still using a REALLY old .jnlp from months earlier that had the resource path wrong and thus why it couldn't find the class.
We were confused why it was still using the ancient .jnlp even though we had redeployed the server correctly many times with the correct .jnlp and lots of code changes between which were reflected in our client application when run.
Well, it turns out that on client machines, Java caches the .jnlp file. Even if your application changes and it redownloads your application, it still won't re-download the new .jnlp for whatever reason. So it will use all of the new code, but look up resources/class paths using the cached .jnlp.
If you run:
javaws -uninstall
On the client machine then that will clear the .jnlp cache and next time it will use the correct .jnlp file.
Really sad that this was the problem. Hopefully, this saves someone else endless hours of frustration like it caused us.
If you run out of ideas with patching the ClassLoaders themselves, you might consider rewriting the library bytecode itself -- just replace the "foo/bar" constant with the correct value, and then you don't need to customize further class loading at all!
You could do this either at runtime or beforehand.

java.util.zip.ZipFile.ensureOpenOrZipException with WAS 7

The problem is exactly the same as described here:
Exception java.util.zip.ZipFile.ensureOpenOrZipException with WAS 7
Following the resolution, I changed my application module to 2.4 and it resolved the issue. I did not changed the path of wsdl as mentioned in the resolution. But once the application module is changed, the webservices.xml file is not getting generated. I need the xml file to be generated.
Anyone having any alternative solution to this problem where I do not need to change the application module?
Regards,
The original question you are referring to has two parts. One is about the ZIPException. Since that exception is triggered deep down in the WebSphere code it is unlikely that you will get a solution for that problem here. You should contact IBM support for that. The other part is about memory issues. From my experience with using JAX-WS services deployed on WebSphere (and using WebSphere in general), I can make two recommendations:
The original question says that the problem occurs "after few deployments". This poins to a class loader leak. A class loader leak is a particular kind of memory leak that prevents the old class loader of an application from being garbage collected after a redeployment or restart of the application (for a more detailed description, see here). This can be caused by the application or the server runtime. Experience shows that WebSphere itself has several issues that cause this type of leaks, and IBM is in general not very efficient in solving these issues. I once compiled a list of known WebSphere issues of this type that I have encountered. It is published here. One can see that basically any more or less complex Java EE application will be affected by this type of issue. Therefore you should be prepared for the fact that when redeploying frequently without restarting the server, it will eventually run out of memory.
Note: In defense of IBM it should be said that other application servers don't necessarily perform better in this area.
There is one particular case where JAX-WS services deployed on WebSphere may consume unexpectedly large amounts of memory. This occurs for services that have been developed using the top-down approach (i.e. starting from the WSDL), but that have #WebService annotations that don't refer to the original WSDL. In that case, WebSphere (quite correctly) believes that they are bottom-up services and generates WSDL and XML Schema documents based on the JAX-WS/JAXB2 annotations. These documents are kept in memory and in some cases (especially for complex services) may be significantly larger than the original WSDL and XML Schema documents. I've once seen an application that was consuming 200MB of heap just for that. To avoid this, make sure that when creating top-down JAX-WS services, you package the original WSDL and XML Schema documents in the application and that the service implementations have #WebService annotations that correctly refer to these documents.

Troubles with HTTP-MMO game in Java

I'm about to write a MMO, using HTTP-requests that are responsed with JSON.
I was writing it all in Java EE-style, hoping it won't be hard to port to Java EE than. But then I've found out that my static instance variables for a couple of sinletons weren't created properly - classloader made a bunch of them when calling SingletonClass.getInstance() from servlets.
I was totally desperate and thought adding #Singleton descriptions would help. But things weren't so easy. My classes simply not working while adding them with #EJB ClassName var. Context lookup doesn't work either.
I was trying developing in Eclipse, NetBeans, used Glassfish, tried to set it up, but nothing really helped. I do not know what to do and really desperate now.
All I need is just few classes, that work all the time application is loaded to handle game events and hold logged users data (which is distributed in non-EJB objects that hold user data, monsters and so on), some timed events for each logged user and ability to respond to HTTP POST requests with JSON. I even do not need the ORM, I wrote all queries by myself, but still... Something that had to work simply doesn't work out.
I'm aware that all that sounds messy and non-informative, but I do not know what to do - where is my problem? Maybe, I should fill web.xml, or use different port, or fly to the moon? Or just change programming language? Sorry for your time spent reading this.
UPD. Some application scheme parts. First two from package "server".
#Startup
#Singleton
public class DbWrapper
handles all database connections, DbConnectionPool is non-singleton class, which handles pool of java.sql.Conneciton.
#Startup
#Singleton
#DependsOn("DbWrapper")
public class World
is yet another class to handle all the in-game events, that holds HashMap of logged users. User and Monster classes are from package "entities" (User holds a list of monsters).
Package "servlets" hold HttpServlet descendants, annotated #WebServlet("/pathname"), that try to use
#EJB World world
for example. But such things as world.getUser(id_user) simply won't work.
As for JDBC - postgres jar is included in GlassFish domain's /lib.
As for JSON - I use org.json found here: https://github.com/douglascrockford/JSON-java
I've found out that my static instance variables for a couple of singletons weren't created properly - classloader made a bunch of them when calling SingletonClass.getInstance() from servlets.
First, you should show us the code for one of these singleton classes. You may have made a mistake in the implementation that causes this problem.
It is true that you can get what appear to be multiple instances of a (properly implemented) singleton class in a servlet framework. But in fact they are not what they appear to be. What is actually going on is that you have loaded the class from multiple classloaders, either because you have multiple webapps each loading the class, or because you are redeploying your webapp and the previous deployment is not clearing up properly.
So what can / could you do about this?
You could use a dependency injection framework to configure your webapp, and hence avoid the need for singleton classes.
You could continue using singletons, but track down why you are getting multiple instances, and fix that problem.
You should use singletons really rarely (best would be not to use them). As an alternative use application scoped beans (#Singleton beans should normally work - they should use instance variables though, not static ones).
With Java EE 6 you also can use CDI and thus you don't have to use EJBs if you don't need the additional features they provide (like automatic transaction demarcation, security etc.) or can live with adding those features yourself.
Additionally, you can use CDI in a SE application. Keep in mind though, that you need to define the scope for CDI beans (e.g. #Application, #Request etc.) otherwise the default scope (#Dependant) is used which causes the beans to be copied on every access.

Categories

Resources