I've just started to work in a new place, and I see several things they do that I find really terrible, and I want to know if they are indeed so wrong, or I am just too strict. Please let me know if my criticism is in place, and your opinion on which problem is the worst and should be fixed first. The developement is all in Java.
Not using svnignore. This means svn stat can't be used, and developers forget to add files and break the build.
Generated files go to same folders as committed files. Can't use simple maven clean, have to find them one by one. Maven clean doesn't remove all of them.
Not fixing IDE analyze warnings. Analyze code returns about 5,000 warning, of many different kinds.
Not following conventions: spring beans names sometimes start with uppercase and sometimes not, ant properties sometimes with underline and sometimes with dots delimiter, etc.
Incremental build takes 6 minutes, even when nothing is changed.
Developers only use remote debug, and don't know how to run the Tomcat server internally from the IDE.
Developers always restart the server after every compilation, instead of dynamically reloading the class and saving the server's state. It takes them at least 10 minutes to start checking any change in the code.
Developers only compile from command line. When there are compilation errors, they manually open the file and go the the problematic line.
A complete mess in project dependencies. Over 200 open sources are depended on, and no one knows what is indeed needed and why. They do know that not all dependencies are necessary.
Mixing Maven and Ant in a way that disables the benefits of both. In one case, even dependency checks are not done by Maven.
Not using generics properly.
Developers don't use Subversion integration with IDE (Eclipse, Intellij Idea).
What do you think? Where should I start? Is any of the things I mentioned not really a problem?
I'd look at it like this:
Anything that affects productivity should be solved first
Things that affect profitability solved second (most productivity fixes are profitability fixes too)
Nitpicky stuff last
Therefore, you should have the following (in order of my opinion):
7 - Restarting the Server after Compilation
5 - Incremental Build Speed
6 - Remote Debugging only
8 - Compiling from command line
12 - Subversion Integration (kind of in the same league as 5. above)
2 - Generated Files
11 - Not using Generics Correctly
Then
1 - svnignore
9 - Project Dependencies (this will take a great deal of time i'm sure)
10 - Mixing Maven + Ant
3 - IDE Warnings
4 - Conventions
The reason I have the ordering in this sense is time vs. benefit. If it takes a user 16 minutes to compile and check their code, it's bloody well insane to be honest. Say a developer compiles 5x per day, we're taking about 80 minutes, doing nothing.
After that it's productivity. If you speed up the rate at which your developers can do their work, the turnover of work completed will rise substantially. (Profitability++)
After this is the "nitpicky" things. I say this not as to infer that they're not important, but the fact is from the looks of things you have much bigger fish to fry, so get those done first before correcting casing in code.
Not being a maven user, I can't comment on some of the above but most things in your list look like good areas for improvement. I think the best advice I can give is:
Take it slow. They've probably been doing it this way for ages and may resist change.
Get the team (and possibly the manager(s)) involved in the changes. Hold a meeting to discuss what improvements you see (keep it simple, just a few), what they think of them, and if they think its sensible to implement. Then, if agreed, pair with someone to get the improvement in place.
Offer presentations on working practices which are easily changed. E.g. show them in a live setting the difference of dynamic class loading during a debugging session.
Prioritize the list above and focus on a few at a time.
Be gentle. Change is hard! To much at once will potentially alienate or disengage folk.
Start with quick wins that will make an immediate and positive difference to the developers in the team. This will build their confidence in accepting more difficult changes.
Best of luck...
Comments to the issues
1) Not using svnignore. This means svn stat can't be used, and developers forget to add files and break the build.
Doesn't sound very critical to me - I assume from the above that you have a CI or nightly build (if not, that would be a major issue indeed). The purpose of the CI build is to catch such problems, so IMHO it is not a catastrophe if it is broken every now and then. Of course if it happens daily, that's a different story :-(
2) Generated files go to same folders as committed files. Can't use simple maven clean, have to find them one by one. Maven clean doesn't remove all of them.
This is bad, and is fairly simple to fix (under normal circumstances :-)
3) Not fixing IDE analyze warnings. Analyze code returns about 5,000 warning, of many different kinds.
This is bad, and it takes a lot of time to fix. However, skimming through the analysis results to spot really critical issues could be a high priority task.
4) Not following conventions: spring beans names sometimes start with uppercase and sometimes not, ant properties sometimes with underline and sometimes with dots delimiter, etc.
Not a catastrophe, OTOH easy to fix.
5) Incremental build takes 6 minutes, even when nothing is changed.
This is bad, and (considering cases 9 and 10 below) may be a rather daunting task to fix.
6) Developers only use remote debug, and don't know how to run the Tomcat server internally from the IDE.
A short demo and mentoring should not take a lot of effort. However, there may be cultural issues, and old members of the team might not be willing to learn new tricks. So a sensitive approach is required.
7) Developers always restart the server after every compilation, instead of dynamically reloading the class and saving the server's state. It takes them at least 10 minutes to start checking any change in the code.
Same as above.
8) Developers only compile from command line. When there are compilation errors, they manually open the file and go the the problematic line.
Same as above.
9) A complete mess in project dependencies. Over 200 open sources are depended on, and no one knows what is indeed needed and why. They do know that not all dependencies are necessary.
This is bad, and is a huge task to fix.
10) Mixing Maven and Ant in a way that disables the benefits of both. In one case, even dependency checks are not done by Maven.
Same as above.
11) Not using generics properly.
Do you mean they are still programming the Java 1.4 way using non generic collections et al? If the code is otherwise stable, this can be fixed (and developers educated) gradually.
12) Developers don't use Subversion integration with IDE (Eclipse, Intellij Idea).
See case 6.
Priorities
I would try ordering tasks based on cost vs benefit ratio. My order would be:
First, tasks to simplify and speed up day to day work, and build up your credibility and authority within the team: 7, 6, 8, 12, 2
Then the fundamental, but difficult and time-consuming tasks, for which you need more support from the team: (continuous integration in case there is none yet), 5, 10, 9
The rest can be introduced gradually: 1, 3, 4, 11
You don't mention continuous integration, but one good thing to start with is to give developers a rapid feedback if the build is broken. Once you have it you can add code quality metrics to encourage them to correct warnings or bad use of generics.
Only with all that in place you should start working on their productivity by showing them how to hot deploy, debug, use an IDE and so on...
And good luck :)
In general, I think that stuff that wastes time for developers should be taken care of first. The less idle the developer is, the greater the benefit.
1) This together with 12) should be prioritized higher, as broken builds take time.
3) IDE warnings aren't that important, as they are just warnings and could be as simple as unused imports.
4) Lack of naming conventions doesn't break anything and can be enforced gradually. That will take a lot of time however you do it. This shouldn't be highly prioritized.
5) I assume you have a separated build server that takes care of the builds, six minutes doesn't sound like a very long time. If you don't have a build server, that would be a good investment.
7) Sounds like a lot of time is being wasted for all developers, this should be highly prioritized.
11) These could cause a lot of the warnings in 3), should be fixed, but not highest priority.
12) Subversion integration with IDE should help out a lot, I think the developers would see this as very useful.
First of all, I totally agree with you list of problems since I have been on projects that have basically the same issues.
If you start with the places where you think you can gain the most productivity.
I would think that you can save considerable amount of time with:
Get tomcat running in the IDE.
Fix any build script, maybe also test, issues to make the builds run fast.
Compilation within the IDE and hotdeploy (hotswap/jrebel) will also save you a lot of time.
As already posted, get a continuous build server up and running for the project.
And if you have an issue tracker, add these issues to it so that everyone is aware of what needs to be done. When the high priority stuff has been completed try to push for time to get the other stuff fixed as well, its really annoying with all the small problems and even though they seem small now they can cause considerable headache after a while.
First of all, since you are new, you need to be careful not to be considered very annoying.
I would suggest you start by talking to your own boss, and say that you may have some experiences that might be useful to your new company. Management backup is essential if you want something done rather quickly.
You will need to demonstrate to your boss and coworkers that your suggestions are immediately beneficial to them, in their daily work. Hence select just one pain-point and fix it good (but reversible as going back is a nice option to have when trying things out). Be prepared to do a lot of work yourself and a lot of mentoring.
Based on your description, I would suggest a quick demonstration of a proof-of-concept web application being run inside the IDE with hotspot editing and instant redeployment of changed files would be very eyeopening. Do NOT go to fast - be certain that everybody understand what you do. Then as a final demonstration, do it again but in normal speed.
Related
I'm being asked to assess whether we can safely upgrade the java version on one of our production-deployed webapps. The codebase is fairly large and we want to avoid having to regression test everything (no automated tests sadly), but we've already encountered at least one problem during some manual testing (XmlStringReader.getLocalName now throws an IllegalStateExeption when it just used to return null) and higher-ups are pretty nervous about the upgrade.
The current suggested approach is to do a source compare of the JDK sources for each version and assess those changes to see which ones might have impact, but it seems there's a lot of changes to go through (and as mentioned the codebase is kinda large). Is it safe and easier to just review the java version changes for each version? Or is there an easier way to conduct this assessment?
Edit: I forgot to mention the version upgrade being considered is a minor version upgrade, i.e. 1.6.10 to 1.6.33
Nothing is going to replace testing it in a real system. you may be able to catch something blatant in a bug report or in visual inspection, but detecting changes due to more complex interactions will be impossible. or even detecting seemingly simple changes which alter how the GC affects your running app or how hotspot optimizes your code (you are checking the c++ code too, right) or how some key algorithm performs...
As #jtahlborn says: Nothing will replace testing it properly.
I would go further and state that without automation then this is cost a you will occur again and again.
The correct answer is to
Define a regression
Run it (verify it)
Automate as much as possible as you go through it
A simpler scenario is to simply run it and catch the errors are you or your customers find time. Personally I think this is good way to get demotivated developers, managers and customers. I strongly recommend you don't use this approach.
I'm looking for a way to boost my team's productivity, and one way to do that would be to shorten the time it takes to compile & unit test & package & deploy our Java EE application which is getting bigger and bigger.
The trivial solution that I know of is to set up a powerful computer with N processors (N ~= num of developers) and a blazingly fast disk system and a lot of memory, and run everything on this computer and connect to it via X remotely. It would certainly be much faster than compiling on our laptops, but still cheaper and easier to maintain than to buy each developer his/her own supercomputer.
Is there another way to solve this problem? For example, could we run our IDEs locally and then tell it to remote compile java source? Can Netbeans / Eclipse / IntelliJ / etc. do this? Or is there a special tool that enables remote java compilation, also that makes use of multiple processors? It need not be free/open source.
Unfortunately our laptops MUST run a (company managed) Windows Vista, so another reason to go for the separate server computer is to let us use linux on it and finally get rid of the annoying managed environment.
EDIT: to sum up the answers so far, one way to shorten build times is to leave compilation for the developers individually (because compiling is supposed to be fast), skip running unit tests and hot-deploy (without packaging) to the container.
Then, when the developer decides to check his/her code in, a continuous integration server (such as Hudson) is triggered to clean & build & run tests & package & deploy.
SOLUTION: I've accepted Thorbjørn's answer since I think that's going to be the closest to which way I'm planning to proceed. Although out of curiosity I'm still interested in solving the original problem (=remote Java compiling)...
You essentially need two workflows.
The OFFICIAL build, which checks out the sources, builds the whole thing from scratch, runs all the unit tests, and then builds the bits which will eventually ship to the customer after testing.
Developer hot-deploying after each source code change into the container the IDE knows about.
These two can actually be vastly different!
For the official build, get Jenkins up and running and tell it to watch your source repository and build whenever there is a change (and tell those who break the build). If you can get the big computer for building, use it for this purpose.
For the developers, look into a suitable container with very good IDE deployment options, and set that up for usage for each and every developer. This will VERY rapidly pay off! JBoss was previously very good for exactly this purpose.
And, no, I don't know of an efficient remote java compilation options, and I don't think this is what you should pursue for the developers.
See what Joel thinks about Build Servers: http://www.joelonsoftware.com/articles/fog0000000023.html
If you don't like Jenkins, plenty others exist.
(2016 edit: Hudson changed to Jenkins. See https://stackoverflow.com/a/4974032/53897 for the history behind the name change)
It's common to set up a build server , e.g. running hudson to do the compiling/packaging/unit-testing/deploying.
Though you'd likely still need the clients to at least perform a compile. Shifting to using a build server, you might need to change the work process too if you arn't using a build server now - e.g. if the goal is to take load off the client machines, your developers will check code in , automatic unit tests gets run, instead of running unit tests first, then checking in.
You could mount each developer dir with ntfs on the powerful machine and then create External Tool Configuration in Eclipse (GUI access), that would be triggering build on external server.
JavaRebel can increase productivity also. It eliminates the need for redeployments..
You can recompile a single file and see the changes being applied directly on the server.
When things start getting too big for efficient builds, it may be time to investigate breaking up your code into modules/JARs (how it breaks apart would depend on many project specifics and how your team tends to work). If you find a good setup, you can get away with less compiling (dont always need to rebuild the whole project) and more/quicker copying/jaring to get to the point where you can test new code.
What your project need is a build system to do the building, testing and packaging for you. Hudson is a good example of such a continuous integration build system.
I am a junior software engineer who've been given a task to take over a old system. This system has several problems, based on my preliminary assessment.
spaghetti code
repetitive code
classes with 10k lines and above
misuse and over-logging using log4j
bad database table design
Missing source control -> I have setup Subversion for this
Missing documents -> I have no idea of the business rule, except to read the codes
How should I go about it to enhance the quality of the system and resolve such issues? I can think of using static code analysis software to resolve any bad coding practice.
However, it can't detect any bad design issues or problems. How should I go about resolving these issues step by step?
Get and read Working Effectively With Legacy Code. It deals exactly with this situation.
As others have also advised, for refactoring you need a solid set of unit tests. However, legacy code is typically very difficult to unit test as is, since it has not been written to be unit testable. So you need to refactor first to allow unit testing, which would allow you to start refactoring... a bad catch.
This is where the book will help you. It gives lots of practical advice on how to make badly designed code unit testable with the minimal, and safest possible, code changes. Automatic refactorings can also help you here, but there are tricks described in the book which can only be done by hand. Then once the first set of unit tests are in place, you can start gradually refactoring towards better, more maintainable code.
Update: For hints on how to take over legacy code, you may find this earlier answer of mine useful.
As #Alex noted, unit tests are also very useful to understand and document the actual behaviour of the code. This is especially useful when documentation about the system is nonexistent or outdated.
Focus on stability first. You can't enhance or refactor until you have some kind of stable environment in-place around the application.
Some thoughts:
Revision control. You've made a start by setting-up subversion. Now make sure that your database schemas, stored procedures, scripts, third-party components, etc. are under revision control too. Have a version labelling system, make sure you label versions and can accurately access old versions in the future.
Build and release. Have a way to build stable releases on a machine other than your dev machine. You may want to use ant/nant, make, msbuild, or even a batch file or shell script. You may need deployment scripts / installers too if they don't exist.
Get it under test. Do not change the app until you have a way to know whether your change has broken it. For this you need tests. You should hopefully be able to write xunit unit tests for some of the simpler, stand-alone classes, but try to build some system/integration tests that exercise the application as a whole. Without high code coverage (which you won't have to begin with) integration tests are your best bet. Get into the habit of running the tests as often as possible. Take every opportunity to extend them.
Make small, focussed changes. Try to identify systems/subsystems within the application, and improve the boundaries between them. This reduces the knock-on effects of changes you may make. Beware the temptation to "pretty-up" the code by reformatting it or imposing the latest fashionable design pattern. Turning-around a system like this takes time.
Documentation. Its necessary, but don't worry too much about it. System documentation is rarely used in my experience. Good tests are usually better than good documentation. Concentrate on documenting the interfaces between the application and the system context that it runs in (inputs, outputs, file structures, db schemas, etc).
Manage expectations. If its in bad shape then it will probably resist your efforts to make changes and timescales may be harder than usual to estimate. Make sure management and stakeholders understand that.
At all costs, beware the temptation to just rewrite the whole thing. Its almost never the right thing to do in this situation. If it works, concentrate on keeping it working.
As a junior developer, don't be afraid to ask for help. As others have said, Working Effectively With Legacy Code is a good book to read, as is Martin Fowler's Refactoring.
Good luck!
First, don't fix what isn't broken. As long as the system you are to take over works, leave functionality alone.
The system is obviuosly broken when it comes to maintainability, however, so that is what you tackle. As mentioned above, write some tests first, get the source backed up in a cvs, and THEN start by cleaning up small pieces first, then the larger ones and so on. Do NOT attack the bigger architectural issues until you have gained a good understanding of how the system works. Tools won't help you as long as you don't dive into the code yourself, but when you do, they do help a lot.
Remember, nothing is "perfect". Don't over-engineer. Obey the KISS and YAGNI principles.
EDIT: Added direct link to YAGNI article
Your issue #7 is by far the most important. As long as you have no idea how the system is supposed to behave, all technical considerations are secondary. Everyone is suggesting unit tests - but how can you write a useful test if you can't distinguish between wanted and unwanted behaviour?
So before you start touching the code, you have to understand the system from the user's point of view: talk to users, observe them using the system, write documentation on the use case level.
Yes, I am seriously suggesting that you spend days, more likely weeks, without changing a single line of code. Because right now, any change you make is likely to break things without you realizing it.
Once you understand the app, you'll at least know which functionality is important to test (manually or automated).
Write some unit tests first, and make sure they pass. Then with each refactoring change you make, just keep making sure the tests keep passing. Then you can be confident that your application behaviour to the outside world hasn't changed.
This also has the added benefit that the tests will always be there, so for any future changes the tests should still pass, guarding against any regressions in the new changes.
First and foremost, make sure you have source control system installed and all source code is versioned and can be built.
Next, you can try writing unit test for core parts of your system. From there, when you have a more or less solid body of regression tests, you can actually proceed with refactoring.
When I encounter messy codebase, I usually start with renaming poorly-named types and methods to better reflect their initial intent. Next you can try splitting huge methods into smaller ones.
Keep in mind that this legacy system, with all it's spaghetti code, currently works. Don't go changing things just because they don't look as pretty as they should. Focus on stability, new features & familiarity before ripping old code out left right and centre.
Firstly, let me say that Working Effectively with Legacy Code is probably a really good book to read, judging by three answers within a minute of each other.
bad database table design
This one, you are probably stuck with. If you try to change an existing database design you are probably committing yourself to redesigning the whole system and writing migration tools for the existing data. Leave well alone.
My standard answer to this question is: Refactor the Low-hanging Fruit. In this case, I'd be inclined to take one of the 10K-line classes and seek out opportunities to Sprout Class, but that's just my own proclivity; you might be more comfortable changing other things first (setting up source control was an excellent first step!) Test what you can; refactor what can't be tested, take a step at a time, and make it better.
Keep in mind as you progress how much better you are making things; if you concentrate only on how bad things still are, you're likely to become discouraged.
As others have noted, don't change something that works just to make it prettier. The risk that you will introduce errors is great.
My philosophy is: As I have to make changes to satisfy new requirements or to fix reported bugs, I try to make the piece of code that I have to change a little cleaner. I'm going to have to test the changed code anyway, so now is a good time to do a little clean-up at small additional cost.
Fundamental design changes are the toughest and must be saved for occasions where you have to make a big enough change that you would be testing all the changed code anyway.
Changing bad database design is hardest of all because the poorly designed tables are likely used by many programs. Any change to the database requires changing every program that reads or writes it. The best way to accomplish this is usually to try to reduce the number of places that access any given part of the database. To take a simple example: Suppose there are 20 places that read through customer records and calculate the customer account balance. Replace this with one function that reads the database and returns the total, and twenty calls to that function. Now you can change the schema for the customer records and there is only one piece of code to change instead of 20. The principle is simple enough, but in practice it is unlikely that every function that accesses a given record is doing the same thing. Even if the original programmer was clumsy enough to write the same code 20 times (not unlikely -- I've seen plenty of that), the real situation is probably not that he wrote 1 function 20 times, period, but that he wrote function A 20 times, function B 12 times, function C 4 times, etc.
Working Effectively With Legacy Code might be helpful.
Design issues are very difficult to catch. The first place to start is understanding the design of the application. I find it useful to diagram using either UML or a process flow diagram, anything works that communicates the design and working for the application.
From there I go into more detail, and ask myself the questions "Would I have done it this way", what other options are there. It is easy to see code-debt, i.e. the debt that we get from making bad choices, as always bad, but sometimes there are other factors involved like budget, time, availability of resources etc. Their you have to ask the question if it is worth refactoring a working but bad designed application.
If there are many upcoming new features, changes, bug fixes, etc I would say it is good to refactor, but if the application rarely changes and is stable, then maybe leaving it as is is a better approach.
Another sidepoint to note, is that if the code is used by another application as a service or module, then refactoring might first mean create a stub around the code that servers as the interfaces, once that is defined clearly and has unit test to prove it work. You can choose any technology to fill in the details.
A good book on this subject is Working Effectively with Legacy Code By Michael Feathers (2004). It goes through the process of making small changes, while working towards a bigger clean up.
Write unit test & Find and remove duplicate code.
Write unit test & Break long methods into a series of short methods.
Write unit test & Find and remove duplicate method.
Write unit test & Break apart classes so that the follow the single responsibility principle.
Try to create some unit tests first that can trigger some actions in your code.
Commit everyting in SVN and TAG it (in case that something goes bad you'll have an escape pod).
Use inCode Eclipse plugin http://www.intooitus.com/inCode.html and look for what refactorings it proposes. Check if the refactorings proposed seem ok for your proble. Try to understand them.
Retest with the units created before.
Now you can use FindBugs and/or PMD to check for other subtle issues.
If everything is oka you might want to check-in again.
I'd also try reading the source in order to detect some cases where patterns can be applied.
I am working on a solution that aims at solving problems that newbie programmers experience when they are "modifying code" while bug fixing / doing change requests, on code in production. Eclipse, as we all know is a great IDE. Features such as Code Completion, Open Declaration, Type Hierarchy, Package Explorer, Navigator, Finding References etc aids people in fixing things quicker compared to say using something like Textpad.
If you are a newbie java programmer and you are using Eclipse IDE, what areas of the Eclipse IDE do you think were less helpful/ less intuitive? If you are a seasoned programmer, what are the common issues that newbies look up to you to solve for them?
Please ignore issues related to : Domain Expertise (Business Knowledge), Infra( where to test your change etc), performance related (eclipse search being slow,etc), Skill level in a particular language (think of the developer as a noob) ... and think one language - Java
I did a local survey in my small team and here are some:
Newbies using Eclipse to handle code that is written to interfaces where the implementation is supplied at runtime. Doing a 'Open Declaration' will always show you an interface. This could be confusing at times.
Eclipse is not intuitive while developing EJBs. Sure, you know all you have to do to create a new bean is to right click and 'Create Bean', however, once created it shows no contextual help to what the next step should be. For instance, generating stubs.
When Data Source Mapping with entity beans, changing something screws up the entire flow of things and eclpise never complains / hints.
Developing applications that make use of Struts, eclipse doesn't tell you that when you change struts-config.xml, particular web flow would get affected.
At this point, to me, as someone who is interested in collecting opinions for my research, it appears as if Eclipse could use more 'contextual runtime hints'.
I am sure the community would have a lot more to add... Please add more of your negative experiences (just from the code change perspective).
EDIT:
I guess, my question was too lengthy and confusing. I am gonna rephrase it a bit and keep it short:
While "making a code change" (not analogous to code formatting, infra related activities, CVS etc... say something like refactoring), what feature(s) of eclipse IDE did you not like / hate the most? Here are the examples:
When modifying code that has been written to interfaces: 'Open Declaration /F3 on an object instance shows you the interface when the implementation is supplied at runtime'.
When changing apps using EJBs: No contextual help
When changing apps using MVCs(Spring / Struts) : No warnings about change impact.
Missing in Eclipse are:
Software visualization, as for example System Complexity View [Lanza 2003]
And also by Lanza, the Class Blueprint [Ducasse 2005]
Post Scriptum: Software visualization in Eclipse: X-Ray provides System Complexity View of Java projects, http://xray.inf.usi.ch/xray.php (via #anjaguzzi and Paul Lammertsma)
And then collaborative filtering "other developers that edited this method before also edited" [Zimmermann 2005]
And the collection of browsable examples, and autocompletion at the level of these examples. That is, for example if your write
ByteBuffer buf = file.
and hit autocompletion it should search the codebase and the interwebs for examples that convert files to bytebuffers and insert that 10-20 lines there.
Parseweb supports developers by recommending method invocation sequences that yield a required
destination data type from given input parameter types. http://doi.acm.org/10.1145/1453101.1453129
Prospector supports developers by recommending method invocation sequences that yield a required
destination data type from given input parameter types.http://doi.acm.org/10.1145/1064978.1065018
Strathcona provides source code examples and structural con-
text for the code fragment under development. http://lsmr.cpsc.ucalgary.ca/papers/holmes-icse-2005.pdf
Rascal recommends how and when to call the methods of objects from common libraries such as Java Swing, based on an analysis of existing classes. It uses collaborative filtering. http://dx.doi.org/10.1007/s10462-005-9012-8
And of course also the feature that I can write a Unit test and then the IDE searches the interwebs for classes that pass the test. Yes, this can be done!
CodeGenie is an Eclipse plugin that allows you to write unit tests and then uses the Sourcerer source code search engine to find passing classes. http://doi.acm.org/10.1145/1529282.1529384
CodeConjurer which is based on Merobase also offers that feature, see http://dx.doi.org/10.1109/MS.2008.110
This list could go on and on, good starting points for more work are the proceedings of past
Conference on Mining Software Repositories (MSR)
Workshop on Search-driven Software Engineering (SUITE)
Workshop on Recommendation Systems for Software Engineering (RSSE)
which are all under the umbrella of the ICSE conference.
"newbie issues" I've seen myself (I've used Eclipse for a good while, but it keeps "surprising" me occasionally) and helping colleagues just starting to use Eclipse:
It's large and complex enough to be very intimidating to some at first. Seems people consider netbeans easier to use initially. One colleague took refuge with the VI editor for a god while...
Installing plugins can be tricky (finding site URLs, awareness of plugins, why is "install"+"update" under the Help menu???)
Updates are still slow (but much better than before) with Eclipse 3.5/Galileo. It's difficult to understand which plugins to install just by their name sometimes.
Any platform besides Mac - preferences under the Window menu seems illogical?
Understanding how to set the project class path neatly. Setting the right project JDK version.
Lack of or unexpected interaction between ant/maven build tools' classpath and that of eclipse's (ant/maven clean causes Eclipse compiler errors when classpath is shared etc.).
Views and (large number of) perspectives are confusing/overwhelming at first. Which are useful when? How to drag views to the desired location or restoring closed ones?
Some JDK/Eclipse version combinations required too much PermGen space than available by default, took a while to diagnose.
For me, most of the newbie problems in Eclipse come from one of it's strengths, its configurability & plugin structure.
When I need to change a property in Eclipse, I always seem to have to spend a few minutes working out where to change it. Example: changing the Java editor to insert 4 spaces instead of a tab. The search bar in the properties is always welcome :-)
That and the lack of documentation for some of the plugins always makes for fun when I'm setting up a project.
EDIT: You can always show the classes that implement an interface using ctrl-T.
One thing I would add is that when I have a complex project, I tend to use Refresh & Project->Rebuild All *a lot". And I use TortoiseSVN to maniuplate stuff outside of Eclipse, because a lot of times this is easier (some refactoring for instance). However, if I'm modifying the project outside of Eclipse, I *always" quit Eclipse, and do a full refresh and build when I restart it. Otherwise Eclipse gets very confused sometimes.
I think the biggest problem I faced (and still face) with Eclipse is that it isn't particularly aware of standard technologies that surround modern Java development. If I'm developing an application, it might include the following:
Spring
Maven
JSF/Struts 2
Subversion
JUnit
I think Eclipse handles those technologies in increasing levels of awareness: (so JUnit will be fine, it works out of the box; Subversion requires Subclipse, and it's a little ropier than the CVS support; JSF needs some WTP tooling to be installed; Maven...you're probably best off setting up your own external tools commands rather than trust M2Eclipse, unless it's become dramatically better in recent times; and Spring, well, as you say, try ctrl-clicking on a method and you'll almost certainly get an interface, because the implementation is hidden away behind a Spring config file).
Getting all of that to play together and check out/compile, then later compile/run tests/check in is the difficult bit. The code change itself is probably easy :)
For me, the biggest hurdle to learning to use eclipse effectively was understanding where to set the classpath and also how to figure out exactly what is included on the classpath for various stages of development (compile, build, test). I was confused for a long time about the difference between compile time, debug configurations, and run configurations classpaths. Then if you throw ant into the mix (which automatically creates a run configuration ) it makes it even more confusing for newbies.
As a beginner, I didn't do EJB or Struts stuff. Or even data source mapping. So I think the question's title may be a little misleading.
I would have appreciated having something like JadClipse built in to "look at" library code when I hit it in debugging or such. But it should be made VERY clear that this is "reconstituted code" and not meant to be hacked around in.
Second, noobs need to be made much more aware that Shift-F2 will get them the API documentation for whatever class/method they're looking at. I know too many novice Java programmers who explore their APIs with nothing more than code completion; they're missing many valuable hints provided by the library authors.
A mindreader which generates code on the fly, so that a single click is sufficient to complete a project.
I found Visual Studio easy to pick up, I tried clicking on each button at least once, and figured out what the whole thing does. It's thought out by a single design team at the highest level, and everything follows the standards top to bottom, more or less.
Then, I play with Eclipse. In technical terms, it's janky at best. Look at the preferences dialog; it's an overwhelming trainwreck, unless you already know exactly what you're looking for, and what the developer working on that feature decided to call it.
Eclipse's configurability relies on the fact you already know how to configure it. The learning curve there is awful, and the only saving grace is that most of the defaults are okay to begin with.
I was a noob to eclipse recently, mostly doing Android and BlackBerry stuff. And one thing that eludes me to this day is the massive multitude of options and settings and various places they can be found in. For instance, if you have a plugin installed (say BlackBerry plugin), the setting might be found in the general prefs or BlackBerry prefs or the project prefs.
It's always a hunt.
Here are basic missing features as far as I know :
Show the beginning '{' when you are at the end '}' where beginning '{' is out of the view
Automatically synchronize the editor with package explorer
Go to different view (package explorer, outline, etc) with keyboard
Inline find, which does not open a dialog.
Go to next error location with keyboard
Go to next/previous structure with keyboard
More stability in general.
These features work great in IntelliJ. Especially #1 and #5 are really useful.
VCS integration - typically the developer is also new to merging changes, keeping working copies in sync, resolving conflicts and so on. There are often several ways of achieving the same thing in Eclipse and I've seen this cause confusion on several occasions (actually, I've seen this with experienced developers too; they know Subversion but not Eclipse, and the latter tries to 'hide' the underlying repository operations).
I think the issue with all IDEs for beginners is the disconnection from the tool chain: how the compiler takes some source and compiles it to bytecode which I then run using the VM with a correctly configured classpath.
As a dev I love the fact I don't need to deal with this - and I've never found myself unable to do what I want concerning more complex build configurations - but it's too important for beginners to understand what's happening when you press that Play button to be ignored.
when i first tried using eclipse i absolutely hated it's coplexity.. you had to do a whole bunch of things befor you were able to start working. furthermore you have way to many options to check and it's not always selfexplaining what each button does.
instead i started using netbeans. way more intuitive and easier to handle. check there gui.. not to much buttons and most of the time you know what the button does even if you have no clue of java (as i had at that time).
when i changed back to eclipse (due to some features not supported in netbeans) it seemed far easier to work with it. so some part of the gui might just be added in a not intuitive way and beginners will definitly have a hard time with it.
simplicity
clearness
consistency
I might write it much more in detail, but i think, that eclipse is overweight and much too much oriented on features - instead of ease of use. IMO, this concerns beginners as well as professionals.
Eclipse has no visual designer for Swing components.
Compare that to Visual Studio, where:
click 'new form'
drag buttons and text boxes onto the form, move them around, add some labels
double click on a button, add some code
done, one quick application, show it to the boss, get paid/promotion/coffee break
In Eclipse you either have to use Netbeans instead (ie not Eclipse...), or use IBM's SWT, or code the Swing forms by hand.
I feel it would be very nice to have a great wysiwyg forms designer in Eclipse for Swing forms.
The other confusing part is that for web development there is a separate version that needs to be used! Well I didn't like this at all and I know that a lot of people just don't about this.
Eclipse is missing Maven Embedded in standard distribution , Maven would help any user in getting their program all the jars and better library management .
Netbeans already has this tools.
Also eclipse misses integrated tools for hibernate , spring , xfire and tomcat deployment using maven.
Check this site http://maven.apache.org/
All of my other problems with Eclipse have already been mentioned except one: It's slooooooooow. Was their goal to prove the "Java is slow" people right? I'm guessing this is related to the "Eclipse does everything", but I stopped using it because it lags every time I click on anything. Change tabs? Lag. Open preferences? Lag. Change tabs in preferences? Lag. It's like using Photoshop with 32 Mb of memory.
Oh and it's incredibly ugly. I wish I could get it with real GTK+ integration.
The android SDK integration is full of jank. xml layouts don't render correctly. Code completion doesn't work well. IBM needs to fix the jank for sure.
We have a large codebase that takes approx 12 minutes on the developer machines to auto-generate some Java 5 classes using JavaCC and then compiles all the classes as well as running the units test.
The project consists of multiple projects which can be built in groups, but we are aiming for a full a build in under 10 minutes
What tips are there for reducing this build time?
Thanks
One quick fix that might shave some time off is to ensure that you are running Ant using the server JVM (by default it uses the client VM). Set ANT_OPTS to include "-server".
Profile the build process and see where the bottlenecks are. This can give you some ideas as to how to improve the process.
Try building independent projects in parallel on multi-core/CPU machines. As an extension of this idea, you may want to look around for a Java equivalent of distcc (don't know whether it exists) to distribute your build over a number of machines.
Get better machines.
some tips for reducing build time:
do less work.
e.g. remove unnecessary logging/echoing to files and
console
make your build 'incremental'.
Compile only changes classes.
eliminate duplicated effort.
Easier said than done, but if you run
the build in debug mode ("ant -debug") you can sometimes see
redundant tasks or targets.
avoid expensive operations.
copying of files, and packaging of jars into wars are necessary for release.Signing jars is expensive and should only be done, if possible' for milestone releases rather than every build
Try be inspired by pragmatic programmer. Compile only what is necessary, have two or more test suites. One for quick tests, other for full tests. Consider if there is real need to use each build-step every time. It necessary try to use jikes compiler instead of javac. After project spans several hundreds of classes I switch to jikes to improve speed. But be aware of potential incompatibility issues. Don't forget to include one all in one target to perform every step with full rebuild and full test of project.
Now that you've explained the process in more detail, here are two more options:
A dedicated machine/cluster where the build is performed much quicker than on a normal workstation. The developers would then, before a commit, run a script that builds their code on the dedicated machine/cluster.
Change the partitioning into sub-projects so that it's harder to break one project by modifying another. This should then make it less important to do a full build before every commit. Only commits that are touching sensitive sub-projects, or those spanning multiple projects would then need to be "checked" by means of a full build.
This probably wouldn't help in the very near term, but figured I should throw it out there anyway.
If your project is breakable into smaller projects (a database subsystem, logging, as examples), you may be interested in using something like maven to handle the build. You can run each smaller bite as a separate project or module, and maven will be able to maintain what needs to be built if changes exist. In this the build can focus onthe main portion of your project and it won't take nearly as long.
What is the breakdown in time spent:
generating the classes
compiling the classes
running the tests
Depending on your project, you may see significant increases in build time by allocating a larger heap size to javac(memoryMaximumSize) and junit(maxmemory).
Is it very important that the entire build lasts less than 10 minutes? If you make the sub-projects independent from one another, you could work on one sub-project while having already compiled the other ones (think Maven or Ivy to manage the dependencies).
Another solution (and if your modules are reasonably stable) is to treat your sub-projects as standalone projects. Each project would then follow their own release cycle and be available from a local Maven/Ivy repository. This of course works well if at least parts of the project are reasonably stable.