|
|
August 26th, 2010 by emil
Hello, web developers!
We’d like to get a sense of the development tools you’re using with Resin and what tools you’d like to use with Resin. If you could post your thoughts, we’d appreciate it and will try to incorporate your ideas into our upcoming development efforts. There are a few framing questions below, but please feel free to comment on any other development issues that we’ve missed:
- Do you use an IDE when developing with Resin? Which one?
- If you use Eclipse, do you use the plugin from http://caucho.com/eclipse?
- If you didn’t know about the Resin eclipse plugin, where do you expect to find it? (e.g. on our webpage, in the Eclipse update system, etc.)
- Do you use other tools such as Maven to develop with Resin?
- If you use Maven or some other command line tool, what plugins and/or features would you like to see from Resin?
- Do you deploy to Resin in production directly from an IDE or command line tool? If not, is that a desirable feature?
You can also reply to this related topic on our forums and/or take the poll there.
Tags: ant, eclipse, ide, maven, netbeans, resin Posted in Community | No Comments »
August 26th, 2010 by ferg
Resin 4.0.10 is now available.
- Several threading and alarm/timing fixes for 4.0.9
- Created HealthService to generalize the ping and health checks
- Improved Resin/Watchdog communication, giving more information on restarts
Posted in Uncategorized | No Comments »
August 23rd, 2010 by ferg
As part of our Resin 4.0 work, we’re going through the various Resin services and improving the testing and quality of each service. In Resin 4.0.9, we revamped the heartbeat service which is at the center of Resin’s clustering configuration.
In each cluster, Resin assigns the first three servers to be the triad servers, the triple-redundant hub for the clustering model. Each of the triad servers can act as a backup for any of the others.
For the heartbeat service, every Resin server in the cluster connects to each triad server and sends a heartbeat every minute. If the connection drops or the heartbeat is missing, the triad knows immediately that the server has failed and can take appropriate measures to deal with the failure. For example, if a server is down, Resin won’t waste effort trying to send messages to the dead server. The heartbeat, however, retries the downed server every 60 seconds, so Resin will know the status as soon as it comes up.
Posted in Uncategorized | No Comments »
August 20th, 2010 by ferg
Well, not really, but in most of the specifications I’ve worked with, the architect-types (people who haven’t touched code in years) assume that the cost of adding complexity is zero.
There’s a weird discussion in the websocket spec where people are arguing that saving one (1) byte in the frame header will lead to massive improvements in latency, and at the same time assume the additional code complexity required to pack the frame into the small frame is zero. In reality, the savings from one (1) byte is pretty small, practically unmeasurable, and although the extra code complexity isn’t huge, it’s also not zero.
Now, in the proposal even a tweet can’t fit into the small frame (127 bytes), because a full tweet with metadata is about 350 bytes.
That point was brushed away with the argument that a compressed tweet would fit into 127 bytes. Assuming, I think, that compression is also free because it’s code. So in order to save one byte in a TCP packet, they’re assuming all the overhead of compression.
The thinking that code is free has twisted specifications in the past. EJB is a notorious one. The working assumption was that the EJB design could be messy (in particular the XML), because people would write IDE tools to solve the problem.
Posted in Uncategorized | No Comments »
July 26th, 2010 by ferg
Just some quick numbers between SSL vs JSSE on Resin because some people have asked:
485 ops, SSL 1k hello file, no keepalive
135 ops, JSSE 1k hello file, no keepalive
272 ops SSL, 64k file, keepalive
51 ops, JSSE 64k hello file, 4 keepalive
The first set of numbers is for a single request, showing the startup cost of SSL vs JSSE.
The second set shows a more typical page load, with multiple objects (4) and larger 64k, showing the long-term, actual costs of the two.
In both cases, the difference is about 3-4x.
For faster performance, a hardware accelerator would be even faster.
Posted in Uncategorized | No Comments »
July 18th, 2010 by ferg
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.caucho.resin</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/java</string>
<string>-jar</string>
<string>/Users/scottferguson/resin-4.0.8/lib/resin.jar</string>
<string>console</string>
</array>
<key>StandardErrorPath</key>
<string>/Users/scottferguson/resin-4.0.8/log/test.err</string>
<key>StandardOutPath</key>
<string>/Users/scottferguson/resin-4.0.8/log/test.log</string>
</dict>
</plist>
Posted in Uncategorized | No Comments »
July 6th, 2010 by ferg
Although engineers understand the purpose and value of CDI for frameworks and applications, it’s been a little more complicated to explain to non-technical staff. One metaphor that’s helped is explaining CDI as a catalyst.
With the idea of a catalyst in mind, it’s not that it’s impossible to write a framework or an application without CDI, or that CDI provides a specific capability, but CDI makes development faster and more extensible than coding alone.
Posted in Uncategorized | No Comments »
June 25th, 2010 by ferg
For people who want to use CDI, the most difficult problem is a large legacy of existing code. Rewriting an entire codebase is not possible (and not wise) and evolutionary change has proven itself as more effective and manageable, even if it doesn’t sounds as impressive as a full rewrite. So the trick to migrating to CDI is finding ways to change one piece of the project.
If you have a service-oriented architecture (when used a legitimate design pattern, not the web services buzzword), you can explore CDI with one service, and transition between the styles using JNDI to enter the CDI environment. A module inside a framework also fits this pattern, like an application within wicket. Essentially, any case where the framework is non-CDI but you want to write a module using CDI. The key is getting access to CDI’s programmatic interface BeanManager using JNDI.
The code to load a CDI-enabled service inside a framework with JNDI is boilerplate. You’ll want to put it in a utility class. The class you load with the utility will be your main service entry, or a root node in a component graph. You’ll use the code like the following, where “myBean” is a fully CDI-enabled bean with injection, interception, XA annotations, events, etc:
CandiUtil candi = new CandiUtil();
MyCdiBean myBean = candi.getReference(MyCdiBean.class);
The utility class is boilerplate code. The BeanManager code is an SPI interface and it’s a bit more verbose than API code, but the added flexibility for framework integration is worth the added complexity. This integration code is only needed at the boundary of CDI and inside a foreign web framework; it’s not needed within a CDI module.
import javax.naming.*;
import javax.enterprise.context.spi.*;
import javax.enterprise.inject.spi.*;
import java.util.*;
public class CandiUtil {
private BeanManager _cdiManager;
public <T> T getReference(Class<T> beanClass)
{
BeanManager cdiManager = getBeanManager();
Bean<T> bean = (Bean<T>) cdiManager.resolve(cdi.getBeans(beanClass));
CreationalContext<T> env = cdiManager.createCreationalContext(bean);
return cdiManager.getReference(bean, beanClass, env);
}
private BeanManger getBeanManager()
{
if (_cdiManager == null) {
try {
InitialContext ic = new InitialContext();
_cdiManager = (BeanManager) ic.lookup("java:comp/BeanManager");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return _cdiManager;
}
}
Once you have this utility code, you can migrate your service to CDI without asking permission from the rest of the framework. Use this CandiUtil.getReference method to create your main service instance once, and all of its dependencies will be CDI-enabled. In an agile-style short release cycle, you can easily add this CandiUtil in one cycle and migrate the service itself bit-by-bit in following cycles.
Tags: cdi, migration Posted in Engineering | No Comments »
June 23rd, 2010 by ferg
We’re cleaning up the Resin 4.0.8 release this week, passing our own regression tests after finishing up the CDI TCK. Although there are still 9 failures, those all appear to be problems with the TCK itself; as we work on finishing all of the JavaEE WebProfile TCK, we’ll be cleaning those up.
Passing the CDI TCK has given us a chance to plug holes in our own test suite, primarily validation of invalid application classes, but also several important lifecycle issues related to interceptors, alternatives, specializing and producers.
It’s also given a chance to refactor the CanDI implementation a bit, organizing it to make it more maintainable, and improving performance in a number of places.
We’ve still got a ways to go for the full JavaEE 6 WebProfile. The next release will be primarily passing the JTA TCK, and after that finishing up EJBs.
Posted in Uncategorized | No Comments »
June 21st, 2010 by ferg
In the large projects that most of us work with, it’s not feasible to rewrite the entire project around a new technology like CDI, even though a redesigned project around CDI would be a better crafted solution. But what you can do is add CDI incrementally and improve your project’s quality piece by piece as time goes on. For example, in an agile-style short release cycle, you’d want to break up the CDI migration task into something small enough to fit in your 2-3 week cycle.
If you’re using JDBC directly, the quickest benefit for CDI is replacing your current DataSource injection (or JNDI) with CDI, since Resin’s database configuration integrates with the CDI injection.
Read the rest of this entry »
Posted in Uncategorized | No Comments »
|