For our purposes we didn't go with the standard OSGI jar reference that builds the jars into the bundle. Rather for online upgrades, we wanted to be able to provide new and updated jars during upgrades. Within our Activator class which starts and stops a bundle, we Implement our own URLClassLoader and then lookup all jars in a sub folder and supply to the URLClassLoader along with the OSGI CLassLoader as the parent. This is great because now admins of the application can simply add jars to a classpath and restart the application(osgi restart, not actually shutting down jvm). We got this working great. Plus our bundle.jar doesn't get huge over time as all of the jar references are not included in the bundle jar.
However, now we have the ability to remotely restart the application using OSGI to do it within the same JVM. However when the restart occurs, the class loader we added never gets garbage collected. So if you restart the application like 10 times then it will blow the Perm Gen out of memory(Java 1.7).
We have tried to mimic what apache WebAppClassLoader does on unload but this didn't remove the references either.
I have scoured the internet for solutions to this and granted we are coding outside the typical OSGI implementation however is there not a way to clear the references to the ClassLoader. After restart there honestly shouldn't be any references.
We have used MAT to analyze the heap dump but the referenced list of classes is always different.
Anyone know of a way to load external libraries a better way for use within OSGI?
Thanks for any information!
Use Java 8, there is no permanent generation in version 8.
Related
I sure am not the first person to wonder, yet it is really hard to find information on my question.
At the company I work at, the servers run WebSphere 8.5. In order to cut down installation time and memory usage, we created some shared libraries, where we have copy-pasted the common dependencies of our applications. Now you can see, that these can easily cause big problems when changing versions.
We have a Nexus Repository however, where every dependency our applications use can be reached. Since in our gradle projects, we have those dependencies listed anyway, it only seems logical for WAS to download and put these dependencies on the classpath of the application at startup (or whenever it wants to).
Is there a way to tell WAS where to look for these dependencies (our repo server) and what files to download? Is there a better solution to the problem?
There's no way to do this inside of the server at runtime. The best you can hope for is setting up the shared libraries during your deployment, single-sourced with your applications declared dependencies.
I have a GWT webapp split into two Maven projects where one is a dependency to the other. Each time I change something in the dependency and I'm running webapp in hosted mode I have to rebuild the subproject and restart hosted mode for changes to apply. It takes a lot of time so I'd like to ask you if there is any way to make GWT using "live" version of the dependency?
There are 2 cases:
for server-side code, assuming you use the DevMode's embedded server, rebuilding the app and then refreshing the server should be enough
for client-side code, AFAICT, you have to use the source and output directories of the dependency module rather than the JAR containing them (GWT will load the source from the classpath, but apparently it'll only see the modified sources if it comes from a folder rather than a JAR; at least that's what I found in my tests). This goes against The Maven Way™ but the only solution so far is to use a special profile that will import the sources of the dependency project as sources of the project you're running. You can see examples of that in my archetypes.
There's actually a bug opened for the gwt-maven-plugin, MGWT-332, to do that automatically when running a reactor build. I also mused about what's really needed, for the forthcoming official gwt-maven-plugin (rewritten from scratch, independent from the CodeHaus Mojo plugin).
If your dependency does not come from a reactor build, then you're out on your own: you chose to make it totally distinct, so that's how it'll behave: you'll have to release it (even a snapshot) each time you make a change to it, and use the new version in your app (which means re-launching the DevMode).
This can be circumvented by running DevMode on your own, without the help of the gwt-maven-plugin. You're left on your own managing the classpath though (using the Google Plugin for Eclipse, I suppose you could simply edit the launch configuration to add the source folders of your dependency project to the classpath, before the classpath provided by Maven, that would reference the JAR).
Remove the dependent other application jar file from the primary application lib folder under webapp.
Eclipse should then resolve the dependency using the other project in the workspace if you have added it to your primary application classpath.
As GWT build takes ages, we invested some money in a JRebel license. We have two separate Eclipse projects for our back-end and our GWT front-end. JRebel reloads the classes automatically and I never need to restart my local server while writing code. It proved to be a wonderful time saver. Definitely worth the investment.
I have been assigned a job to compile an old Websphere(WAS4) project, so we can find out which parts of it need to be changed for the project upgrating( to WAS7).
But when I was trying to fix the jar errors, wesphere.jar is missing!! And WAS7 installation path never hava this jar anymore, searching google failed. And I don't like to install older WAS again to just get this jar.
please anybody can help with this, providing an WAS4 version webspere.jar???
TKX in advance!
The jar file itself isn't important, the classes within it are. I don't recall what was in websphere.jar, but there's a good chance that what was is now in j2ee.jar. In fact, if your code isn't using any WebSphere-specific extensions, there's a good chance j2ee.jar is the only jar from WebSphere that you'll need for compiling.
But you should be able to see what specific classes are being complained about by the compiler and if necessary search for those by opening the jar files in like WinZip.
(Keep in mind that the larger changes are the changes to J2EE and Servlet specification levels.)
Trying to build Spring-based application one needs to figure out all necessary dependencies the application will have.
For example, I was using HibernateTemplate, and each time I run the application the ClassNotFound exception comes out. So I “google” for jars that contains this particular class, after search mvnrepository to find appropriate artifact. Always confuse about which version to use.
And it’s happened again and again, and only after few hours and few dozens of dependencies added the application become runnable.
But even after that, I tried to use my app. on different computer with slightly different parameters, and slf4j class not found error appeared, even after testing extensively on the developer machine, still some dependencies missing.
Now it works fine, but I want to distribute my application, and not sure if on another system there will no dependency missing.
So, what is the best practice to determine all necessary dependencies not only at design time but in runtime too? Is there any tool for that?
How one can manage versions confusion, when there are dozens of dependencies each with its own version?
They both resolve dependencies, so you keep a dependency file and it does all the heavy lifting of making sure everything is included in your builds. Use the full spring dependency list. I had problems with SLF4J too.
http://mvnrepository.com/artifact/org.springframework/spring-full/1.2.8
JDeveloper 10.1.3.x
I've recently learned that a library that is not exported will not be included on the classpath when deployed to the embedded OC4J container because it will have no library entry in the application-oc4j-app.xml file.
I have also demonstrated to myself that libraries that are not exported in projects that my project depends on are included in the application-oc4j-app.xml file.
Unexported libraries in my project do not get included. Unexported libraries in my project dependencies do get included.
Is that a bug or a feature, and can I change that behavior such that unexported libraries in my project dependencies also do not get included?
Thanks,
Steve
Unexported libraries should not get included in the application-oc4j-app.xml file. It looks like there is a bug, or some inexplicable behavior in JDeveloper.
IMHO, given a choice between Eclipse or <insert another IDE here>, and JDeveloper, it is wise to choose Eclipse.
One of the inexplicable behaviors that I referred to earlier, was the issue with JDeveloper compiling all projects in the application's directory, even if they were not part of the current workspace file (jws file). In other words, JDeveloper will consider a JPR file for inclusion in the workspace, even if the JWS file states otherwise (i.e. is does not appear visually in the JDeveloper workspace).
To date I have not found a way to specify different classpaths for build vs run time, but with help from a colleague, a solution to my specific situation was stumbled upon. Even though the connector is not a JDev project, the dependent project can reference the log4j jar file that is packaged and loaded with it. That effectively mimics the behavior at runtime, for both standalone as well as embedded oc4j container deployment, in which the web application and associated application code link to the log4j instance loaded by the 3rd party JCA connector's classloader. I did not think this would work assuming that a log4j library loaded by two different classloaders would still appear to be two distinct instances of the library with respect to log4j's static initializers. (That is what I am presuming motivates log4j to throw an exception if it finds another instance of itself in the classloader hierarchy.) Apparently this is not the case, at least for the embedded scenario. I do not have to test this for the standalone container since the Maven build knows not to include a copy of the log4j library jar in the application EAR file via the "provided" scope specification in the build file. The embedded OC4J container now loads the JCA connector, the associated log4 library instance, deploys the application, and allows both to use the log4j classes from the same log4j library file. Not entirely sure of how the connector and web applications classloaders interact, but it works now.