Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I am currently working on a project with some (in my opinion) architectural problems.
For example - every dependency is retrieved when needed from a common Framework Bean that every object has access to via a static method. This is in effect just a wrapper around spring that will return a Spring bean. No dependency injection.
Entities have references to DAO's to retrieve relational data - hidden in the Entity getters.
Exceptions have references to services to parse and translate error messages.
Every service or DAO inherits from some common abstract framework bean that have their own dependencies and configuration requirements. If you try to do anything else you will get a 'Framework not initialized' error. It should also be mentioned that the Framework is a black box that noone dares touch.
Every test is in effect an integrationn test as all of them requires a working database connection to a central, shared database.
We have a dependency graph that everything is connected to everything, basically.
And no tests.
Imagine how hard it is to set up a unit test in this environment. In fact every test tries to insert test data and clean up after itself - without using any kind of transaction.
And I'm only scratching the surface here.
Needless to say, I worry a little about the code quality. The project is (of course) running low on time and resources, and deadline is approaching.
So - How to convince management in a language they understand that refactoring is needed if we shall have any hope of delivering something that resembles functional software?
In my opinion the best approach is:
Metrics: Collect all the possible data about the problems caused by the use of the current architecture. Analyze the information and separate it in topics of interest like: reliability, efficiency, security and Maintainability. (See: Software quality)
Visual: Make beautiful bar charts and pie charts with the analyzed info.
Diff: Compare your results with an standard or ideal metrics.
With this you are ready to present your point of view of the project to the management.
Usually this work is responsibility of project manager, team manager, or team leader.
Good luck!
Actually, in many cases refactoring may not be good for business, because benefits are less than cost. In other cases benefits may be bigger than cost, but cost is too much to be payed right now. Try to estimate benefits and cost of refactoring in some units which business can convert to $$$, i.e. in man hours of developers, testers and support team, in hours of system unavailability, etc and let business decide whether refactoring is worth to be done, or not. Such decisions is where business is stronger than developers.
I'm working on a project that is similar in dependencies. Unit testing it isn't ideal. I'm mocking so many classes in each my tests that simply running the full application in a development environment is a better solution.
I guess it depends on your application. Mine was a custom web application serving HTTP requests. I turned it on and sent all sorts of requests to try and follow all possible paths. It is more of a functional test than unit testing, but I found the process to be much faster and my log statements were informative enough to lead me to bugs in specific class or methods.
I wrote my code, functional tested it in dev. environment, then when I found time, I slowly added unit tests to classes.
Talk to them about the expected changes that might affect the future of your application, new features, requirements, technologies, etc. The project might not warrant refactoring if it'll never evolve.
I am not saying functional testing is a replacement for unit testing.
If you think you need to persuade "the business" about the benefits of refactoring, what you have in mind is not refactoring. Refactoring is a kind of redesign, but not all redesign is refactoring. A refactoring is a small, incremental design improvement. As it is small, it is cheap and quick. So it does not need approval from "the business": you can just do it. It sounds like what you really have here is that the existing code is not fit for purpose. So you should be trying to petsuafe them of that, rather than trying to persuade them of the need to do something that will sound to them like needless "polishing".
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
The development team I'm a part of wrote and still maintains a codebase of pure Java spaghetti code. Most of this was implemented before I joined this team.
My background is in Python/Django development and the Django community really emphasizes "pluggability" -- a feature of Django "apps" (modules) which implies mostly "one thing and one thing well", re-useability, loose coupling, and a clean, conscious API. Once the Django team I once worked in started to "get it", we pretty much had zero problems with messy, tightly-coupled masses of monolithic code.
Our practice involved developing Django apps outside of the Django project in which we intended to use the app (a common practice among Django developers, from what I've gathered) Each even lived in a Git repository separate from that of the overall Django project.
Now, we're presented with an opportunity to refactor much of our spaghetti code, and it seems to me that some of what I learned from the Django community should be applied here. In short, I'd like to see our new codebase developed as a series of "pluggable" modules each written under the assumption that it won't have access to other modules (except those on which it should rationally depend). I believe this should do a good job of driving home principles of proper software design to the whole team.
So, what I'm advocating for is to have one separate repository per "feature" we want in our new (Spring) project. Each would have its own, independent build process and the result would be a .jar . We'd also have a repository for project-level things (JSP's, static files, etc) and its build process would produce a .war . The .jars wouldn't be placed inside the .war, but rather be treated as Gradle dependencies (the same way third-party dependencies would be.)
Now I have to sell it to the boss. He's asked for some example of precedent for this plan. Obvious places to look would be open-source projects, but if a project is split across multiple repositories, it's likely to be multiple projects. So, perhaps I'm looking for some sort of suite. Spring itself looks promising as an example, but I haven't been able to find many others.
My questions are (and sorry for the long back-story):
Is there any such precedent?
What examples are there?
Is there any documentation (even just a blog post would be of help) out there advocating anything like this?
Any suggestions for implementing this?
Is this even a good idea?
Thanks in advance!
Edit: Whether or not to refactor is not in question. We have already decided to make some drastic changes to most of our code -- not primarily for the purpose of "making it cleaner" in fact. My question is about whether our planned project structure is sound and how to justify it to the decision-makers.
The following issues are more important that where to put code on the disk or in an artifact:
If you don't understand that, you have already failed.
What you describe is not refactoring, it is rewriting using a more palatable name:
Unless you have 100% code covered in unit tests already; someone(s) are going to get fired over this when ( not if ) this effort fails spectacularly, probably multiple times!
Even with awesome unit tests, someone is going to miss something and someone is going to take the fall when it finally gets discovered in production, usually after months of silently corrupting data.
Semantics are Important:
Removing Struts and replacing with Spring is not refactoring is rewriting by definition. Refactoring would be moving from Struts 1.1 to 2.0, replacing Struts means replacing all the Struts code with something else, by definition that is rewriting not refactoring.
Working Software comes in many disguises:
The business always thinks what they have is working.
Miss a deadline, introduce a bug no matter how minor, lose a feature no matter how minor, mis-interpret an undocumented process and change something no matter how minor or even for the better. They are just looking for any problems weakness or potential trouble to spread FUD and make sure your effort is a failure, at least most of the time.
All these things will cost you and your team political capital, someone will take the fall for these things, no matter how innocent or merit-less the perceived failures are!
Projected outcome:
Most likely you and/or other "non-Java" developers and not the core Java people that created this working system that you "non-Java" people refactored ( code word for rewrite in this case ) and delivered on time broken and incomplete or didn't deliver on time or didn't deliver at all.
I think it's possible to find examples of good and bad implementation in both Java and Python.
Spring is indeed a good place to start. It emphasizes good layering, designing to interfaces, etc. I'd recommend it highly.
Spring's layering is "horizontal". If "module" means "business functionality" to you, then multiple modules will be present in a given layer.
Plugable suggests a more vertical approach.
Maybe another way to attack it would be to decompose the system into a set of independent REST web services. Decouple the functionality from the interface completely. That way the services can be shared by web, mobile, or any other client that comes along.
This will require strict isolation of services and ownership of data sources. A single web service will own/manage a swath of data.
I'd recommend looking at Michael Feathers' book "Working Effectively With Legacy Code". It's ten years old, but still highly regarded on Amazon.
One thing I like about the REST web services approach is you can isolate features and do them as time and budget permit. Create and test a service, let clients exercise it, move on to the rest. If things aren't too coupled you can march through the app that way.
Refactoring entire application is not an easy task, specially if the code is hard-wired as you have described. If Pluggablity is an important target, I would recommend Grails/Groovy.
If you can somehow identify view, controller and business logic, or much better services. You might be able to reuse some existing codes. The good thing about grails/groovy is that you are able to incorporate JSP/JAVA with GSP/GROOVY.
Again, this is really hard to sell and grails is probably a good framework to ease the refactoring pain.
I would recommend watching "Four Strategies for Dealing with Legacy Code" by Eric Evans, the originator of Domain-Driven Design: http://dddcommunity.org/library/evans_2011_2/
It may not entirely answer your question but it offers arguments and strategies that might help with your endeavour.
Every component is in its own jar, but the jars are not contained in the war ? How should that work ? Even third party libs are included in the war. Except for those that are provided by the container. Regarding the jsp stuff: Can I serve JSPs from inside a JAR in lib, or is there a workaround?
When mocking dependent services for writing unit test cases for any enterprise-grade java service, I find setting up the data for the unit test cases a huge pain. Most of the times, this is the single most compelling reason for developers to not write unit test cases and rather write integration style test cases. If the service is dependent on couple of other services (which depend on their respective DAO's) and a DAO of its own, generating the when-thenReturn clauses for a reasonably nested object becomes quite an effort and developers are seen to be taking the easy route and loading the entire spring context and sourcing their data from the direct sources which may not always give the data that can traverse all required code paths. With this in the background, a colleague of mine suggested that why not run a sample integration test, and using aspects, capture all of the relevant data points and serialize it to an XML representation which may be used for materializing test data for the unit test cases. To our pleasant surprise we found a framework called TestDataCaptureJ on github which was very similar to this. It used aspects to capture the data points and it generated the java code to create the objects.
The motivation stated on the site seemed very apt and I was wondering if there are any other alternatives that can give similar features. Also, it would be great if the experts can critique this overall approach.
Also, the project is about 2 yrs old and has a few bugs which we we had to fix and are hoping to give it back as a mavenized github fork. Just checking to ensure that there is no other similar initiative from one of the well-known stables as well.
Thanks in advance!
I have two critiques to that approach... and please bear in mind that my knowledge of your context is almost nil, which means that what I suggest here might not work for you.
I've only once experienced a problem like the one you mentioned, and it was a symptom that there was too much coupling between the objects because the responsbilities were way to broad. Since then I use a Domain-Driven Design approach and I haven't had this problem again.
I prefer to use Test-Data Builders to create test data. This approach allows me to have a template of what I want to build, and just replace the bits I'm interested in the test. If you decide to go this way, I strongly suggest you to use a tiny library called Make-It-Easy that simplifies the creation of these builders.
And two suggestions
If you have some time, I suggest you to
Watch a presetation called The Deep Synergy Between Testability and Good Design by Michael Feathers - Part of the talk is about something very similar to what you're experiencing.
Read the book Growing Object-Orieted Systems, Guided by Tests (aka GOOS), it has all sorts of insights about how to write simple, amazing, testable code.
We have an agile enterprise application built on JSP and Servlet without any design strategy.
This application was built in early 2002 considering 1000 users. After 2002, we received lots of requests from the marketing partners.
Currently, the application has lots of spaghetti code with lots of Ifs and elses. One class has more than 20,000 lines of code with a huge body of functions without abstraction.
Now, we need to support billions of records,
what we need to do immediately and gradually?
We have to refactor the application?
Which framework, we need to use?
How the usage of the framework will be helpful to the end users?
How to convince the leaders to do the refactoring?
How to gain the faster response time as compare to the current system?
Here is how I would approach this if I had appropriate company resources at my disposal (yeah right):
Get a good QA process going, with automated regression testing set up before making significant changes. I don't care how good you are, you can't put a system like that under unit test and reasonably control for regressions.
Map out interdependencies, see how much an individual class can be tested as a unit.
How do you eat an elephant? One bite at a time. Take a given piece of required functionality (preferably something around the increase load requirements) and refactor the parts of the class or classes that can be worked on in isolation.
Learn how do 3 above by reading Working Effectively with Legacy Code.
Convenient way to refactor the application.
There are no "convenient" or "easy" ways to refactor an existing codebase, especially if the codebase looks like spaghetti.
... what we need to do immediately and gradually?
That's impossible to answer without understanding your system's current architecture.
We have to refactor the application?
On the one hand, the fact that you have a lot of poorly designed / maintained code would suggest that it needs some refactoring work.
However, it is not clear that it will be sufficient. It could be that a complete rewrite would be a better idea ... especially if you need to scale up by many orders of magnitude.
Which framework, we need to use?
Impossible to answer without details for your application.
How the usage of the framework will be helpful to the end users?
It might reduce response times. It might improve reliability. It might allow more online users simultaneously. It might do none of the above.
Using a framework won't magically fix a problem of bad design.
How to convince the leaders to do the refactoring?
You need to convince them that the project is going to give a good return on investment (ROV). You / they also need to consider the alternatives:
what happens if you / they do nothing, or
is a complete rewrite likely to give a better outcome.
How to gain the faster response time as compare to the current system?
Impossible to answer without understanding why the current system is slow.
The bottom line is that you probably need someone from outside your immediate group (e.g. an external consultant) to do a detailed review your current system and report on your options for fixing it. It sounds like your management don't trust your recommendations.
These are big, big questions. Too broad for one answer really.
My best advice is this: start small, if you can. Refactor piece by piece. And most importantly, before touching the code, write automated tests against the current codebase, so you can be relatively sure you haven't broken anything when you do refactor it.
It may not be possible to write these tests, as the code may not be testable in it's current format. But you should still make this one of your main goals.
By definition refactoring shouldn't show any difference to the users. It's only to help developers work on the code. It sounds like you want to do a more extensive rewrite to modernize the application. Moving to something like JSF will make life a lot easier for developers and will give you access to web component libraries to improve the user experience.
It is a question which needs a lengthy answer. To start with I would suggest that the application is tested well and is working as per the specification. This means there are enough unit, integration and functional tests. The functional tests also have to be automated. Once these are in place, a step by step refactoring can take place. Do you have enough tests to start?
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I find the nature of this question to be quite suited for the practical-minded people on Stack Overflow.
I'm setting out on making a rather large-scale project in Java. I'm not going to go into specifics, but it is going to involve data management, parsing of heterogeneous formats, and need to have an appealing interface with editor semantics. I'm a undergraduate student and think it would evolve into a good project to show my skill for employment -- heck, ideally it would even be the grounds for a startup.
I write to ask you what shortcuts I might not be thinking about that will help with a complicated project in Java. Of course, I am planning to go at it in Eclipse, and will probably use SWT for the GUI. However, I know that Java has the unfortunately quality of overcomplicating everything, and I don't want to get stuck.
Before you tell me that I want to do it in Python, or the like, I just want to reiterate why I would choose Java:
Lots more experience with algorithms in Java, and there will be quite a bit of those.
Want a huge library of APIs to expand functionality. ANTLR, databases, libraries for dealing with certain formats
Want to run it anywhere with decent performance
I am open-minded to all technologies (most familiar with Java, perl, sql, a little functional).
EDIT: For the moment, I am giving it to djna (although the low votes). I think all of your answers are definitely helpful in some respect.
I think djna hit better the stuff I need to watch out for as novice programmer, recognizing that I'm not taking shortcuts but rather trying not to mess up. As for the suggestions of large frameworks, esp. J2EE, that is way too much in this situation. I am trying to offer the simplest solution and one in which my API can be extended by someone who is not a J2EE/JDBC expert.
Thanks for bringing up Apache Commons, although I was already aware. Still confused over SWT vs. Swing, but every Swing program I've used has been butt ugly. As I alluded to in the post, I am going to want to focus most on the file interchange and limited DB features that I have to implement myself (but will be cautious -- I am aware of the concurrency and ACID problems).
Still a community wiki to improve.
Learn/use Spring, and create your project so it will run without a Spring config (those things tend to run out of control), while retaining the possibility to configure the parameters of your environment in a later stage. You also get a uniform way to integrate other frameworks like Hibernate, Quartz, ...
And, in my experience, stay away from the GUI builders. It may seem like a good deal, but I like to retain control of my code all the time.
Google-collections:
http://code.google.com/p/google-collections/
Joda Time for all date and time manipulations.
One of Hibernate or iBATIS to manipulate data in a database
Don't forget the IDE: Eclipse, Netbeans or IDEA if you have some cash and like it
Apache Commons has a lot of time saving code that will you most likely need and can reuse.
http://commons.apache.org/
A sensible build and configuration platform will help you along the way, Ant:
http://ant.apache.org/
or Maven (preferably):
http://maven.apache.org/
Especially as the size of the project, and the number of modules in the project increase.
There's getting the "project" completed efficiently and there are "short cuts". I suspect the following may fall into the "avoiding wasted effort" category rather be truly short cuts but if any of them get you to then end more quickly then I perhaps they help.
1). Decomposition and separation of concerns. You've already identified high-level chunks (UI, persistence layer, parser etc.). Define the interfaces for the provider classes as soon as possible and have all dependent classes work against those interfaces. Pay a lot of attention to the usability of those interfaces, make them easy to understand - names matter. Even something as simple as the difference between setShutdownFlag(true) and requestShutdown(), the second has explicit meaning and hence I prefer it.
Benefits: Easier maintenance. Even during initial development "maintenance" happens. You will want to change code you've already written. Make it easy to get that right by strong encapsulation.
2). Expect iterative development, to be refining and redesigning. Don't expect to "finish" any one component in isolation before you use it. In other words don't take a purely bottom up approach to developing your componenets. As you use them you find out more information, as you implement them you find out more about what's possible.
So enable development of higher level components especially the UI by mocking and stubbing low level components. Something such as JMock is a short-cut.
3). Test early, test often. Use JUnit (or equivalent). You've got mocks for your low level components so you can test them.
Subjectively, I feel that I write better code when I've got a "test hat" on.
4). Define your error handling strategy up front. Produce good diagnostics when errors are detected.
Benefits: Much easier to get the bugs out.
5). Following on from error handling - use diagostic debugging statements. Sprinkle them liberally throughout your code. Don't use System.out.println(), instead use the debugging facilities of your logging library - use java.util.logging. Interactive debuggers are useful but not the only way of analysing problems.
Don't discount Swing for the GUI. There are a lot of good 3rd party Swing libraries available (open source and commercial) depending on your needs e.g.
JGoodies Form Layout
SwingX
JFreeChart
Use logging framework (i.e. Log4J) and plan for it. Reliable logging system saves a lot of time during bug fixing.
For me big time-savers are:
use version-control (Subversion/Git)
use automatic builds (Ant/Make/Maven)
use Continuous-integration (Hudson/CruiseControl)
the apache-commons-libraries are very useful
Test Driven Development
Figure out the functionality you want and write tests to demonstrate the functionality. Then write just enough code to pass the tests. This will have some great side effects:
By writing just enough code to satisfy your requirements you will not be tempted to overbuild, which should reduce complexity and make your code cleaner.
Having tests will allow you to "refactor with confidence" and make changes to the code knowing you're not breaking another part of the system.
You're building quality in. Not only will you have assurance that you code "works, but if you really want to use this code as a sort of "resume" for potential employers, this will show them that you place a lot of value on code quality. This alone will set you apart from the majority of the developers out there.
Aside from that, I would agree that other big time savers are Spring, having an automated build (Maven), and using some form of source control.
For data persistency, if you're not certain that you must use SQL, you should take a look at alternate data-storage libraries:
Prevayler: an in memory database systems, using developing ideas like "crash only components", that make it easy to use and very performatic. May be used even for simple applications where you just need to save some state. It has a BSD License.
BerkleyDB Java Edition: a storage system with different layers of abstraction, so one can use it as a basic key-value storage (almost an in-disk hashtable) to a fully transactional ACID system. Take a look at it's licensing information because even some commercial software may use it for free.
Be aware that they have trade-offs when compared with each other or with a standard SQL database! And, of course, there may be other similar options around, but these are the ones I know and like. :)
PS: I was not allowed to post the respective links because I'm a new user. Just google for them; first hits are the right ones.
You can save time between restarts by using JavaRebel (commercial). Briefly, this tool allows you to write your code in Eclipse and have the code changes picked up instantly.
Spring Roo can not only get your project quickly kickstarted (using a sound architecture) but also reduce your ongoing maintenance. If you're thinking of using Spring, servlets, and/or JPA, you should definitely consider it. It's also easy to layer on things like security.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I joined a new company about a month ago. The company is rather small in size and has pretty strong "start-up" feel to it. I'm working as a Java developer on a team of 3 others. The company primarily sells a service to for businesses/business-type people to use in communicating with each other.
One of the main things I have been, and will be working on, is the main website for the company - from which the service is sold, existing users login to check their service and pay their bills, new users can sign up for a trial, etc. Currently this is a JSP application deployed on Tomcat, with access to a database done thru a persistence layer written by the company itself.
A repeated and growing frustration I am having here (and I'm pretty happy with the job overall, so this isn't an "oh no I don't like my job"-type post) is the lack of any larger design or architecture for this web application. The app is made up of several dozen JSP pages, with almost no logic existing in Servlets or Beans or any other sort of framework. Many of the JSP pages are thousands of lines of code, they jsp:include other JSP pages, business logic is mixed in with the HTML, frequently used snippets of code (such as obtaining a web service connection) is cut and paste rather than reused, etc. In other words, the application is a mess.
There have been some rumblings within the company of trying to re-architect this site so that it fits MVC better; I think that the developers and higher-ups are beginning to realize that this current pattern of spaghetti code isn't sustainable or very easily scalable to add more features for the users. The higher-ups and developers are wary of completely re-writing the thing (with good reason, since this would mean several weeks or months of work re-writing existing functionality), but we've had some discussions of (slowly) re-writing certain areas of the site into a new framework.
What are some of the best strategies to enable moving the application and codebase into this direction? How can I as a developer really help move this along, and quickly, without seeming like the jerk-y new guy who comes into a job and tells everyone that what they've written is crap? Are there any proven strategies or experiences that you've used in your own job experience when you've encountered this sort of thing?
Your best bet is probably to refactor it slowly as you go along. Few us of have the resources that would be required to completely start from scratch with something that has so many business rules buried in it. Management really hates it when you spend months on developing an app that has more bugs than the one you replaced.
If you have the opportunity to build any separate apps from scratch, use all of the best practices there and use it to demonstrate how effective they are. When you can, incorporate those ideas gradually into the old application.
First pick up a copy of Michael Feather's Working Effectively with Legacy Code. Then identify how best to test the existing code. The worst case is that you are stuck with just some high level regression tests (or nothing at all) and If you are lucky there will be unit tests. Then it is a case of slow steady refactoring hopefully while adding new business functionality at the same time.
In my experience, the "elegance" of an app typically has more to do with the database design than anything. If you have a great database design, including a well-defined stored procedure interface, good application code tends to follow no matter what platform you use. If you have poor database design, no matter what platform you use you'll have a very difficult time building elegant application code, as you'll be constantly compensating for the database.
Of course, there's plenty of room between great and poor, but my point is that if you want good application code, start by making sure your database is up to snuff.
This is harder to do in applications that are only in maintenance mode because it is hard to convince management that rewriting something that is already 'working' is worth doing. I would start by applying the principles of MVC to any new code that you are able to work on (ie. move business logic to something akin to a model, put all your layout/view code in one place)
As you gain experience with new code in MVC you can start seeing opportunities to change the existing code subtly so that it also falls in line. It can be a very slow process, but if you can show the benefits of this way of doing it then you will be able to convince others and get the entire team on board.
I would agree with the slow refactoring approach; for example, take that copy-and-pasted code and extract it into whatever the appropriate Java paradigm is (a class, perhaps? or better yet, use an existing library?). When your code is really clean and terse, yet still lacking in overall architectural strategy, then you'll be able to make things fit into an overall architecture much more easily.
Iteratively refactor. Also look for new features that can be done completely in the new framework as a way to show the value of the new framework.
My suggestion would be to find the rare pages that do not require an import of other JSPs, or have very few imports. Treat each JSP imported as a black box, and refactor these pages around them (iteratively, testing each change and making sure it works before continuing). Once these are cleaned up, you can continue finding pages with more and more imports, until finally you have refactored the imports.
When refactoring, note the parts that try to access resources not given to the page and try to take this out to a controller. For instance, anything that accesses the database should be inside a controller, let the JSP handle the display of the information the controller gives to it via a forward. In this way you will develop several servlets, or things like servlets, for each page. I would suggest using a front-controller based framework for this refactoring (from personal experience I recommend Spring and its Controller interface), so that each controller isn't a separate Servlet but is rather delegated to from a single servlet that is mapped appropriately.
For the controller, it is better to do database hits all at once rather than attempt them piecemeal. Users can and generally do tolerate a page load, but the page output will be much faster if all the database data is given to the rendering code rather than the rendering code hanging and not giving data to the client while it is trying to read yet another piece of data from the database.
I feel your pain and wish you luck in this endeavor. Now, when you have to maintain an application that abuses Spring Webflow, that's another story :)
The best way is to print out the code, crumple it up, and throw it out. Don't even recycle the paper.
You've got an application that is written in 1,000+ line long JSPs. It probably has a god-awful Domain Model (if it even has one at all) and doesn't just MIX presentation with business logic, it BLENDS it and sits there and keeps stirring for hours. There is no way to take out the code that is crappy and move into an MVC Controller class and still be doing the right thing, you'll just end up with a MVC app with an anemic domain model or one that has stuff like Database calls in Controller code, you're still failing.
You could try a new app that does the right thing and then have the two apps talk to each other, but that's new complexity in itself. Also you're likely going to be doing the same amount of work that you were going to do if you just started from scratch, but you might have an easier time trying to convince your bosses that this is a better approach.