Pages

Showing posts with label jrebel. Show all posts
Showing posts with label jrebel. Show all posts

Saturday, January 6, 2018

Setting up JRebel for WebSphere AS in Docker environment

Getting any Java application server up and running in the development environment is usually a fairly simple task. You can just download the zip archive, and start the contain either from command line or via IDE integration. Configuring JRebel agent for the server is also quite straightforward. However, there are some exceptions to that. For instance, if you’d like to try JRebel on WebSphere AS and you are using MacOS, then you will have to take another route.

WebSphere Application Server is available for Linux and Windows platforms, but not for MacOS. The good news is that there is a WebSphere Docker image that you can use for development.

The developerWorks' article demonstrates it pretty clearly, what needs to be done in order to get WebSphere running in Docker and deploy a web application. With the help of the article I have assembled a demo project that deploys a Petclinic application on WebSphere running with JRebel in Docker container.

Let me explain some interesting bits of the outcome.

First of all, we need to derive from the base image, package the application archive into the new image, and make sure that WebSphere will deploy the application when it starts:

#Dockerfile
FROM ibmcom/websphere-traditional:profile
COPY target/petclinic.war /tmp/petclinic.war
RUN wsadmin.sh -lang jython -conntype NONE -c "AdminApp.install('/tmp/petclinic.war', \
'[ -appname petclinic -contextroot /petclinic -MapWebModToVH \
[[ petclinic petclinic.war,WEB-INF/web.xml default_host]]]')"

As you’ve noticed, it is not enough just to copy the application archive to some folder. You also need to invoke a script to actually deploy the application: call wsadmin.sh by providing it a snippet of Jython code.

Next, as we want to enable JRebel, we also need to package the agent binary into the image, and also we need to modify JVM arguments of the application server. Hence, the corresponding Dockerfile will get a little more complicated:

#Dockerfile
FROM ibmcom/websphere-traditional:profile
COPY ["jrebel-7.1.2","/tmp/jrebel"]
RUN wsadmin.sh -lang jython -conntype NONE -c "AdminConfig.modify(AdminConfig.list('JavaVirtualMachine', \
AdminConfig.list('Server')), [['genericJvmArguments', \
'-Xshareclasses:none -agentpath:/tmp/jrebel/lib/libjrebel64.so']])"
COPY target/petclinic.war /tmp/petclinic.war
RUN wsadmin.sh -lang jython -conntype NONE -c "AdminApp.install('/tmp/petclinic.war', \
'[ -appname petclinic -contextroot /petclinic -MapWebModToVH \
[[ petclinic petclinic.war,WEB-INF/web.xml default_host]]]')"


The Dockerfile above packages JRebel distribution into the image. That’s an easy part. The hard part was to figure out how to configure JVM arguments. In WebSphere, JVM arguments are set via server.xml configuration which is quite unusual. Normally, a developer would use an administrative user interface to modify the parameters, but in our case we need the arguments to be in the right place right at the start. Hence we need to do some Jython scripting via wsadmin again.

Now that the Dockerfile is ready, we can build and run the new image. In the terminal:

$ docker build -t waspet .
$ docker run -d -p 9043:9043 -p 9443:9443 -v `pwd`:/tmp/petclinic -v ~/.jrebel:/home/was/.jrebel waspet

The docker run command above also maps a few directories: a project folder and JRebel’s home folder. We map the project folder because JRebel agent could then see if any resource is updated. JRebel’s home folder (~/.jrebel) includes cached resources, so that if we would have to restart the Docker image then the application will start faster the next time.

Now it is possible to use JRebel to update the application instantly, without restarting the application server or redeploying the application. For the full list of instructions, see the README.md file in GitHub repository.








Thursday, June 1, 2017

Conferences I have visited in May'17

Riga DevDays


Riga DevDays - a perfect conference of an Estonian to visit: not too far away (45 minutes flight), nice city, very good event!

There, I have presented a talk about Java class reloading, which covers the different options for reloading Java classes and explains the fundamental differences of those.


GeeCON, Krakow


I have presented at GeeCON before. The vibe of the event is quite energising! :) I have presented a talk about TestContainers which seemed to spark a lot of the interest from the attendees. Almost a full room and a lot of questions after the talk. Looks like integration testing is in demand these days!


JUG.ua & JEEConf, Kiev


The visit to Kiev (Kyiv) was super-productive. I've visited EMAP offices of the on-site presentation as well as a local JUG meetup just before the conference. Very good attendance: 100+ people came to the meetup. Interestingly enough, in Ukraine (as well as in Russia) people ask questions in an interesting way: they usually start the question with "What if ...". They are always curious to find the limitations of the technology, the approach, the method, etc - almost like trying to break things. I think this critical mindset is very helpful when you have to develop software these days.


At the JEEConf I have presented 3 talks: 2 on my own, and 1 with Anton Keks, helping to deliver the Kotlin Puzzlers talk. This was a very well organized conference: super-nice view in the center of Kiev, well crafted schedule with the interesting and useful talks, good athmosphere... I recommend :)


I had a pleasure to deliver a live coding session about Javassist, though I still have the slides just as a reference for those who attended the session. I don't find this talk to be very useful for the developers, however, attendees still find it interesting, so I'm puzzled with this a bit :) Here are the slides:



As for the Java class reloading talk, I had some time to update the content since Riga DevDays -- removed boring parts and added a few other things. Lots of "What if.." questions after the talk -- I love this crowd! :)












Friday, February 12, 2016

HotSwap vs hot deploy

It is the year 2016 and one still has to explain that HotSwap and hot deploy in Java IDEs is not the same thing.


Stackoverflow is full of questions about avoiding restarts of Java applications. So of the answers suggests that “Eclipse can update code without restarting the application” or “IntelliJ IDEA can hot update running applications” or “NetBeans automatically updates running code in debugger”. But the ultimate solution for this problem is JRebel, of course.

UPD: You can also read about various solutions to the redeployment problem in my Stackoverflow answer.

One fundamental thing that people don’t understand is that it is not even the capability of an IDE to be able to update applications. The IDE is just a medium -- it only triggers the update, and then the runtime environment is the one responsible for updating the code.

Repeat after me: 

HotSwap and Hot deploy is not the same thing!

What is HotSwap?

HotSwap (тм) is the technology in HotSpot JVM that is tailored at updating class definitions at runtime. Most importantly, "HotSwap adds functionality to the Java Platform Debugger Architecture (JPDA) to allow a class to be updated while under the control of a debugger”.

So when it comes to IDEs, once an application is started in a debug mode, the IDE can trigger class redefinition in a running JVM by utilizing JPDA.

If you are interested in the intimate details of HotSwap, read the “Safe class and data evolution in large and long-lived java applications” paper by M. Dmitriev.

It is important to understand the limitations of HotSwap: it is limited only to updating statements of code inside methods. Can’t change method signatures, can’t add new methods, fields, etc. Some JVM implementations are able to do a bit more. For instance, with IBM J9 JVM it is possible to add new methods to an existing class. Nevertheless, HotSwap capabilities are minimal. A JEP for enhanced class redefinition has been submitted long ago, and even a research project was sponsored by Oracle, but no further progress was made.

The bottom line here is that HotSwap is not a feature of an IDE, it is the ability of a JVM that you use.

What is hot deploy?

Hot deploy is the ability of application container to automatically deploy (web) applications at the startup. Obviously, the same feature can be applied to re-deploy the applications without restarting the JVM process.

Hot deploy is not a feature in any of the IDEs either. IDEs can only trigger (re)deployment of an application by either copying the artefacts to a correct location, or by using hooks if provided by the application server. So this is totally application server specific - this is what server adapters are for! It requires the IDE to be aware of the application server specifics, hence some people affiliate this functionality to their IDE.

Redeploying the application drops its state. Sometimes, application server can serialize/deserialize HTTP session state, but that's about it, not more. It can't preserve the state of the structures inside the application; internal caches have to be warmed up; framework internals have to be reinitialized, etc. The process is time consuming.

Application servers rely on class loader magic to redeploy applications. You can read about it in details in ZeroTurnaround’s blog.

Summary

Make sure you use the terms correctly -- 'HotSwap' and 'hot deploy' is not the same thing! You may other terms, like 'hot update' -- then make sure to ask, what does the person actually means by this, because the devil is in the details.

Friday, July 26, 2013

JRebel 6.0 Beta Registration Started

It’s been more than a year since JRebel 5 has been released. During the year there have been a few minor releases and a lot of things were improved – remoting, debugger integration, support for more frameworks, IDE plugins, etc.

Now, JRebel 6 is on the horizon. There will be several big changes (not revealing yet), which I hope will improve the UX very much. JRebel will be able to do things that it wasn't able to do before - that's very cool!

Since it is a major release and there are a lot of changes that we introduced to the product, I'm looking for volunteers to try out the new beta version on real-life Java projects.

You can register for the beta program here.

If all goes as planned the first builds will land late August / early September.

Tuesday, May 8, 2012

Con-FESS 2012, Day 2

I had great fun speaking at Con-FESS today. Here are my slides for the Why Doesn't Java Have Instant Turnaround talk. The internet connection was great so I even managed to make a JRebel Remoting demo with Jelastic PaaS.

After that, we had a great time investigating Griffon framework internals with Andres Almiray. Although it is quite tricky to update desktop applications on the fly, it seems it is still possible and Griffon will be able to leverage JRebel facilities.

Peter Niederwieser talked about Gradle in the enterprise. Gradle is just about to go 1.0 which is great. The tooling is getting better and there are very nice features in Gradle that simplify build procedure and build script implementation - true incremental builds, autowiring, dsl extensions, etc. What is really missing at the moment is the stable way to migrate Maven projects to Gradle (there are some scripts, but these aren't quite stable) and the native release plugin. It is quite interesting that Gradle has implemented its own dependency management solution and isn't based on Ivy any more.

Stefan Armbruster talked about using Grails with Neo4j graph database. It seems that it doesn't integrate that smoothly yet - some minor glitches still exist, but nevertheless it was used for a production application.

The video recording of the talk is available at Con-FESS website: http://2012.con-fess.com/sessions/-/details/139/Why-doesnt-Java-have-instant-turnaround

Wednesday, July 27, 2011

Using JRebel with MyEclipse Blue and WebSphere

Just recently ZeroTurnaround and Genuitec announce JRebel for MyEclipse. Here's what it looks like in combination with WebSphere application server. It is quite easy to install and configure.



JRebel 4.0.x

JRebel 4.0.3 was released just recently. The debugger support is maturing - some features are still missing, like expression evaluation support for the reloaded classes, but stepping functionality and breakpoints installation are quite well polished now.





See the press release.

Wednesday, April 6, 2011

33rd Degree, 2011, Day 1


ZeroTurnaround is exhibiting at 33rd degree conference in Krakow. In fact, we are the only software product company at the tiny expo here. The others, Luxoft and Tieto are the outsourcing companies, so we feel a bit lonely in this situation. BTW, Luxof has the most meaningless booth I've ever seen - it is huge and it completely ineffective.


Anyways, we've met a lot of smart people asking a lot of smart questions about JRebel and it is tough to answer all kind of questions - I wish I could.

I didn't have much time to attend the sessions myself. However I've managed to escape from the expo area and to attend Ted Neward's talk Busy Developer's Guide to Scala: Patterns. I've got smarter in a way. I've learned about some Scala idioms that diminish some of the classical design patterns that you need to implement in Java from scratch. In fact, I realized that many of the design patterns become obsolete once the target language supports closures.

At the end of the day we've organized the beer party for all the conference attendees. It is a funny thing but people are more interested in JRebel if they're are served with the free beer :)

Tuesday, March 22, 2011

JRebel 4.0 M1 Released

JRebel 4.0-M1 was released. Grab it while it's hot!

The new features include integration with HotSwap, support for anonymous classes and adding new session beans to JBoss 4.2/5.1 and Glassfish 2/3.

For the new features, I would encourage everyone to give it a try! JRebel already provides the integration for JSF (Mojarra), JAX-RS (Jersey), CDI (Weld), and now the support for EJBs is extended! It is possible to create a JavaEE6 app with almost no redeploys already. Things are improving quite fast!

Thursday, November 18, 2010

JRebel at Devoxx 2010, Conference Day #2

Day 3 at Devoxx for me is over. Lots of JRebel demos today again at Devoxx expo area.

We've got plenty of feedback for the product and features/improvements we would consider to implement  in the next releases. That includes Grails GORM support, support for adding new EJBs (3.0) on-the-fly, support for Servlets 3, better support for Wicket, better NetBeans plugin, plugin.xml support for Eclipse RCP, and many more! So that's something we should definitely to consider for the upcoming releases of JRebel.

Also, I met some people who haven't used JRebel yet, or haven't heard of it at all. After the demo they wanted to start using it! I hope we'll get to hear from those who started using JRebel - the feedback for is really appreciated!

I managed to escape from the booth to attend JavaPosse live session at the conference - I haven't had a chance to attend their sessions before. That was fun! :)



With that, the expo is over and JRebel team is going back to continue doing the awesome job!

Wednesday, November 17, 2010

JRebel at Devoxx 2010, Conference Day #1

Day 2 at Devoxx for me is over! Lots of demos, chatting, explaining things, etc

For a start we had a quick chat with Geertjan Wielenga about Javeleon. Even after a short conversation I think I have more understanding what it is about.





Also, I had luck to "unvirtualize" with Claus Ibsen and Charles Moulliard (from FuseSource), the guys behind Apache Camel - it is always a pleasure to meet people in person.



Also, somehow, my twitter reference have gotten to the Devoxx daily web page. Just because we have released a new JRebel version before Devoxx we were actually get quite a lot of buzz for the product which is positive as it gives the opportunity to get the feedback faster from the users. For Devoxx attendees we still have the giveaway "LiquidMetal" licenses - so go grab one!


I attended one session, the Reflection Madness by Heinz Kabutz. This was an awesome talk, but pretty much a compilation of the articles from JavaSpecialists.eu newsletter.

I can say I really like the spirit of Devoxx (compared to JavaOne this year) - it is even more technical: people come and ask good questions about JRebel. Some already use it but want to know more - that's also great! What I'm realizing now, is that the awareness is quite low for the issues that we're trying to solve. Probably, it would be a good idea to submit a talk at JAZOON'11, just to show what problems exist that are related to deployment under application servers of all sorts...

Tuesday, November 16, 2010

JRebel at Devoxx 2010

The first day for us was actually the University Day #2 at Devoxx. Not as many participants yes as it is expected on the real conference days. I did a few demos today demonstrating the PetClinic Spring MVC app. Frankly, I've got sick from doing the same demo again and again. Gotta prepare a new demo for tomorrow so it wouldn't be as boring :)




The fun stuff is that I managed to convince some hard-core devs that JRebel isn't about continuous integration, and it doesn't prevent devs from doing TDD and any other 'enterprise practices' one may apply during the development cycle.

Sunday, September 26, 2010

JRebel at JavaOne

And so as JavaOne 2010 is over and I'm back home, I probably should make a summary of the event as I seen it.

We arrived at the venue on Sunday to set up the boot for the upcoming expo. It was the very disappointing: the expo area was really small compared to the previous years. I do understand that OOW and JavaOne are held together as one event for the unity to show the benefit of using Oracle products. But JavaOne is a conference considered to be a #1 conference for Java developers for a long time and now this - sessions moved to Hilton and Park 55, and broken apart, and the expo is tiny small :(

Anyways, we had busy time showing JRebel demos one ofter another. And the most exciting part of that was that some of the people coming already used JRebel for their development and just came to say thanks for that JRebel exists! :)



Our marketing guys hired two pretty models to attract people to the booth. This was a blast! People stopped by even if they weren't interested at first! :) I could feel the jealousy coming from the booth next to us :) I admit, it was a dirty trick, but it worked well.

Unfortunately, we couldn't take part in the sessions as it was almost impossible to get in if you weren't preregistered. That said, I'm in a hunt for the slides of the Core Java sessions for now :)

Personally I've met quite a lot of interesting people (Hello, everyone!), hopefully I we'll be able to develop the connections further on. Also, I had luck to take part in the JRuby meetup at EngineYerd's office and JetBrains Be Wiser Party. Enjoyed that!

Thursday, August 26, 2010

Screencast: RESTEasy application instant updates with JRebel

JRebel manages the updates while adding new changes to a simple RESTEasy application: adding new resource using the JAX-RS annotations and adding new Java code to the application. No re-deploy phase required.

Tuesday, August 24, 2010

RESTEasy. rest, easy.

I've spent some days figuring out how does RESTEasy initializes itself. The goal, which came actually from a support case, was to hook into the framework and make it possible to add new resources with @Path annotation without re-deploying the application itself.

It turned out that as RESTEasy has 3 main options for bootstrapping: servlet (which actually has a plenty of configuration switches), listener, and filter. This is quite important as RESTEasy initializes itself a little bit differently depending on what kind of configuration is provided.

I've managed to patch the internals of RESTEasy in a way, so that in case of "servlet" bootstrapping, when adding a new resource to the application, the new context path appeared instantly, without re-deploying the application.

For a demo, I used the 'jaxb-json' example that is bundled with RESTEasy distribution. By default, the example uses listener bootstrapping configuration, thus web.xml has to be modified a little bit to use 'servlet' configuration instead:

<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/resteasy</param-value>
  </context-param>

  <servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>
      org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
    </servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application>
      <param-value>org.jboss.resteasy.examples.service.LibraryApplication</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/resteasy/*</url-pattern>
  </servlet-mapping>

</web-app>

Next, run the application, and see that localhost:8080/resteasy/library/books/badger responds as intended for the given example.  Now, if we use JRebel to make the class re-loading possible, and patch some classes of RESTEasy framework, one will be able to add new methods to the resource class without having to re-deploy the application. Say, I've added a new method to the class, and marked it with the @Path annotation:

@Path("library")
public class Library {
   @GET
   @Path("books/test")
   @Produces("text/html")
   public String getTest() throws Exception {
      return "my test";
   }
}

So now I could go to localhost:8080/resteasy/library/books/test and see the changes instantly! Hopefully we can add this feature to support all kinds of RESTEasy configurations. The feature will be available quite soon in one of the upcoming JRebel nightly builds.

Wednesday, August 11, 2010

Having fun with Grails and JRebel

Gails is a fun framework to work with. Recently, I had to figure out how "dynamic" the framework is.

BTW, IntelliJ IDEA Grails support just rocks!

One thing that is definitely useful - to tell Grails not to re-deploy the application after a new change has been introduced. You can do that by adding -Ddisable.auto.recompile=true to VM parameters of your application start script.


By default, controllers and service classes are initialized dynamically by Grails, but with the option above enabled it lets you to skip the re-deploy phase. Re-deploy of the application is required once you change Java classes, which may be included in your Grails application - this will be solved using JRebel as you will see below. Let's see a small example for that.

1) Create a new controller, called ActionController (grails create-controller action), which will delegate its calls to a service, HelloService (grails create-service hello), which will just return a string:



ActionController.groovy


class ActionController {
   def helloService

  def helloAction = {
    render(helloService.serviceMethod(params.name))
  }
}

HelloService.groovy

class HelloService {
  def String serviceMethod(String name) {
    return "hello ${name}!"
  }
}

HelloService is injected to the ActionController by convention. Run the Grails app with grails -Ddisable.auto.recompile=true run-app or from IDE as shown above. ActionController.helloAction is the entry point for our application: 


It tells now "hello Anton!"

Let's add another service to the application. Say, it will be GoodbyeService (grails create-service goodbye):

GoodbyeService.groovy

class GoodbyeService {
  def String serviceMethod(String name) {
    return "bye ${name}!"
  }
}

... and change the ActionController accordingly:

ActionController.groovy

class ActionController {
  def helloService
  def goodbyeService

  def helloAction = {
    render(helloService.serviceMethod(params.name))
  }

  def goodbyeAction = {
    render(goodbyeService.serviceMethod(params.name))
  }
}

So without any restart/redeploy phase, http://localhost:8080/jr-grails/action/goodbyeAction?name=Anton tells me "bye Anton!"

Perfect! I'm productive! :)

Now try another example, including some Java sources from within the application. For instance, we have a DummyController which delegates the calls to Util class instead of a Grails service.


DummyController.groovy


class DummyController {
  def index = {
    render(jr.util.Util.value())
  }
}

Util.java


public class Util {
  public static String value(){
    return "hello";
  }
}

http://localhost:8080/jr-grails/dummy now gives "hello" in response.

The problem is that if you make some changes in the Util class and recompile it, the change will not be visible in the application. To see the changes, you would need to redeploy the application which may require some time once you have a more sophisticated application.

JRebel to the rescue!

JRebel will help you with the issue above. Once you download and install the software, it is possible to start the application from your favorite IDE (via dedicated plug-in) or by adding special parameters to the application start script: -javaagent:"jrebel.jar"

Now if you run the example (see above), and after it is started, try making some changes to the Util class (for instance, change "hello" to "goodbye"). Hit F5 and the corresponding change will be visible now. The console will also display a message - JRebel: Reloading class 'jr.util.Util' - meaning that JRebel has noticed that the class has been altered and you want to use it in your application.

Unfortunately this trick doesn't work for all cases in Grails. For instance, for CRUD functionality in Grails application, if a change is made on a domain class, JRebel will reload the classes, but the change is not propagated further to the view because of some magic that Grails does behind the scenes.  The good news is that JRebel support for Grails is still in progress. Stay tuned! :)

Disqus for Code Impossible