Discussion:
hot class reloading
Oleksiy Stashok
2014-03-20 01:59:07 UTC
Permalink
Adding Jersey mailing list in case anyone has experience with that.

Just my guess is that you probably have to split resources jar out of
main jar and replace and reload only resources, not entire jar.

Thanks.

WBR,
Alexey.
What is the best way to reload some part of the web facing portion of an
app running in production without taking the Grizzly/Jersey server down?
Set<Class<?>> classes = new HashSet<>();
classes.add(myapp.MyClass.class);
classes.add(myapp.MyOtherClass.class);
ResourceConfig rc = new ResourceConfig(classes);
HttpServer httpServer =
GrizzlyHttpServerFactory.createHttpServer(BASE_URI, rc);
System.out.println(String.format("Jersey app started with WADL available
at " + "%sapplication.wadl", BASE_URI, BASE_URI));
GrizzlyHttpContainer c = (GrizzlyHttpContainer)httpServer.getHttpHandler();
c.reload();
but no luck, just a ClassCastException. Will that method do what I want
and what's the preferred way to get a reference to it?
Thanks!
Kevin Duffey
2014-03-20 03:07:40 UTC
Permalink
Maybe I am missing something, but usually in production, you have at least 2 servers for fail over reasons. If this is the case, you take one down, deploy the latest, bring it back up then take the 2nd one down (or next one), redeploy, etc. Or, you could just have the auto-redeploy feature turned on since you typically don't deploy to a production server too often. The one thing you gotta watch out for if you do this is perm-gen space. Glassfish I think defaulted to 128MB or something. Bumping that up a few notches would be good in case you deploy more frequently. Also, make sure you run all the server optimizations for java such as -server and so forth.

If you're running only a single server, and you own the hardware, set up a linux KVM setup with 2 or more KVM instances and use one KVM for a load balancer if you don't have a physical one, with at least 2, if not 3 instances of your web server. Today's cheap server hardware can handle several VMs at once, and it gives you the ability to fail over and load balance at least on your physical machine. A better option is using two physical servers each with a couple VM instances.. or just deploy to the cloud. Amazon is typical but VMware has some very easy to use cloud services as well and VMware are the masters behind virtualization and vloud computing.






On Wednesday, March 19, 2014 6:59 PM, Oleksiy Stashok <***@oracle.com> wrote:

Adding Jersey mailing list in case anyone has experience with that.
Post by Oleksiy Stashok
Just my guess is that you probably have to split resources jar out of
main jar and replace and reload only resources, not entire jar.
Thanks.
WBR,
Alexey.
What is the best way to reload some part of the web facing portion of an
app running in production without taking the Grizzly/Jersey server down?
Set<Class<?>> classes = new HashSet<>();
classes.add(myapp.MyClass.class);
classes.add(myapp.MyOtherClass.class);
ResourceConfig rc = new ResourceConfig(classes);
         
HttpServer httpServer =
GrizzlyHttpServerFactory.createHttpServer(BASE_URI, rc);
System.out.println(String.format("Jersey app started with WADL available
at " + "%sapplication.wadl", BASE_URI, BASE_URI));
GrizzlyHttpContainer c = (GrizzlyHttpContainer)httpServer.getHttpHandler();
c.reload();
but no luck, just a ClassCastException.  Will that method do what I want
and what's the preferred way to get a reference to it?
Thanks!
Robert DiFalco
2014-03-20 03:17:51 UTC
Permalink
Yup, that's what we do too. I second the idea that maybe what's needed here
is some better DevOps kung-fu rather than a more complicated running server.
Post by Kevin Duffey
Maybe I am missing something, but usually in production, you have at least
2 servers for fail over reasons. If this is the case, you take one down,
deploy the latest, bring it back up then take the 2nd one down (or next
one), redeploy, etc. Or, you could just have the auto-redeploy feature
turned on since you typically don't deploy to a production server too
often. The one thing you gotta watch out for if you do this is perm-gen
space. Glassfish I think defaulted to 128MB or something. Bumping that up a
few notches would be good in case you deploy more frequently. Also, make
sure you run all the server optimizations for java such as -server and so
forth.
If you're running only a single server, and you own the hardware, set up a
linux KVM setup with 2 or more KVM instances and use one KVM for a load
balancer if you don't have a physical one, with at least 2, if not 3
instances of your web server. Today's cheap server hardware can handle
several VMs at once, and it gives you the ability to fail over and load
balance at least on your physical machine. A better option is using two
physical servers each with a couple VM instances.. or just deploy to the
cloud. Amazon is typical but VMware has some very easy to use cloud
services as well and VMware are the masters behind virtualization and vloud
computing.
On Wednesday, March 19, 2014 6:59 PM, Oleksiy Stashok <
Adding Jersey mailing list in case anyone has experience with that.
Just my guess is that you probably have to split resources jar out of
main jar and replace and reload only resources, not entire jar.
Thanks.
WBR,
Alexey.
What is the best way to reload some part of the web facing portion of an
app running in production without taking the Grizzly/Jersey server down?
Set<Class<?>> classes = new HashSet<>();
classes.add(myapp.MyClass.class);
classes.add(myapp.MyOtherClass.class);
ResourceConfig rc = new ResourceConfig(classes);
HttpServer httpServer =
GrizzlyHttpServerFactory.createHttpServer(BASE_URI, rc);
System.out.println(String.format("Jersey app started with WADL available
at " + "%sapplication.wadl", BASE_URI, BASE_URI));
GrizzlyHttpContainer c =
(GrizzlyHttpContainer)httpServer.getHttpHandler();
c.reload();
but no luck, just a ClassCastException. Will that method do what I want
and what's the preferred way to get a reference to it?
Thanks!
cowwoc
2014-03-20 05:56:26 UTC
Permalink
If you use Jetty, it'll hotswap static resources automatically.

Yes, you need to separate the static resources from the JAR file, and
place them ahead of your JARs on the classpath. Take a look at the
sample code I posted at
https://java.net/projects/jersey/lists/users/archive/2014-03/message/66

I hope this helps.

Gili
Post by Oleksiy Stashok
Adding Jersey mailing list in case anyone has experience with that.
Just my guess is that you probably have to split resources jar out of
main jar and replace and reload only resources, not entire jar.
Thanks.
WBR,
Alexey.
What is the best way to reload some part of the web facing portion of an
app running in production without taking the Grizzly/Jersey server down?
Set<Class<?>> classes = new HashSet<>();
classes.add(myapp.MyClass.class);
classes.add(myapp.MyOtherClass.class);
ResourceConfig rc = new ResourceConfig(classes);
HttpServer httpServer =
GrizzlyHttpServerFactory.createHttpServer(BASE_URI, rc);
System.out.println(String.format("Jersey app started with WADL available
at " + "%sapplication.wadl", BASE_URI, BASE_URI));
GrizzlyHttpContainer c =
(GrizzlyHttpContainer)httpServer.getHttpHandler();
c.reload();
but no luck, just a ClassCastException. Will that method do what I want
and what's the preferred way to get a reference to it?
Thanks!
Libor Kramolis
2014-03-20 08:55:07 UTC
Permalink
Hi.
We do some experiments with Spring Loaded [1], it can reload changed classes. We are going to use it just during development phase, not in production. And also it does not reload Jersey JAX-RS model. It means if you changed your RESTful API (changed JAX-RS annotation usage) it is not automatically reloaded. You do have to call Container.reload() method [2]. See reload example [3].

Still not sure if it works in all cases. But we think about it just for development purposes...

Best regards,
-lk

[1] https://github.com/spring-projects/spring-loaded
[2] https://jersey.java.net/apidocs/latest/jersey/org/glassfish/jersey/server/spi/Container.html#reload()
[3] https://github.com/jersey/jersey/tree/master/examples/reload
Post by Oleksiy Stashok
Adding Jersey mailing list in case anyone has experience with that.
Just my guess is that you probably have to split resources jar out of main jar and replace and reload only resources, not entire jar.
Thanks.
WBR,
Alexey.
What is the best way to reload some part of the web facing portion of an
app running in production without taking the Grizzly/Jersey server down?
Set<Class<?>> classes = new HashSet<>();
classes.add(myapp.MyClass.class);
classes.add(myapp.MyOtherClass.class);
ResourceConfig rc = new ResourceConfig(classes);
HttpServer httpServer =
GrizzlyHttpServerFactory.createHttpServer(BASE_URI, rc);
System.out.println(String.format("Jersey app started with WADL available
at " + "%sapplication.wadl", BASE_URI, BASE_URI));
GrizzlyHttpContainer c = (GrizzlyHttpContainer)httpServer.getHttpHandler();
c.reload();
but no luck, just a ClassCastException. Will that method do what I want
and what's the preferred way to get a reference to it?
Thanks!
Loading...