In IDEA IntelliJ I have the option to:
Update resources
Update classes and resources
Redeploy
Restart server
If I change some code of a Servlet then I always need to redeploy. Is there another way to "reload" faster to get changes affected?
Check out this IntelliJ WebHelp article: Reloading Classes
However there are limitations:
At the moment due to original limitations of Java SDK the HotSwapping
is possible ONLY if a method body is altered. In all other cases (like
changing method or class signature), the class reload is impossible
and the corresponding error message appears.
For more options you might want to check out what Engineer Dolly suggested in his comment to your question.
Related
Regulations breakthrough! Due to major issues with recycling in XPages I got green light to install and use OpenNTF's Domino API now to leave a lot of recycling of Notes objects to ODA.
But what should I consider to change in code?
Besides creation of database object:
Database db = Utils.getSession().getDatabase("", "file.nsf");
Session sess = Factory.getSession(SessionType.CURRENT);
Database db = sess.getDatabase("", "file.nsf", true);
I noticed I saw code examples that stated SessionType.NATIVE. What is the difference?
I notice an additional parameter in sess.getDatabase("", "file.nsf", true). What is that for?
I also wonder what to do with all the exception handling that I have in my current code. Can I keep this or should I remove this?
What about logging for exceptions, do they appear automagically in openlog or not? Or how should I setup use of openlog?
Nowadays I use a different OpenNTF addon for use of OpenLog https://www.openntf.org/main.nsf/project.xsp?r=project/XPages%20OpenLog%20Logger . Can I remove this then?
I am looking for an example application for code but I have not found any yet. Perhaps you know a good source?
Thank you in advance for your guidance!
SessionType.NATIVE is used to run as the server. For the last few years I never used SessionAsSigner, only SessionType.NATIVE.
XPages OpenLog logger was incorporated into ODA. There may be different package names to import, but there are no differences in functionality. As I made changes to XPages OpenLog Logger, the same changes were made in ODA.
The demo app is available at http://paulswithers.me.uk/odaDemoApp and includes some documentation, including getting a database. You basically just need a single parameter and, if the database doesn’t exist, you get null returned, as would be normal for a Java method - no need to check if it’s
In the zipfile of the OpenNTF Domino API there is an apidoc folder this contains javadoc for the api.
Ok, here is the issue. We are using an old version of Tomcat (6.0.35) because our version of linux (ubuntu 12.04) doesn't have a repository with a newer version of it. Unfortunately, there is a bug in 6.0.35 that is affecting us ( https://issues.apache.org/bugzilla/show_bug.cgi?id=53725 ). IT doesn't want to/can't change tomcat versions. They want to use the package management system, they don't want to rebuild tomcat. They can't maintain something like this on a whole bunch of servers and we don't particularly want to disable Gzip. We can deal with the corruption until we can finally upgrade.
So with that background, the real question. The changes which fix this bug reside in one single class. We came up with a crazy solution (which will probably never see production, but was more of a "this would be so terrible, lets try it!" sort of idea), How about we compile the fixed version of the class and hotswap it in. After all, tomcat and our project use the same JVM.
Is this doable/possible/more than a little crazy?
Some hurdles. We are using Java 6. The new class adds methods and fields. I'm not sure that tomcat keeps it around.
In most cases this is unreasonable to actually do. The only way to cleanly unload a class and then load a replacement is to let the ClassLoader used to load that particular class be garbage collected. This will require you to remove all references to any of the classes that ClassLoader loads (which is probably at least all of TomCat) and reload them using a ClassLoader that loads all classes like normal, except for the class you 'fixed'. You would have to make it so that it loads that class instead of the old one, while still allowing the other classes to load normally.
In short, it is possible, however it will require digging into java ClassLoaders. I'd recommend that you do not actually attempt this, as it will be very annoying to get right and it will certainly not work without shutting down the TomCat server first (since you have to reload all of TomCat's classes).
Who is doing the unzipping, Tomcat or the application? If its the application, just make a copy of the class in error to the root of your project classpath in src/main/java and put there the patched version of the class.
Upon packaging the patched class will be in WEB-INF/classes, and override the version in the server. But its overridden only from the point of view of the application, the server cannot see the patched version and still sees the buggy version.
If its tomcat itself that needs to unzip something, then its not possible to fix that without tinkering with the server.
But if its the application doing the unzipping its for sure possible, there is no obligation to use the libraries of the server we can use our own more updated copies, usually not in patches but in jars in WEB-INF/lib - the server is designed for that.
Background / example (but question is probably broader than this):
I'm trying to write a Java application that accesses a Google AppEngine server. To set up the project for this, I followed the steps outlined in the accepted answer here:
Developing a Java Application that uses an AppEngine database
I am now running into a problem where I'm trying to execute an HttpURLConnection-request in the Java client application (i.e. not in the AppEngine server code), but Google's AppEngine library seems to have replaced the Java version of this connection with its own urlFetch()-implementation. This leads to me getting the following error: "The API package 'urlfetch' or call 'Fetch()' was not found.".
Actual question:
What determines the order in which Java looks through libraries to find needed class-implementations? Is there a way to modify this order (specifically in Eclipse), so that the actual JRE-functions take precedence over a third-party-library that is also needed. Or is there maybe something special going on with the implementation of Url in the example given above, that cannot be resolved by specifying a library order?
Update:
Turns out the problem I was seeing had nothing to do with the order in which classes were loaded. The AppEngine server code explicitly calls setContentHandlerFactory(...) to register its own handler during execution rather than at library load time (see here for a fix to this specific issue). So, while my "actual question" might still stand, I haven't actually yet come across a scenario where it matters...
You might have to define a custom ClassLoader.
Also, take a look at this answer.
Inside Eclipse, you can adjust the classpath order. Right click your project, choose Properties, Java Build Path, then click the "Order and Export" tab. However, of course, this won't affect your program when running outside Eclipse.
I'm using jboss server and having all my classes inside a jar file.
Now if I change any of the java files, I need to replace the class file in the jar and have to restart the server.
Is there any way to dynamically load the newly created class file without the server restart?
Thanks in advance.
I've had great success with JRebel (http://www.zeroturnaround.com/jrebel/). This is a very good product that enables seamless class reloading for the vast majority of modifications you can make to a Java class. There is no restarting of the app sever or even the application required, classes simply reload behind the scenes.
It comes with a free 30 day trial so you can see if it works for you.
(Disclaimer: I'm in no way connected to Zero Turnaround)
It appears that you have to trick the server into reloading your application by modifying web.xml -- meaning you can open web.xml in an editor enter a space then delete and save the file or change the modification date on the file with a utility.
JBoss doesn't seem to have a handy feature like Tomcat's reloadable="true" flag in Tomcat's Server.xml file.
there are a number of solutions, none of them particularly clean or easy.
As stated, changing the web.xml will cause the context to reload and hence refresh the source code and this can be done without restarting the server. This works because "WEB-INF/web.xml" is configured as WatchedResource in the TOMCAT/conf/Context.xml file. That is every context inherits this setting and automatically watches this file. You can remove this behaviour but you can also provide WatchedResource values in your own web.xml to watch additional files. While I don't recommend it, you could add all of your class files to this and the context would reload when you change one file.
A better solution relies on the fact that a Class can be reloaded when you discard the ClassLoader that loaded the Class. Therefore if you manage your hot swappable code in your own ClassLoader then you can refresh your code without restarting the context if you refresh the ClassLoader. Easier said than done, unfortunately but it may get you started.
There is component within the application that uses com.sun.java.swing.SwingUtilities2 Now I understand that this class shouldn't be used, but it's a component within the system that uses it.
Therefore since it's no longer available in Java 6 I get a NoClassDefFoundError. How can I get around this issue without having to upgrade the component as I don't yet know if that's an option.
If you have absolutely no other choice, then you should figure out exactly what it was that the class is using from SwingUtilities2, and then make proxies for that functionality in your own SwingUtilities2. You can then stick it in your own com.sun.java.swing package, which will overlap with the original one, and if the same class loader that loads your component is also aware of SwingUtilities2, then the one will see the other and your application will work.
Depending on what the component is, and what it used out of SwingUtilities2, this could be significantly harder than upgrading it or even rewriting it.
Da-dum! This is precisely why you should pay attention to those pesky warnings admonishing you not to rely upon internals of the JVM!
Just a though, I don't know if this would work.
Try pulling out the SwingUtilities2 class and put it in a patch jar, include this jar in your classpath. Hopefully this works until you can change the source.
The only correct way (out of hacking) is to ask vendor to fix and rebuild this component to Java 6. The possible working way is copy sun.swing.SU2 to com.sun...SU2 and package it into separate jar (e.g. java6fix.jar) and try to run your application. It will be fine if you add this patch jar into jvm bootclasspath. The best patch should be to create own com.sun..SU2 and delegate all calls to sun.swing.SU2. And take a look for different version of component which support Java6 maybe also from different vendor. Also if the problem is only in the mentioned line ((Boolean)c.getClientProperty(AA_TEXT_PROPERTY_KEY)); then you may put your own client property for this component to prevent NPE. When you take this path you can just simply create your own com.sun...SU2.AA_TEXT_PROPERTY_KEY and call c.setClientProperty(AA_TEXT_PROPERTY_KEY, true) on this component. Also try to disable anti aliasing check on component if possible.