Posted
by
timothy
on Sunday January 16, 2011 @04:18AM
from the not-yet-spayed dept.

alphadogg writes "The volunteer developers behind Apache Tomcat have releasedversion 7.0.6 of the open-source Java servlet container. 'This is the first stable release of the Tomcat 7 branch,' developer Mark Thomas wrote in an e-mail announcing the release on various Tomcat developer mailing lists. While not a full application server, Tomcat implements the functionality described in the Java Enterprise Edition Web profile specifications. Most notably, it supports version 3.0 of the Servlet API (application programming interface) and version 2.2 of JavaServer Pages, both part of the recently ratified JEE 6. A servlet container manages Java-based applications that can be accessed from a Web browser. One big area of improvement is in configuration management for Web applications. Previous versions required all Web app configuration changes to be entered in a central file called web.xml, a process that led to unwieldy web.xml files as well as security risks."

I don't mind XML configuration file as long as it contains only things that are important and has little/no plumbing boilerplate. In most Java frameworks (especially in Spring) there are two things mixed into a single set of configuration files: items created once while developing application (for example Spring depencency injection bindings, Hibernate mappings etc. - let's call it plumbing) and factual configuration settings (for example: database URL, user and password for application). Mixing these two things is a major sin as plumbing and configuration have different characteristics.

Plumbing is like code. It is done while as part of application development and is tightly bound to development process - it should be easily testable, easy to refactor (IDEs should handle this - for example if you change name of some class/method, IDE refactoring features should also change it in all plumbing code). If possible - it should not change between development and production environments. That's why I prefer annotations rather than XML for binding everything into final application (eg. Guice over Spring). One notable exception I often is Hibernate and that's only because hibernate-annotations adds tons of additional JAR files and addidional complexity coming out of it doesn't justify convenience of using annotations instead of XML.

Configuration is a tool for administrators, not for developers. It should be as simple as possible and easy to change by hand. And yes, a generally prefer plain.properties files or YAML over XML, however as long as config file is simple enough and has no unnecessary overhead, I won't complain much about it. It is also important to keep major aspects of configuration separate (for example general server config vs. application specific config) and to keep application configuration separated from application itself (.war/.ear file).

So, in short: there are two things: "plumbing configuration" and real configuration. It is important to keep these two things separate and to keep real config as simple as possible.

In most Java frameworks (especially in Spring) there are two things mixed into a single set of configuration files: items created once while developing application (for example Spring depencency injection bindings, Hibernate mappings etc. - let's call it plumbing) and factual configuration settings (for example: database URL, user and password for application)

So pull them out into a.properties file and use a PropertyPlaceholderConfigurer to inject them into your XML file of bindings and mappings

That's why I prefer annotations rather than XML for binding everything into final application (eg. Guice over Spring)

Except Spring has annotation-based config and it's fairly nice?

(Disclaimer, haven't actually used Guice, but do spend quite a bit of time using Spring - your comments look as though they're based on opinions and experiences from using Spring version $old?)

GP and parent both make good points. However, GP perspective is a bit outdated. Spring < 2.0 an earlier was all (mostly) about XML config. You'd have dozens and dozens of lines of XML to do what was ultimately a fairly simple task (ie: quartz jobs or AOP).

Spring 2.0+ (especially 3.0) made two very fundamental changes in "preferred" methods for application configuration. 1) XML namespaces and 2) increased use of annotations.

1) Going back to the AOP example, what used to take around 50-80 lines of XML in Spring < 2.0 and earlier can now be done in roughly 1/3 - 1/4 the config by using the <aop:...> <tx:...> or <scheduling:...> namespaces. You can still do things the old, verbose way, but now there's no reason to do so unless your either reinventing the wheel or have highly specialized needs that require low-level customization.

2) Spring has gone through their framework and found so-called "sweet spots" where XML-based config simply doesn't make sense. URL mapping, AOP pointcuts, autowiring or init methods, transactional behavior, all become much easier to configure as you no longer need swaths of XML to do something that a simple annotation can do (@Transactional anyone?). And inasmuch as there exists a standard Java annotation or JSR which specifies the same thing, they support that (following their "light weight framework" mantra).

A particular note on the parent's mention of PropertyPlaceholderConfigurer: I extended that configurer a couple years ago for our team such that it dynamically loads different sets of properties depending on the environment it is running on (defined by an environment variable). We pull nearly everything out into those properties files (app variables, logging config, profiling, etc) such that a single WAR file can be deployed on any of our environments w/o the need for any post-deploy reconfiguration.

As for DB config, that's the job of the servlet container. By using JNDI binding, there's no need for the application to worry about DB config at all (why would you want your production creds in a build anyways).

As for the web.xml in particular, most web.xml's I've seen for applications that are built by developers who understand the Spring framework (again > 2.0) are very thin. They pretty much just point to DispatcherServlet and URL config inside Spring (again minimized by using URL mapping annotations) take care of the rest. No need for servlet filters since Spring request interceptors do the same thing and in a much more flexible way. This is very much in-line with most frameworks which redirect all requests to a single entry point inside the framework (ie: wordpress, rails, cakephp, etc.).

Bottom line, be careful when you make/see the "Spring requires loads of XML config" argument. It usually comes from those whose idea of Spring is several years old.

IMHO the plumbing part is like code (if you have to rebuild your WAR to change it then it is the same as code), so prefer to write anything smaller than the huge applications in code alone (or annotations), and minimize the funky XML dialects (Spring included) for the plumbing. You should be trying to write your systems so that the number of skills required to maintain it are minimized (you might have been tracking Spring since day 1 and know all the variations over the versions, but how likely is your main

IMHO the plumbing part is like code (if you have to rebuild your WAR to change it then it is the same as code), so prefer to write anything smaller than the huge applications in code alone (or annotations), and minimize the funky XML dialects (Spring included) for the plumbing.

This is true unless you have multiple concurrent version of the same code running with different configurations. I have worked on applications that all shared the same internal api for data access (just as an example) but they connected to different databases with different internal schemas (because the application did not have control over the DB schema). So we would have different OR Mappings for each different implementation of the same application. So even though the OR Mappings where compiled in the

> And as I have said before, anyone can misuse a framework, but it takes real ignorance to blame the framework for that misuse.

Ignorance? no. You can mis-use any framework or language. The problem is not Spring per-se, IMHO it is the documentation and zealots that suggest dependency injection is the One True Way and Spring is the One True Path - to be used everywhere. In practice it is far less clear cut, but the Spring documentation is very poor on when *not* to use it, and it is poor on keeping thing

The problem is not Spring per-se, IMHO it is the documentation and zealots

I'm not going to argue about documentation of zealotry. Springs Documentation is very detailed, and very easy to understand, though certainly still plagued with the usual open source problems. And as for Zealots, well zealots suck in all walks of life.

While you could debate the merits of the implementation of BeanKeeper, you'd be pretty hard pressed to beat its philosophy. Have a think whether Spring is designed with the same philosophy in mind.

BeanKeepers philosophy is exactly why it's not in widespread use, and most programers would have to look it up, as opposed to Spring or Hibernate which are becoming household names. The BeanKeeper philosophy contains majors flaws that will continually hold bac

Bro, creating objects is easy. Configuring them can be trickier but you don't necessarily need something with the conceptual weight of Spring to do it. Spring certainly has its uses - it's just not a panacea. There are other ways of achieving the same thing without the bulk though.

Sounds like the ever so typical "I hate this framework because when I misuse it, it doesn't work very well," or is to hard to maintain or extend or whatever.

It's like my house, where the designer decided to put the hot water heater on one side of the house and then use a ton of plumbing to pipe it to the shower on the far side of the house which cause a huge waste in water to get hot water out of the shower, rather than build all the hot water appliance around a central location. Now I could blame indoo

At least they do when you have to deal with a real website with real, complex functionality.

Why do people always assume what they are doing is the 'real' thing. Just like all those MTV hip-hop videos with people talking about the 'real' world.
If you want a modular webapplication with Spring use Spring Slices. If that's not modular enough you can click Slices onto an OSGi solution like Spring DM server. You can't get a cleaner separation between modules.
And since your into the real world; Yes, I've made such an application in the 'real' world, a rather large one.

LOL! How did you take that above comment, written in 2 seconds late at night, so personally? And how do you assume that I was telling you you've never done a large application in the real world? And how do you assume that I wasn't doing the real thing myself?

In any case, the web.xml file was thousands of lines long and I remember hating it. I'm sure there have been major improvements since then (about 4 or 5 years).

Tomcat 6 has been a rock solid server for me for years. It's fast, it's easy to roll out, it can scale, and it's real tough to break. (Has it been cracked in the wild?) The non-blocking I/O extensions to the servlet spec were genius, and I wish other vendors had picked that feature up.

I look forward to much more goodness with Tomcat 7, sounds like there are tons of refinements to security and the codebase.

It's solid for normal serving of servlet stuff but that's about it sadly.

- Your "security record" comes from the fact that tomcat is written in a "safe" language, a security hole would have to come from some stupid manual hole, a JVM bug or the APR connector.

- The non-blocking extensions are non-standard, and much worse than that is that those extensions only works with the APR connector (IE NATIVE C CODE!) but are only experimental with the portable NIO connector (after alot of debugging my own code i fina

I disagree that Java's JVM is the sole reason Tomcat is the first choice for Java web containers. Look at some of the bug reports on the major commercial vendors' app servers, and you'll see just how complicated a situation it is to build out these JEE specs. Tomcat seems to avoid these kinds of exploits, and I think its a simple matter of: the team cares about security and they get massive feedback from the user base because they are so widely deployed.

I agree with most of what you are saying, but I am having a problem I haven't been able to find a solution yet.

Here is the problem. I have just one straightforward web app on the server, and once in a while a request for data takes a bit too long and the user retries it, but the original request is still running in a tomcat thread, and it's not stopping.

Eventually what may happen is that the entire thing becomes useless until it's restarted.

after reading the rest of hot-headed thread, here's solution I use. Big-ass reports should be done as batch requests processed elsewhere than your web front end, it's a kind of middleware, you can e-mail the user when they are done or have a status page. Only a limited set of reports should be allowed to be interactively generated, and those should have implicit limits on size of data set returned.

This solution actually pre-dates the web, I'm old. Some things are just better done with batch jobs

Not good. The report interface is dynamic, allows the users to change filters and ordering in real time, the entire point of this app is to do this in real time. The only problem is they are not limited on what they can do in terms of the total size of the data set. Normally even the largest requests return within 2 minutes, it's actually good enough for them.

However in cases of graphs, they can choose too many data types to be on them. For example they can choose not just brands to be on the graph, but di

We understand the question, but the answer is your architecture is poor. Killing the user's request will only anger them, it is the wrong way, your job is to make an architecture that works and fulfills the user's request. My batch-middleware suggestion (which to your clients could be made to look the same as real-time interactive with a job-status page), could even be implemented on the same server

Large enterprise applications will generally have a multi-tier, not a two-tier, architecture for solving th

- are you providing money to buy, maintain, support more hardware and software?

your job is to make an architecture that works

- I explained in that link. It works.

and flfills the user's request.

- and I explained in that link, it fulfills them.

My batch-middleware suggestion (which to your clients could be made to look the same as real-time interactive with a job-status page), could even be implemented on the same server

- an irrelevant suggestion. There is no difference between a middleware solution and this one, when in fact all this solution does is generating reports, that's its purpose. All of the resources of the hardware are allocated to it. Every day

a few dozen lines is what I am doing at this point - starting a worker thread, have the request thread wait for 100ms, wake, check status and time, if status is done, exit, if time is out, do that instead, but first signal the worker thread to destroy itself.

What you should do is have a background worker thread, with the user making requests that the background processes, so that the interface and the heavy report creation is done in different threads/processes. Then send the user immedately to a page where they can check the status, and download the result when it is done. Since you are talking more than a minute, a browser waiting isn't a good way to do this.

(Basically, this would be like BeOS worked, with the interface in a separate thread from the applicati

@roman_mir I'm sorry you got nasty responses to your post here. I've occasionally had to deal with the same kinds of issues, and I have come to terms with how to deal with the problem. As a rule of thumb, if a response takes time to generate and you're keeping your users waiting for more than 2 or 3 seconds, that's generally a sign that that work should be done as an asynchronous activity (like with a JMS queue for offline processing and the response going out to the user by email.) I don't think Threadi

As to the issue at hand, it's not about the 'refresh' button, it is just people abandoning one report to try and generate another and it's not a normal occurrence, not something that happens all the time, but 1-2 times a month, hard to spot and slows everything to a halt. Normally it happens when the users start generating yearly graphs with too many data types on them, like sales for all products within a number of brands on a comparative graph over a p

Yeah, well, you took the bait and fed the trolls with all the cussing.

If an in-memory cache is too hard to work out, then just consider a "job" metaphor. To make a graph, you start a job. The list of currently running jobs is a global. If you detect that a job requests' parameters exactly match those of an in-flight job, you can just wait for that job to complete and return the results. Obviously, if the user changes his parameters for his second request, that would mean another job is fired off - in wh

Yeah, well, you took the bait and fed the trolls with all the cussing.

- wasting some time, no question about it.

If an in-memory cache is too hard to work out, then just consider a "job" metaphor.

- I have 15G of RAM, 50 users. All product definitions are cashed, but cashing all receipts from all stores and years, etc. and still to allow the container to have enough space to generate all the reports.... I'll need much more space than that, an order of magnitude more space than that.

Whether it's your users resubmitting or a refreshing, doesn't matter: you're making your users wait too long and they think their connection has stalled so that's why they're trying again.

- the users know what amount of time their reports take normally. They know which reports take a few seconds, they know that sometimes they need to wait a few minutes, that's j

I bring shame into it because you obviously get snippy when anyone comes close to hitting a nerve. If you've got the architecture of last resort or whatever and your clients are just so thankful they have what they have, good for you. I've encountered plenty of examples of people like yourself in my travels and a lot of 'em can just ride that wave for years until it crashes. Hang ten.

And I do know your business. Reporting, db's, Java, enterprise apps? It's like, uhm, I've been doing that for 12 years a

The short answer is that a thread can never be both arbitrarily and safely stopped. That's why Thread.stop() has been deprecated since nearly its introduction in Java. There's an official summary [oracle.com] of the reasons, linked from the API. Essentially any forcible stoppage of a thread could silently compromise the thread-safety of the entire application.

How do you even time out Executor threads after a fixed amount of time?

If your worker threads happen to by blocked on IO or something similar, or they are waiting for a synchronization monitor, then you can indeed interrupt them. Howe

The short answer is that a thread can never be both arbitrarily and safely stopped. That's why Thread.stop() has been deprecated since nearly its introduction in Java.

- yes, I have been working with Java since 1997, I have already discovered this, thank you, you know.

Yes, in my case the threads are not blocked, they are doing whatever work they must, running hundreds, to thousands of SQL requests, yes I absolutely can have them implement their own way of timing out because of this specific way they are doing work.

Yes, my question was about whether Tomcat is doing anything about this, providing any interfaces/interrupting listeners for it, or whether this has to be done

ha ha ha ha, idiot, didn't I say: what is the way to time out an executor thread? What is the difficult thing to understand? You can sit there and yap and yelp about code as much as you want, but what is the way to kill a thread that is taking too long? How the fuck, do you, idiot, know what a thread is doing? It's creating a gigantic 3 year based report by running SQLs against a dabase and putting together a picture that's going to be placed an HTML page.

12 years of java coding behind me, and you look like the idiot, not the AC you're replying to. If an accumulation of threads (because of refreshes) bring your tomcat instance down, it means your code is crap. Or you need a cluster because you have high traffic. Deal with it. Having automated restarts of tomcat instances or timeouts is just going to destabilize your app, which does look like it doesn't need it.

Yet with your 12 years you still didn't get the question, did you? How do you time out an executor thread that's no longer useful, if it's still doing work, type of work that takes long time to do? - so if this looks like an idiotic question to you, then you haven't had to do much in those 12 years.

Secondly, it's not 'refreshes' that cause this, it's dumped requests, that are still processing. Sometimes many dumped requests.

Clearly there can be more done, more memory, a cluster, etc. Most of it would be a

Another moron with a keyboard. Polling connection on what, you, nimrod? From the client it's useless, the thread is already running in the container, nothing can stop it until it's done with its task. From the thread itself - the client can still be there just fine, working on some other report. Go bang your stupid fucking head against the wall, maybe you'll set your brains straight.

for report like what you described a few post up, you should consider a BI tool to do the reporting on a denormalized database.But for your rag tag "real world" system, a rapid fix would be to inject a bean that hold the Futures in the session attributes and then to cancel them when they are no longer needed.I leave the implementation details to yourself, I have already said to much without getting paid.

Second: nobody can answer a simple question, is it possible to time out a running task through Executor thread. Your solution is not doing much good, is it? Since the user can have multiple reports running at once legitimately.

Third: I don't need your implementation, since you don't understand the question.

Beautifully done, I love/. an entire number of assumptions, not backed by any reality, but made with complete certainty. It's an amazing site and sight.

1. I am no longer looking for a Tomcat provided solution, I am quite certain all of the changes must be in application.2. Would you like to pay for the new tool? The transitioning to the new tool? Maintenance? Support? Training?3. Are you sure that your tool would do a better job than what is currently done with that same data, regardless of how the data i

Money well spent when I spend it on a vacation, everything else is a waste.

As to hiring a consultant - for what purpose? To solve a problem that happens 1-2 times a month on a system that is being used by 50 people 12 hours a day? I already have a solution, and it doesn't involve buying into nonsense.

Yeah, let me post something here right now. This is a list of requests from today (the day is not over yet, it's not US timezone, so don't be surprised.)I just cut that out of the log table, I am not showing the incoming IP addresses, user names, types of the reports that are executed, the parameters passed into the reports, etc.etc. Just times and milliseconds.

You think people, who are busy working, care about your idea of queues? You think it doesn't let the people to 'feel in control' in a system that do

...by editing thousands of lines of XML files by hand in various directories!

The horror...

Not really. The idea behind web-fragments.xml is that individual libraries can have their own configuration that the user doesn't need to bother about. So if you're upgrading from Tomcat 7 to, say, Tomcat 8 at some point, then YOU as the user only need to bother about YOUR web.xml and web-fragment.xml. The other "thousands" of web-fragment.xmls will be the headache of the individual library developers. Well, that's even worse, you might say. But then think again: why would you even need to "upgrade" your we

... a virtualization nightmare, definitely not recommended for production environments, needs lots of good (expensive) hardware to tame. Also, if you are running realtime OS on some low spec. board then the resource hoggishness and unpredictability is a major show stopper.

An HTTP server running on a low spec board on a realtime OS? Quite a strange idea. This is definitely not a typical scenario for web applications. Tomcat does need some memory, e.g. half gigabytes at us, on the other hand it scales very well.

Oracle is evil, and I'm not going with anything that they've got or derived from anything they've got in a way that they can control, no matter where it came from. I don't care if it's Sun-based or whatever. If it's got the Oracle taint on it I ain't interested. A fork that ain't beholden to them might be interesting.

(Well, almost; the ASF's implementation may or may not work, but they can't possibly show that it does because they don't have access to the test cases and never will. There are also a couple of nominally separate implementations - but IME they are all derived from the Oracle one to the extent that they all have the same bugs).

Just wanted to share my experience of building a real production product based on Tomcat 7. We've been using it for the past 8 months, ever since the release candidate, and specifically wanted to exploit the async servlets of Servlet 3.0 spec. Jetty didn't fit what we needed, so Continuations was out.

Why did I post the background? Read this: http://www.tomcatexpert.com/blog/2011/01/11/field-report-tomcat-7-action. It's just a play-toy for articles like that, but real production use of Tomcat's asynchrony is

I'm stuck developing and deploying apps to JBoss 4.0.5.GA . I have problems when I deploy a WAR file that contains struts jars and other jars that conflict with the jars already installed in the JBoss. Is there a chart of feature comparisons between all the version of JBoss (and the underlying Tomcat) that could show which version has features to help me avoid those problems? FWIW, I use Eclipse Helios for development and testing, while another group runs ant against a build.xml I supply to deploy (and I'd