When working with Git repositories in Windows, it’s not rare to have to create .gitignore or even a .gitattributes file for your repo. Unfortunately, in Windows Explorer, creating files with a dot prefix isn’t so easy. If you try to rename a file to .gitignore for example in Windows Explorer, you will be met with this error message:
To get around this problem, you normally have to open up a command prompt window in your repo and manually rename an existing file using:
ren gitignore.txt .gitignore
There is however a much easier way. Instead of naming your newly created file .gitignore, add an extra period onto the end making .gitignore. and your file will be created without the errors:
As an aside those on Unix machines (or with Git Bash installed on Windows) can simply use this command and forget about the above:
There is a lot of Spring documentation online which makes use of the queryForInt() and queryForLong methods of the very handy JdbcTemplate class. However, using newer versions of the Spring framework, these methods have now become deprecated (apparently this has happened from version 3.2.2).
These are the two methods affected:
I’m not sure why the designers have to decided to deprecate these two methods, but the solution (or perhaps the workaround is simple):
The workaround makes use of the queryForObject method and we pass in the Integer class in order to coerce the general object into the type we desire. Similarly, for queryForLong, you can replace Integer.class with Long.class.
It’s very common for beginners in Java to use the many helpful methods of Scanner to obtain input from the user. They normally have some sort of task which involves asking the user for some String input, some numerical input and finally more String input - be this to do some processing with or just output back to the user in the simplest case. Most people will be happy using the nextLine() and nextInt() methods of Scanner to do so, however will then get confused when they don’t get the behaviour they expect. This is a great example of why you should know the specific behaviour of the library methods you call and not just assume that they will conform exactly to your needs by default.
As an example, say we get the task to ask the user for their name, storing it in a String variable, their age, storing it in an int variable, and finally their address, again storing it in a String variable. We may come up with this code to start off with:
Seems OK at a first glance, we prompt the user for input, use Scanner to retrieve it from the console and finally output what they entered. When we run this code however, it doesn’t function as expected:
We get the name and age input successfully, but what happened to the address? We get prompted for the address yet have no opportunity to enter anything - resulting in a blank String for this field.
Although it may not seem like it, Scanner is actually behaving here exactly how it was designed to do so. The Scanner class is a multi-purpose tool, capable of not only parsing character input from the console, but also from other files and streams. In order to do so, it provides two methods: next() and nextLine(). The next() method takes a token from the current input stream up to the next delimiter (which by default is whitespace although this can be changed). It then returns this parsed token, but importantly leaves the delimiter in the stream. The nextLine() method on the other hand accepts a whole line up to and including the newline character. This time however, the delimiter gets consumed as well. Most of the other parsing methods in Scanner base themselves around these two base models.
Examples of those other parsing methods include convenient methods to accept input and convert it into another type (a call to nextInt() for example). Scanner does this by calling the next() method and then attempting to parse the output into the resulting type. This seems quite reasonable, but recall that we have called the next() method here and not nextLine(). This is where the problems occurs in our example above. The next() method leaves the delimiter in the stream, which means that when the user types a number, say “20” for their age and hits return, the Scanner gets a stream consisting of “20\n”. When the nextInt() call happens, the “20” is removed, and becomes a 20, and now the stream is “\n”. Now we call nextLine() again to retrieve the address. The Scanner does what it’s meant to and takes the the “\n”, discards the newline character (“\n”) and returns the remaining String - which in this case is “”. Thus we get the undesired behaviour.
The solution? Simply call nextLine() after we call nextInt() to consume the remaining newline character so that we get the chance to enter the address. Ideally however, you shouldn’t litter your input code with a load of new nextLine() calls to get the desired behaviour. Therefore, its probably best to implement your own utility class to take input in the manner you expect - leaving the Scanner in the correct state for further use afterwards.
This leaves the question as to why they decided to implement it in this way. As I said before Scanner is a very multi-purpose tool that should be able to accept a wide variety of input formats - not just one token on each line. A major use case of Scanner is to for example parse all the ints on one line, separated by whitespace, in order to populate some kind of Collection. If the nextLine() methods was used in nextInt() rather than next() we wouldn’t be able to do this and Scanner would be restrained in its use. This of course wouldn’t be a useful design decision and so we have to do this small bit of extra work to make it conform to our requirements.
In Python the typical way to iterate over a loop is to use the conventional foreach loop, as lists expose iterators:
In a lot of cases this is all that’s needed, however in other circumstances we may need access to the index that each element is at inside the list - most of the time in order to perform some kind of check on the next or previous values in the list. The conventional for loop above of course simply gives us the values inside the list, not the indexes. We could set up a counter variable which increments each time around the loop, yet this seems clumsy. We are increasing the scope of a variable that should ideally be kept local to the loop.
Another popular solution is to use the range function, which returns an iterator of values from zero to the number we specify as a parameter. By creating a list of numbers from zero to the size of the list, we can then use each element as an index in order to extract each value:
Although this gets us our desired output (in this simple example anyway), it again seems quite a clunky way to perform such as simple task in Python. We have to refer to each value as values[i], or otherwise set up a new local variable. Luckily however, as ever, this is a much neater way of doing this in Python.
One of the built-in functions that Python provides is the enumerate function. This handy function gives us an iterator that returns a tuple containing a count (which by default starts from zero) and the values obtained from iterating over the sequence. By simply running through the tuples returned from the iterator provided by this function, we get access to both the indexes and the corresponding values:
As you can see this is much neater and more efficient than the other solutions. There is no need for extra variables - everything is provided to us in the loop declaration.
It is assumed that before starting this tutorial, you have read and understand the first part of this series which includes an overview of Maven and creating a simple Maven project.
What are dependencies?
In this context, dependencies are any modules of code that your application requires in order to function properly. In this case, this mainly consists of large public libraries that are often needed for Java programs. Such examples include logging frameworks such as Log4J, unit testing frameworks such as JUnit, or a whole multitude of other frameworks and libraries such as Spring for dependency injection, Hibernate for object relational mapping and Struts for MVC web applications. In this example we will be using Guava which is a commonly used collections library from Google.
The dependency capabilities of Maven don’t just end with managing dependencies for a single a project however. Maven really starts to excel when you start getting into dealing with multi-module projects and applications that consist of maybe tens or even hundreds of modules - each of which may depend on a selection of the others.
Why do we need Maven for this?
At this point you may be asking why we even need Maven to handle this at all. You may be used to adding libraries to your project by visiting their website and downloading the latest release. You then copy the relevant .jar files into your project and modify the classpath so that the compiler can see and use them. This method however does present quite a few potential problems that Maven tries to fix.
Perhaps the biggest potential problem is handling the dependencies of those libraries themselves (the dependencies of the dependencies if you will). You’ve probably been there at some point. You download a library and find out that it itself needs a few other libraries or frameworks in order to operate. You then have to try and locate those files just to find that each of those has a whole set of other dependencies. After a while you end up with quite a headache on your hands. This is perhaps not readily apparent on smaller libraries, but when you start dealing with the big frameworks (think Spring and Hibernate etc), this can start to become a a real problem - and a big waste of time.
Another common problem with libraries is making sure you are using the correct version. Maybe one library needs a specific version of another in order to function properly. You then start having to delve deeper into the relevant websites in order to try and track down the right version. You then have to do it all over again if that library depends on others. Another example is when migrating to a new versions. Particularly with new JDK releases, you end up at some point updating to new supporting versions of the libraries that you’re using. You then end up going through the same problem as described above.
There are a whole load of other big problems you can run into with larger applications, but these examples alone are hopefully reason enough to start doing something about it - using Maven.
Maven tries to solve these problems by managing a repository that contains a whole load of libraries and frameworks that you could use in your application (there are also local repositories often for use with multi-module projects). When we want to start using a certain library, we can simply tell Maven what it is and what version we want to use. As long as the dependency is in the repository somewhere, Maven will run off, collect all the relevant files for that specific version and add them to your project for you - no manual work needed at all. In addition Maven also stores all the dependencies that library needs to operate. When you tell Maven about the new library, it will not only download the files for that library, but it will also collect each and every dependency - all automatically. When you want to update or change versions, simply tell Maven about it and everything will be sorted for you.
Collecting dependency information -
In order to add a new dependency to our project with Maven, we first need to collect the relevant information about that dependency in order for Maven to be able to correctly identify it in the repository. You can either memorise this information, or preferably use one of the many website that allow you to search for a library in the Maven repository. In this case we will be using the popular site http://mvnrepository.com/
In this example we will be adding the Guava collections library to our project. In order to get the information simply search for 'guava' in the search-bar. A list of search results will appear containing all the relevant artifacts in the repository. In this case (and in most cases), the top result is what we are looking for. When you click on the link, you will be presented with a page allowing you to select which version of the library to use. In this case we will be using the most recent release - 17.0 as of writing. By clicking on the version you will be presented with information about that particular version - including any of its dependencies and what other artifacts depend on it. What we are interested in however is the small snippet of XML near the top that defines the dependency to Maven. Snippets for various other dependency management systems are also provided by the site.
Adding the dependency to the project -
Here is the XML snippet we obtained from the repository explorer:
As you can see it’s really quite simple. It merely defines the groupId and artifactId of that particular dependency - much like we did when we created our project in the first tutorial. The groupId can be thought of as a kind of container which can potentially hold many projects. The artifactId defines the specific artifact in the container that we want to access.
In order to tell Maven about this new dependency, we simply add it to the existing pom.xml for your project. The dependency tag goes inside a container dependencies tag - meaning that we can have as many dependencies as we like in our project. The edited pom.xml looks like this:
As you may have seen, there is already a dependency inside the pom.xml file - JUnit. This has been added automatically by the archetype we chose when the project was created.
And that’s it! Maven will now know about that dependency when we compile our project, whereby the library will be downloaded and added to the classpath automatically. But before we compile, we first need some code to use the library in order to make sure everything has worked properly.
In the main App.java file, that currently has the Hello World example from the last tutorial, add the following code in order to use the Guava library:
In this example we make use of the Joiner class to join together an array of words with a space delimiter.