I am starting a new project which might be open-sourced later on and/or at least get some external contributors during its life-time.
I am now thinking about what the best approach to code-style / auto-formatting would be. I am a strong supporter of only having auto-formatted code committed to a project, as this eliminates the differences between individual developers and helps keeping individual commits clutter-free of reformatting issues.
My first approach was to use Eclipse built-in style for the project, but I really don't like the default style, because I think line-break at 80 characters is way out-dated for today's screen resolutions. Also, as the name suggests, it's available only for people using Eclipse as IDE.
So I was also thinking about using my own formatter settings and checking the exported settings into the project's repository so that any contributor can pick them up. Again, this would force most people to use Eclipse, as I am not aware of any formatting definition that can be read by multiple IDEs.
Any hint how this is handled in other projects? I searched some github repositories, but to me it seems that this issue is more or less ignored by a lot of projects.
I do understand that this question may be border-line for Stack Overflow, as I don't know if a definite answer is possible and if this triggers a discussion, but it is something I often struggle with when starting a new project.
While screens grow wider, they don't seem to grow taller.
Whatever you other drivers are, preserve vertical space. Put { and } on lines containing other language key words, if you can.
In any case, use a maven plugin or other automated tool in your compile chain to enforce the rules that you care about. That way they are unambiguous.
Also don't create too many rules that don't matter. Each rule costs time to make the code comply.
I understand your concern and in my opinion the best approach is to create code formatting preference file which can be shared along with the project.
For example in eclipse Using a file explorer, navigate to //.settings and copy org.eclipse.jdt.core.prefs to a new location. This file contains all your formatting settings. Hence this can be shared to maintain the code formatting consistencies.
If not that then you might have to rely on the editor specific code formatting.
I definitely look forward to other expert opinion on the same if what I have shared is not optimal as per the requirement.
Related
I have an array of configs that while they may possibly change in the future, the likelihood is that they will never have to be changed.
If any are missing or incorrect then a certain feature of my system will not work correctly.
Should these still be retrieved be some sort of config, either xml, database etc and made available to the end user to change - or is this a good situation where it makes more sense to hard code them in the class that uses them?
I have spent a long time changing mind over and over on this.
Designer's estimate of the likelihood of something needing to change is not a reliable criterion to make a decision, because real-world use of our programs has its peculiar ways of proving us wrong.
Instead of asking yourself "how likely is something to change?", ask yourself "does it make sense for an end-user to make a change?" If the answer is "yes", make it user-changeable; otherwise, make it changeable only through your code.
A particular mechanism through which you make something changeable (a database, a configuration file, a custom XML file, and so on) does not matter much. An important thing is to have good defaults for settings that are missing, so that your end-users would have harder time breaking your system by supplying partial configurations.
Best practice is to use any kind of config or properties file and use default values and failsafe if the file is damaged/missing. These approach has the following advantages:
It can easily be recognised as a config file meaning another dev would not need to dive through your classes to change a parameter
property files can be written by build tools like ant, so if you have e.g. a test server address and a productive server address the ant task could change the content accordingly
it works with default values even without it
Disadvantage is the added complexity.
Yes, it's almost certainly a bad idea to hard-code them; if nothing else, it can make testing (whether automated or manual) a lot more difficult than it needs to be. It's easy to include a .properties file in your jar with the usual defaults, and changing them in the future would just require overriding them at runtime. Dependency injection is usually an even better choice if you have the flexibility to arrange it.
If the configs will never gonna change as you said then its fine if you declare those properties as a variable in interface or a separate class and use this constant through out the program.
Separate property files are used only when some property value are not fixed and is depend on environment like database name,username, password etc. Whereas some property are fixed and is not dependent on the environment in which it is going to deploy like portno, tablenames if any etc.
It depends on your application. As a baseline, its good design to use static variables to hold data that your program will need, instead of hardcoding strings and integers all over the place; This means any changes (i.e. application wide font color) in the future will only require a single change, then a compile cycle and your good to go.
However, if these settings are user configurable, then they cannot be hard coded, but instead need to be read from an external source, and where you do it, is a matter of design, complexity and security.
Plain text files are good for a small application, where security is lax and things are plain text. The SublimeText editor and notepad++ editor do this for their theme settings and it works well. (I believe it was plain text, perhaps they have moved to XML now)
A better option is XML, as it is structured, easier to read/parse/write. Lots of projects use this as an option. One thing to look out for is corrupt files, while reading/writing to them, if the user closes the program or the JVM exits randomly for whatever reason. You might want to look at things like buffers. And also deal with FileNotFoundExceptions, if the text/xml file is missing.
Another option is a database file of some sort, its a bit more secure, you can add application level encryption and you have a multitude of options. Large programs that already use a DB backend, like MySQL, already have a database to hand, so create a new table and store the config there. Small applications can look at SQLite as an option.
Never ever hard code things if hey "might" change, or you might be sorry later and make others mad (very likely in big or/and open source projects). If the config will never change, it is not a config any more but a constant.
Only use hard coding when experimenting with code.
If you want to save simple values, you can user java properties.
Look HERE for an example.
good luck.
There are some properties you can change without having to retest the software. These properties you have tested for a range of values, or you are sure it is safe to change with at most a restart. This properties can be made configurable.
There are other properties which you cannot assume will just work without retesting the software. In this case it is better to hard code them IMHO. This encourages you to go through the release process when you change such a value. Values which you never expect to change are a good candidate for this.
I have a Java-based server, transmitting data from many remote devices to one app via TCP/IP. I need to develop several versions of it. How can I develop and then dwell them without need in coding for 2 projects?I'm asking not only for that project, but for different approaches.
Where the behaviour differs, make the behaviour "data driven" - typically by externalizing the data the drives the behaviour to properties files that are read at runtime/startup.
The goal is to have a single binary whose behaviour varies depending on the properties files found in the runtime environment.
Java supports this pattern through the Properties class, which offers convenient ways of loading properties. In fact, most websites operate in this way, for example the production database user/pass details are never (should never be) in the code. The sysadmins will edit a properties file that is read at start up, and which is protected by the operating system's file permissions.
Other options are to use a database to store the data that drives behaviour.
It can be a very powerful pattern, but it can be abused too, so some discretion is advised.
I think you need to read up on Source Control Management (SCM) and Version Control Systems (VCS).
I would recommend setting up a git or Subversion repository and adding the code initially to trunk and then branching it off to the number of branches (versions you'll be working on).
The idea of different versions is this:
You're developing your code and have it in your SCM's trunk (or otherwise known as a HEAD). At some point you consider the code stable enough for a release. You therefore create a tag (let's call it version 1.0). You cannot (should not) make changes to tags -- they're only there as a marker in time for you. If you have a client who has version 1.0 and reports bugs which you would like to fix, you create a branch based on a copy of your tag. The produced version would (normally) be 1.x (1.1, 1.2, etc). When you're done with your fixes, you tag again and release the new version.
Usually, most of the development happens on your trunk.
When you are ready with certain fixes, or know that certain fixes have already been applied to your trunk, you can merge these changes to other branches, if necessary.
Make any other version based on previous one by reusing code base, configurations and any other asset. In case if several versions should be in place at one time use configuration management practices. Probably you should consider some routing activities and client version checks on server side. This is the place where 'backward compatibility' comes to play.
The main approach is first to find and extract the code that won't change from one version to another. The best is to maximize this part to share the maximum of code base and to ease the maintenance (correcting a bug for one means correcting for all).
Then it depends on what really changes from one version to another. The best is that on the main project you can use some abstract classes or interfaces that you will be able to implement for each specific project.
First off, I'm coming (back) to Java from C#, so apologies if my terminology or philosophy doesn't quite line up.
Here's the background: we've got a growing collection of internal support tools written for the web. They use HTML5/AJAX/other buzzwords for the frontend and Java for the backend. These tools utilize a lightweight in-house framework so they can share an administrative interface for security and other configuration. Each tool has been written by a separate author and I expect that trend to continue, so I'd like to make it easy for future authors to stay "standardized" on the third-party libraries that we've already decided to use for things like DI, unit testing, ORM, etc.
Our package naming currently looks like this:
com.ourcompany.tools.framework
com.ourcompany.tools.apps.app1name
com.ourcompany.tools.apps.app2name
...and so on.
So here's my question: should each of these apps (and the framework) be treated as a separate project for purposes of Maven setup, Eclipse, etc?
We could have lots of apps appear here over time, so it seems like separation would keep dependencies cleaner and let someone jump in on a single tool more easily. On the other hand, (1) maybe "splitting" deeper portions of a package structure over multiple projects is a code smell and (2) keeping them combined would make tool writers more inclined to use third-party libraries already in place for the other tools.
FWIW, my initial instinct is to separate them.
What say you, Java gurus?
I would absolutely separate them. For the purposes of Maven, make sure each app/project has the appropriate dependencies to the framework/apps so you don't have to build everything when you just want to build a single app.
I keep my projects separated out, but use a parent pom for including all of the dependencies and other common properties. Individual tools / projects have a name and a reference to the parent project, and any project-specific dependencies, if any. This works for helping to keep to common libraries and dependencies, since the common ones are already all configured, but allows me to focus on the specific portion of the codebase that I need to work with.
I'd definitely separate these kind of things out into separate projects.
You should use Maven to handle the dependencies / build process automatically (both for your own internal shared libraries and third party dependencies). There won't be any issue having multiple applications reference the same shared libraries - you can even keep multiple versions around if you need to.
Couple of bonuses from this approach:
This forces you to think carefully about your API design for the shared projects which will be a good thing in the long run.
It will probably also give you about the right granularity for source code control - i.e. your developers can check out and work on specific applications or backend modules individually
If there is a section of a project that is likely to be used on more than one project it makes sense to pull that out. It will make it a little cleaner as well if you need to update the code in one of the commonly used projects.
If you keep them together you will have fewer obstacles developing, building and deploying your tools.
We had the opposite situation, having many separate projects. After merging them into one project tree we are much more productive and this is more important to us than whatever conventions happen to be trending.
We have a Java code base that has grown to be too big for a single monolithic JAR (more than 5000 classes). One of the tasks that we are investigating is how much effort would it be to break this single JAR into smaller components with controlled dependencies between them. However, it's somewhat hard to look at a big bag of code and be sure that you are finding the best points of separation without some analysis.
Are there good tools to inspect and visualize the interpackage dependencies? Given those, we would have a set of suggested cut points where we could begin separating code.
As an example, in the days before Netbeans and Eclipse (and at a different job), we used TogetherJ and TogetherEnterprise. Those had the ability to do a static package analysis and draw the UML diagram. That sort of behavior would be optimal but that feature alone is not sufficient to justify the cost.
I have recently discovered CodePro AnalytiX, formerly from Instantiations, now available for free from Google:
https://developers.google.com/java-dev-tools/codepro/doc/features/dependencies/dependencies
I used stan4j for the same purpose but unfortunately the community edition has a 500 classes limit. On the other side, it works as an eclipse extension.
Intellij IDEA has one:
(source: jetbrains.com)
JDepend is a free tool for analyzing package dependencies.
It identifies circular dependencies, which would impede breaking this monolith into smaller pieces.
We put this check for circular dependencies into our unit tests, to prevent them from the start.
There's a corresponding Eclipse plug-in.
You can send the output to GraphViz. However, the visualization becomes less understandable as the number of packages grows.
Now that CodePro AnalytiX [mentioned first by Fabian Steeg above] is free, it's worth another look. At least prior to purchase by Google, Instantiations reliably produced great software. I played with it some years back, and recall no complaints other than cost.
A good try would be to reverse your jar file into a class diagram. I have found this tutorial which explain how to reverse project composed by jar files into UML class diagram: http://www.ejb3.org/jar_file_reverse/jar_file_reverse.html
You will be able to reverse at package level at see package relation but also to see clases from one package having relation to other packages. Once the project has been reversed you can reorganize it as a model and give this documentation to the implementation team.
SonarJ is a good tool to do that, but it is expensive.
Another very good tool is XDepend, which is cheaper. For your purpose, I would recommand you this tool. The best choice in terms of quality/price I think.
With much less functionalities, you can use a Sonar (Free and OpenSource) analysis and its dependencies matrix.
Do the classes use packages in a normal fashion or are all the classes in the same package? If the first case is true, I'd consider writing a special-purpose tool to do the first cut.
This is exactly the kind of use case I build degraph for.
It allows you to define slices, i.e. sets of classes that belong together, and visualizes them as one collapsible node. You jars to be would be slices that you can tweak until they don't have any more cyclic dependencies, at which point they can become their own jar.
This makes it easy to spot dependencies between slices that you need to break. Since you can open the slice node and see all the contained classes it makes it also easy to identify possible refactorings (introducing interfaces, moving classes ..) to achieve you goal.
We have a developer who is in the habit of committing non-java files (xsd, dtd etc) in the java packages under the src/java folder in our repository. Admittedly, these are relevant files to that package, but I just hate to see non-java files in the src folder.
Is this is a common practice that I should get used to or are we doing something strange by maintaining these files like this?
The problem with putting non Java (or other languages) files that are closely tied to the code in a different place than the code is knowing where to find them. It is possible to standardize the locations then theoretically everyone will know where to go and what to do. But I find in practice that does not happen.
Imagine your app still being maintained 5 or 10 years down the road by a team of junior - intermediate developers that do not work at the company now and will never talk to anyone who works on your project now. Putting files closely linked to the source in the source package structure could make their lives easier.
I am a big proponent of eliminating as many ambiguities as possible within reason.
It's very common and even recommended as long as its justifiable. Generally it's justifiable when it's a static resource (DTD+XSLT for proprietary formats, premade scripts etc.) but it's not when the file is something that's likely to be updated by a third party like IP/geographic location database dump.
I think it gets easier if you think of 'src' as not specifically meaning 'source code'. Think of it as the source of resources that are things needed by your program at compile time and/or runtime.
Things that are a product of compile or build activities should not go here.
Admittedly, like most things, exceptions may apply :)
Update:
Personally, I like to break down src further with subdirectories for each resource type underneath it. Others may like that division at a higher level.
There is a lot of jar libraries that uses the same practice.
I think it is acceptable and comfortable.
In Eclipse it works well for us to have a src folder containing java classes, and a configuration folder (which is blessed as a source folder) containing property files etc. Then they all go in the output folder together and can be found in the classpath while still being in seperate folders inside Eclipse
One of the advantages of keeping all the auxiliary files next to the source is that version consistency is maintained between these 3rd party libraries and your source code. If you ever need to go back and debug a specific version, you can pull the entire set of source+config and have it all be the same version.
That being said I'd put them in a $project/config/ directory, or some such, rather than in $project/src/java itself. They're not source, nor java, really, so it's misleading having them in that directory.
When you really get down to it, though, this is an issue of personal style. There's no "Right" answer and you should be talking with those team members and understanding why they made this decision. Using this thread as evidence to support a unilateral decision probably won't go over well. ;)
Its pretty common, you can find it in really popular frameworks, e.g. xsd files for spring various schemas. Also people usually place hibernate mapping files in the same package as the model classes.
I think this is common as long as the files are necessary. The problems arise when people start committing files that are not needed with the source, such as design specs or random text files.
It is surely common, but incredibly lazy and sloppy. My skin crawls when I see it.
Using a tool such as Maven to build your products enables you to easily, and clearly separate code from resources.
Eclipse bundles can be similarly separated.