Featured FREE Whitepapers

What's New Here?


Guava Functions & Java 8 Lambdas

I recently read Brian Goetz’s The State of the Lambda and after reading that article I wanted to try using Java 8 lambda expressions. In his article, Brian goes on to describe interfaces that have one method as “functional” interfaces. Functional interfaces are almost always used as anonymous classes, with the ActionListener being the canonical example. These “functional” interfaces are the initial target for lambda expressions, with the main goal being removing much of the boilerplate or ceremony around their usage. As I have been writing a series on the Guava library, the Function interface immediately came to mind as a prime candiate for trying lambda expressions.My goal is simple, take the unit test from my Guava Futures blog (it makes heavy use of the Function interface) and convert it to use lambda expressions. While I will describe the structure of the lamba expression as it pertains to the example presented, this post is not a tutorial on Java 8 lambda expressions. Rather it’s documenting my first attempts at using lambda expressions in Java. Lambda Expressions The first example is a test for the Futures.chain method, which takes a Function as one of it’s arguments: Function<List<String>, ListenableFuture<List<Person>>> queryFunction = new Function<List<String>, ListenableFuture<List<Person>>>() { @Override public ListenableFuture<List<Person>> apply(final List<String> ids) { return dbService.getPersonsByIdAsync(ids); } };ListenableFuture<List<String>> indexSearch = luceneSearcher.searchAsync('firstName:martin'); ListenableFuture<List<Person>> results = Futures.chain(indexSearch,queryFunction,executorService); Using lamba expressions it would now look like: Function<List<String>, ListenableFuture<List<Person>>> queryFunction = ids ->(dbService.getPersonsByIdAsync(ids));ListenableFuture<List<String>> indexSearch = luceneSearcher.searchAsync('firstName:martin'); ListenableFuture<List<Person>>results = Futures.chain(indexSearch, queryFunction,executorService); Keep in mind that from the code examples above the two highlighted sections are equivalent. Let’s take a look at line 2 and explain how this matches up with lines 1-7 from the first code exampleids is the input to the apply method and corresponds to the final List<String> ids parameter on line 4 in the first code example. The types of the lamba expression are being inferred from the context in which it is being used, so we don’t need to repeat them for the ids parameter. Then there is the arrow (->) token which is part of the general syntax of Java 8 lambda expressions in their current form Then we have the body of the lambda (dbService.getPersonsByIdAsync(ids)) which is a method call that returns a ListenableFuture that in turn yields a List of Person objects. Note that we did not have to put a return statement, as this is a single expression and is evaluated and returned.The next example is a utility method from the test that returned ListenableFutures by passing anonymous Callable instances into an ExecutorService: private ListenableFuture<List<Person>> getPersonsByFirstNameFuture(final String firstName, final boolean error) { return executorService.submit(new Callable<List<Person>>() { @Override public List<Person> call() throws Exception { startSignal.await(); if (error) { throw new RuntimeException('Ooops!'); } List<String> ids = luceneSearcher.search('firstName:' + firstName); return dbService.getPersonsById(ids); } }); } And here is the equivalent using a lambda expression: private ListenableFuture<List<Person>> getPersonsByFirstNameFuture(final String firstName, final boolean error) { return executorService.submit(() -> {startSignal.await(); if (error) { throw new RuntimeException('Ooops!'); } List<String> ids = luceneSearcher.search('firstName:' + firstName); return dbService.getPersonsById(ids); }); } In this example there are no input arguments so the expression starts with empty parentheses () on line 2. There is the -> token, but in this example, the body contains multiple statements surrounded by { …}. Since there are multiple statements an explicit return statement is needed on line 7. Environment to Run Java 8 My current laptop is a MacBook Pro, so I needed to set up an environment to run Java 8 with lambda support. Here are the steps I took:Installed LinuxMint 12 on VirtualBox. Created a directory and shared it with the LinuxMint guest Installed the developer preview of java 8. To get the source and test source from the existing maven project I ran mvn jar:jar jar:test-jar and put the resulting jar files in the shared directory Placed all the dependencies in the shared directory (guava,lucene,h2 and junit) Re-wrote the unit test to use lambdas and ran the new test from the command lineConclusion Although it will be some time before Java 8 with lambda support is released, what is available in the developer preview looks promising.Thanks for your time and as always comments and suggestions are welcomed ResourcesState of the Lambda, Part 4 Java 8 developer preview Source code for this post Guava Project Home Source Code for Guava blog series  Reference: Guava Functions & Java 8 Lambdas from our JCG partner Bill Bejeck at the Random Thoughts On Coding blog. ...

Facade Design Pattern – Design standpoint

In our previous article we have described about the Adapter Design Pattern. In today’s article we are going to show about another such Gang of Four Structural patterns. As the name suggests structural pattern is used to form a larger object structure from many different objects. Façade pattern is one such pattern which provides a simplified interface to a set of interfaces within a system and thus it hides the complexities of the subsystem from the client. When to use Façade Pattern? Layering: Facade pattern can be used in JEE applications for creating a layer to abstract and unify the related interfaces in the application. Use of a facade will define an entry point to each subsystem level and thus make them communicate only through their facades; this can simplify the dependencies between them. Façade makes the API and libraries easier to use which is good for maintenance and readability. It can also collate and abstract various poorly designed APIs with a single simplified API. It also reduces dependencies of the external code on the inner working of the libraries and thus providing flexibility.In the above structure for Façade pattern the Façade class insulates the subsystem from the client. The client only interacts with the Façade class without knowing about the subsystem classes. Example: Let’s take an example of Order processing online website. The client has placed an order without having knowledge of how internal classes are functioning. Once the order is placed the façade class layer calls the methods of the subsystems like Inventory for inventory check and Payment for processing of the payment. After processing it returns the control to the client class with the confirmation about the order being processed. Sequence Diagram:Code Example: Inventory.java – public class Inventory { public String checkInventory(String OrderId) { return 'Inventory checked'; } } Payment.java public class Payment { public String deductPayment(String orderID) { return 'Payment deducted successfully';} } OrderFacade.java public class OrderFacade { private Payment pymt = new Payment(); private Inventory inventry = new Inventory();public void placeOrder(String orderId) { String step1 = inventry.checkInventory(orderId); String step2 = pymt.deductPayment(orderId); System.out .println('Following steps completed:' + step1 + ' & ' + step2); } } Client.java public class Client { public static void main(String args[]){ OrderFacade orderFacade = new OrderFacade(); orderFacade.placeOrder('OR123456'); System.out.println('Order processing completed'); } }   Benefits:We can use the façade pattern to collate all the complex method calls and related code blocks and channelizes it through one single Façade class. In this way with respect to client there is only one single call. Even if we make changes to the subsystem packages / class and their logic there is no impact to the client call. In short this increases loose coupling. It makes easier to use and maintain creating a more structured environment and reduces dependencies between libraries or other packages.  Drawbacks/Consequences:One of the drawback is that the subsystem methods are connected to the Façade layer. If the structure of the subsystem changes then it will require subsequent change to the Façade layer and client methods.  Interesting points: Façade pattern might be confused with mediator pattern. Mediator also abstracts the functionality of the subsystem in similar manner to façade. However there is a subtle difference between both these patterns. In case of Mediator pattern the subsystem is aware of the mediator, however in case of Façade the subsystem does not know anything about the façade. It’s a one way communication from Façade to subsystem. Façade used in Java APIjavax.servlet.http.HttpSession javax.servlet.http.HttpServletRequest javax.servlet.http.HttpServletResponse javax.faces.context.ExternalContext  Reference: Façade Design Pattern – Design standpoint from our JCG partner Mainak Goswami at the Idiotechie blog. ...

Off-loading your test execution using Hudson

One of the annoyances if you have a load of tests for a particular project is that running them can tie up your machine for a while. There are also sometimes consistency issues when running on different machines with different window managers and operating system versions. One thing we do is for every main hudson job we create a copy just to run the tests for a particular developer. It solves the ‘it runs on my machine’ dilemma and frees up the developer to get on with other work. In our part of the organization running the tests on another machine is a mandatory step before merging to main. This example uses subversion; but it most likely work equally well with any other source control system with a similar interface. It also assumes that all the developers are working on branches, you are doing this right?. First of all you take a copy of you original job, in my case I am running test for the abbot project so I am starting with ‘abbot_SF’, and create a copy of this job with a suitable postfix. In our case the job is called ‘abbot_SF_TestTrans’. You need to first disable any normal build triggers so this job only gets used when there is a manual action. We keep the results separate as it makes the normal build results much easier to interpret. So to this new job add a new Parameter ‘BRANCH’ of type string and update the repository URL to contain this parameter, so in my case https://abbot.svn.sourceforge.net/svnroot/abbot/abbot/branches/$BRANCH. You will also notice that I have the used the description setting plugin to capture the branch name automatically. (You could also just put the $BRANCH parameter in the description field and leave the RegEx blank). After you have finished you have something like this, ignore the red ink as that appears to be a local configuration issue.Now if you click build on the job you get a nice interface where you can ask Hudson to build a particular branch, leaving the developer to get on with the next job while the build machine does it’s business.Speaking of that, it looks like I have some bugs to fix… You might also want to tick the ‘Execute Concurrent Builds if necessary’ flag so that if you have more than one developer you can make proper use of your farm. It turns out this can be quite simple, you just need to make use of a job parameter that takes a File as it’s input, this is then written to the specified location in the workspace. In my example I have the following two parameters, the Title allow me to name the job and this property is picked up later by the job Description plugin.Once you know where the patch is located you can just apply the patch before you perform the required build steps, here is an example using SVN so we use the unix patch command, git users can use the git command instead for this.And there you are, you can test a user submitted patch for testing without tying up your development machine. You can also run the tests more than once to check for any intermittent tests which can be very valuable in concurrent environments. I forgot to mention a very important plugin that is essential if you want to convince your developer to preflight there work. The problem is that is the slave allotment/smallholder/farm is busy running other jobs then they are forced to wait before merging. The easy solution to this problem is the priority sorter plugin. This allows you to specify that some jobs are more or less important then others. The default priority is 100, so seeing your preflight job to 1000 should see it jump to the front of the queue.It is interesting how the length of tests affects my commuting behaviour, now that is take around an hour to run the long tests just for our components. It makes sense to start a work at home, kick of a job and you should have you nice shiny test results by the time we get into work. One day I might even get a blue ball if I am so very lucky with our dependencies. :-)   Reference: Off-loading your test execution using Hudson, Off-loading test execution using Hudson part 2, Off-loading test execution using Hudson part 3, skipping the queue from our JCG partner Gerard Davison at the Gerard Davison’s blog blog. ...

The 10 rules of a Zen programmer

On a rainy morning I found myself sitting on the desk thinking about efficient working. Before I started as a freelancer I had some days were I worked lots but could look only back on a worse outcome. I started with Zen practice back in 2006. What clearly came to my mind before a good while was: the old Zenmasters already knew before hundreds of years, how today programmers should work. Even when I don’t like these “be a better programmer” posts, I want to outline some of my thoughts from that morning. It shall serve me as a reminder, but if you have some ideas about it, feel free to comment. 1. Focus If you have decided to work on a task, do it as well as you can. Don’t start multiple things at the same time. Do only one thing at one time. You’ll not become quicker, just you work multi-threaded. If you work multi-threaded you’ll become exhausted, make more errors and lose time to jump from one task to another. This is not only about programming, this is a general tip. Kodo Sawaki says: if you need to sleep, sleep. Don’t plan your software when you try to sleep. Just sleep. If you code, code. Don’t dream away – code. If you are so tired that you cannot program, sleep. Even known multitaskers like Stephan Uhrenbacher meanwhile have decided to work singlethreaded. I have made a similar experience to Stephan and finally I wrote Time & Bill, a time tracking tool. Goal was to track my time so easily that I even do it for small tasks like a phone call. Now I can create a few stopwatches at the beginning of the day and track my time with only one click. The outcome was a disaster: sometimes I just worked a few minutes on a task until I moved on to the next one. Now I am better. Similar to the Pomodoro technique I plan a few time slots and concentrate on them. No chatting, no sleeping, no checking out of a new great game on the Appstore.  2. Keep your mind clean Before you work on your software, you need to clean up your memory. Throw away everything in your mind for the time being. If you have trouble with something, don’t let it influence you. It is mostly the case that trouble will go away. If the trouble is so heavy that you can’t let it go, don’t work. Try to clear things up. But when you start working, let the outer world shape away. Something exciting on the mailing list? Leave it there. You can follow the exciting stuff again – later. Shutdown what fills your mind with shit: close Twitter, Facebook, your E-Mails. You should even mute the ringing of you mobile and leave it in your pocket. You can say it is similar to item #1, focus. But there is one more restriction: don’t use that tools before work or at lunch. They connect you with the outer world and probably bring up some new trouble or things which require you attention. Think like this: at most times your mind is pretty clean when you wake up at the morning. If it is not, some sports helps (I do long distance running). If you feel clean and refreshed, go to work and work as well as you can. When you leave your work then you can fill up your mind with clutter. You’ll see it is not so much fun if you have a full working day behind you. Twitter and Co are consuming much of your energy. Do not think: it is just a minute. It is not. You know it already. 3. Beginners mind. Remember the days were you were a beginner. Or memorize, if you still are one. You have never learned enough. Think of yourself as you were a beginner, every day. Always try to see technologies from a beginners mind. You can accept corrections to your software better and leave the standard path if you need it more easily. There are some good ideas even from people who don’t have your experience. Was there ever a software build twice, the same way? Even if you copy software it is somehow different. 4. No Ego. Some programmers have a huge problem: their own ego. But there is no time for developing an ego. There is no time for being a rock star. Who is it who decides about your quality as programmer? You? No. The others? Probably. But can you really compare an Apple with a Banana? No. You are an individual. You cannot compare your whole self with another human being. You can only compare a few facets. A facet is nothing what you can be proud of. You are good at Java? Cool. The other guy is not as good as you, but better with bowling. Is Java more important than bowling? It depends on the situation. Probably you earn more money with Java, but the other guy might have more fun in life because of his bowling friends. Can you really be proud because you are a geek? Programmers with ego don’t learn. Learn from everybody, from the experienced and from the noobs at the same time. Kodo Sawaki once said: you are not important. Think about it. 5. There is no career goal. If you want to gain something and don’t care about your life “now”, you have already lost the game. Just act as well as you can, without looking at the goal you might reach after a long time. Working for 20 years to become a partner? Why aren’t you working as hard as possible just because it is fun? Hard working can be fun. A day without work is a day without food is a Zen saying. There is no need to start happiness after 20 years. You can be happy right now, even when you are not a Partner or don’t drive a Porsche. Things change too easily. You can get sick. You can get fired. You can burn out (if you follow all these items I guess likeliness is low). Until these bad things happen, just work as well as you can and have fun with doing it. No reason to look at the gains of the colleges. No reason to think about the cool new position which you didn’t get. After all, you will reach something. You’ll end up with nice memories, maybe a good position – and 20 excellent years. Every day is a good day. If you ever come to the point were you think that working at your company is no fun at all you must leave immediately. NEVER stay at a company which does take away the happiness in your live. Of course, this is only possible in the rich countries, were people have the choice to go away. But if you are living in such an good environment, do it. Go away without regret. You have no time to waste, you are probably dead tomorrow. When you have no career goal going away is easy.  6. Shut up. If you don’t have anything to say, don’t waste the time of your colleagues. This doesn’t make you look wimpy. Everyday you work you need to try not getting on someones else nerves. Imagine if everybody would try this – what a great working place would that be? Sometimes it is not possible. Try hard, you will like it. If you don’t develop an ego it is pretty easy to shut up and care on the things you have something to tell. Don mix up your ego with your “experience” and always remember: you are a beginner. If somebody has a good idea, support the idea. 7. Mindfulness. Care. Awareness. Yes you are working. But at the same time you are living and breathing. Even when you have some hard times at work you need to listen to the signs of your body. You need to learn about the things which are good for you. This includes everything, including basic things like food. You need to care for yourself and for everything in your environment – because after all, the water you drink is the water which runs in the river. Because you are living only for yourself. You live alone and you’ll die alone. World goes on, even without you. Avoid working situations you don’t like. Avoid working for free if it means you will have no fun and keeps you away from your bed. Let go what doesn’t make you happy. Working for free sounds is just theory? Consider the people doing Open Source in their prime time. If you have subscribed to some projects mailing list you probably know what heat there is (sometimes). If you don’t have fun with that – stop doing it. I know a bunch of people who work in an Open Source environment they don’t like. Again with Time & Bill I have tracked the time I spend in 0pen Source projects and was surprised how much time I lose there – esp. on projects I didn’t like so much. Having this in mind, some people think they are only happy when they have prime time and can spend the evening with an xbox and some beer. While this is a good idea from time to time, it is not necessary that the whole time in your life is “fun”. If you can avoid situations you don’t like, avoid them (like I said above). But sometimes there is need to something really shitty. Like for example manually copy/pasting stuff from your managers Excel sheet into phpmyadmin. This can take you days, and it is really boring. It is no fun, but sometimes you need to do such stuff. You cannot always quit your job when you got a boring task. Zen Monks are not to shy with their work too. They get up at 4am (sometimes earlier, sometimes later, depends on the convent) and start meditation and work (they even consider work meditation practice). They have stuff to do like cleaning the toilets. Or working in the garden. Or as a Tenzo, they cook. They do it with all the care they can get. Whatever they do, they do it without suffering and they are (or should be) happy, because every second, even the second where they are cleaning toilets, is a second of their life. That being said: stop crying, if you need to copy/paste excel. Just do it. Don’t waste your energy with such things, they will pass. Become the best excel copy/paster out there instead. If you suffer a heart attack, people will probably say: “uh yes, he really worked too much, he even worked for me for free at night”. Nobody can guide you to the other world. This last step is taken by us alone. You cannot exchange anything in this world. Not even a fart. So it is up to you to take care, in every second. If you die, you die. But when you live you live. There is no time to waste. “Care” is a huge word in zen buddhism (and I think in every form of buddhism). I cannot express everything which needs to be said. it is difficult to understand the different meanings of “care”. Probably you are better with the word “awareness”. You must be aware of what you do, in every second of your life. You must be mindful in your life. Otherwise you waste it. But, of course, it is up to you to do so, if you like. 8. There is no Boss Yes, there is somebody who pays you. There is somebody who tells you what needs to be done. And he can fire you. But this is no reason to give up your own life or to become sick of your work. Finally your Boss has no control about you. It can even be doubted that you have control about you – but don’t lets go down this path. Back to your Boss: he can make your life worse if you allow him to do so. But there is a way out. Say “No” if you need to do something which makes you sick or is against your ethics. What will happen? In worst case he will fire you. So what? If you live in western nations and if you are a coder (which is very likely when you read this) you’ll get another job.I don’t mean to say “No” to tasks like copying CSV Data to HTML. I am speaking of 80 hours weeks and you feel your body breaks. Or if you feel that your kids could need some attention too. Or if you are forced to fire people just because your Boss doesn’t like them. Or if you are a consultant and get the job to develop software for nuclear plants (some might say it is perfectly fine to work for nuclear power companies – it is against my ethics and serves as an example) or for tanks. You can say “No”. 9. Do something else A programmer is more than a programmer. You should do something which has nothing to do with computers. In your primetime, go sailing, fishing, diving. Do meditation, martial arts or play Shakuhachi. Whatever you do, do it with all the power you have (left). Like you do at your worktime. Do it seriously. A hobby is not just a hobby, it’s expression of who you are. Don let anybody fool you, when he says hobbies are not important. Nowadays we can effort having hobbies. I have recorded several CDs and wrote fantasy books (the latter one unpublished, I must practice more). These things have made me to the person I am now, and finally they have led me to Zen and this blog post. These days I practice Zen Shakuhachi. It is a very important aspect to my daily life. 10. There is nothing special. A flower is beauty. But it’s just a beauty flower – nothing more. There is nothing special around it. You are a human who can program. Maybe you are good. There is nothing special around you. You are of the same kind as I am or all the others on this planet. You need to go in the loo and you need to eat. Of course you need to sleep. After (hopefully) a long time you will die and everything you have created will be lost. Even pyramids get lost, after a long time. Do you know the names of the people who build up a pyramid? And if you do, is it important that you know? It’s not. Pyramids are there, or not. Nothing special. Same goes to your software. The bank is earning money with your software. After you leave, nobody remembers you. There is nothing wrong around it. It is the flow of time. Nothing you should be worried about it. If you are living after the first 9 rules, you’ll see that this last project was a good and funny project. Now it’s simply time to go on and concentrate on something else. If your comapany closes because of financial problems, no problem. Live will go on. There is no real need for a xbox, a car or something else. Most people on this planet live in deepest poorness. They don’t care on a xbox, because they would be glad to get some food or even water. So… why exactly are you special? Because you had the luck to be born in the western territory? Because you can code? No, there is nothing special around it. You can let go you ego and live freely. Enjoy the colors and the smell of flowers around. Don’t be too sad when the winter comes and don’t be too happy when spring comes back. It is just a flow. Keep it in mind when somebody denies your application. Because the company is not so special that you need to be worried about the job. Disclaimer I am not a Zen monk. I am just practicing and learning. Please ask your local Zen monk if you feel there is something you need to understand deeper. Of course I can try to answer on this blog, but well, I am just a beginner. Anyway I am glad about your comment and if you would send a tweet with this pages url if you liked this post. Thanks for reading! You want a book on Zen Programming? Click here.   Reference: The 10 rules of a Zen programmer from our JCG partner Christian Grobmeier at the PHP und Java Entwickler blog. ...

Introduction To Scrum

This post is an introduction to Scrum, one of the Agile methods to drive software application implementation. Reading this post is a prerequisite to this post. ConceptsScrum projects deliver software application features iteratively. Each iteration is called a sprint. Scrum projects have 4 stages:Planning – Definition of the vision, budget, and expectations. The first version of the product backlog should containing enough implementation items for the first sprint. Staging – This is the first iteration where the requirements and product backlog created in the planning are refined. Development – It is the set of sprints required to implement the project fully. It ends when the product backlog is empty. Release – The final product is deployed, training is performed, documentation is finalized, etc… The release backlog can be used as the product backlog for the next release of the product.There are 4 main roles in scrum projects: team member, product owner, stakeholders and scrum master:A product owner is a customer representative acting as a single point of contact on the customer side. A stakeholder is anyone having a vested interest in the project, providing information about requirements and participating to the decision process of features to be implemented. A scrum master is a facilitator and single point of contact on the development team side. It is a support function, not a ‘controlling chief’ role. It is a mix between a team leader and a software engineering role, which does not include people management or profit & lost responsibilities. A team member is a software engineer.Scrum of scrum can be implemented when multiple scrum teams are working on the same large project. Scrum master and product representatives get together. The product backlog is a list of features, use cases, enhancement, defect, etc… to be implemented in the project’s forthcoming sprints. The release backlog is the list of features, uses cases, enhancement, defect, etc… which are postponed to the next version of the project (not next sprint).  PracticeSpring teams typically do not have more than 7 members. A sprint duration is 30 days. Scrum projects are client-driven. They select the features to be implemented. Each sprint begins with two meetings:The stakeholder meeting, with the scrum master and customer representative to re-prioritize the product backlog and update the release backlog. The product owner and team meeting where tasks are created from the product backlog.Each task must require between 4 and 16 hours of work. Bigger tasks must be subdivided into smaller tasks. The scrum master and product owner check whether there are enough resources to support the efforts required to achieve the sprint and adjust the workload accordingly. Team member pick their tasks and work on their implementations. Each spring finishes with a presentation of implemented features to the stakeholders. Every day, a stand-up meeting (15-20 mins) with the team members and eventually the product owner is organized in front of a white board. The following is discussed:Which tasks have been achieved since the last meeting? Are there new tasks? New requirements? What is blocking? Any impediments?If decisions have to be taken, the Scrum Master should take them quickly, within an hour if possible The Scrum Master should deal quickly with any impediments and communication issues Scrum teams should preferably operate from the same room  Conclusion As for all Agile methods, the Scrum approach is best suited for new projects created from scratch. Over time, when successive application releases are implemented, the project can slowly transform into a continuous integration or even maintenance project, where less stakeholders input or daily supervision is required. The cogs are well oiled and operate naturally.   Reference: Introduction To Scrum from our JCG partner Jerome Versrynge at the Technical Notes blog. ...

Introduction To Agile Principles

This post is a reminder about Agile principles. It is also an introduction for those who want to learn about it. The Agile principles were initially proposed in 2001 in the Manifesto for Agile Software Development which defines 4 values and 12 principles. Several project implementations methods were already available then, but many found these inflexible, cumbersome or unadapted. Some tried to apply them with too much orthodoxy and rigidity, went far beyond planned budgets and did not manage to produce operational software. Those who did deliver a product often saw end users refusing to use it. The end result was far from their real needs and expectations. Agile is a reaction to the think & plan first → design everything → implement everything → test everything → deliver everything mentality (waterfall). Secluding each step of the software process development proved to be a failure in many cases, especially when developing new software from scratch. By focusing on iterative development, (i.e., successive deliveries of software parts and functionalities with frequent customer feedback), Agile is aiming at being rapid and flexible in response to changes. Project are kept small to maximize success rates. Iterative methods were existing long before Agile. Agile is extending the concept and principles. Agile Manifesto ValuesIndividuals & Interactions over processes and tools – When reading maps, some people tend to try to confirm that they are indeed where they think they are on the map, rather than taking indications on the ground and use these to find their position on the map. The map should only be a support to human interactions, not the other way round. Working software over comprehensive documentation – Excessive planning and design used to plague many projects. The process was too intellectualized and disconnected from the final product and user needs. Customer collaboration over contract negotiation – Customers know best about their needs (what the product should do), not the designer and software engineer. By getting the customer engaged, one also gets their approval on the delivered product. Responding to change over following a plan – Setting rigid project milestones, with a predefined set of tasks, fails on many occasions. The customer rarely has a fully detailed picture of the product he wants or needs. Design and gathering of needs is an ongoing process.  Agile Manifesto PrinciplesOur highest priority is to satisfy the customer through early and continuous delivery of valuable software – Customer likes to see where the money is going. The more they see something substantial, the more they trust the process, and the more they get engaged. Welcome changing requirements, even late in development. Agile processes harness change for the customer’s competitive advantage – Devil is in the details, and sometimes, these lie under several layers of analysis and design. For new software, some real practical requirements are only discovered late in the process. These are essential and must be accommodated for. Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale – This practice guarantees that expectations are met and that the project does not go in the wrong direction. Frequent customer feedback is the lighthouse. Business people and developers must work together daily throughout the project – Developers usually have little managerial decision power, yet their daily work depends on managerial decisions which must be made for the project to flow. Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done – This is about empowerment and people management. It is not specific to Agile only. The most efficient and effective method of conveying information to and within a development team is face-to-face conversation – Self-explanatory. Working software is the primary measure of progress – Again, this principle helps avoiding never-ending projects. Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely – This is achieved with face-to-face communication and frequent deliveries of product features, plus frequent customer feedback. Continuous attention to technical excellence and good design enhances agility – This is a tautology. Simplicity–the art of maximizing the amount of work not done–is essential – It is complicated to keep things simple, to resist the temptation of including too many technologies or frameworks. Overkill is common in software implementation. The purpose is to satisfy requirements, not optimizing the last lemon drop. The investment is often not worth the return. The best architectures, requirements, and designs emerge from self-organizing teams – Again, this is about resisting implementing large strategic plans or theories, and trust the process and people. At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly – This nothing but debriefing in action.  Implications By following Agile principles and values:Implementation teams practice iterative development, by collecting customer needs, implementing them progressively, with frequent releases (a.k.a. incremental delivery) This implies some kind of evolution of user requirements over time Programming and testing starts early, alongside analysis At each iteration, the client chooses the next features to implement Each team member takes ownership of the tasks they will achieved and decide how to implement them until the next iteration The riskier and most complex requirements are dealt with first Each iteration has a fixed duration (1-4 weeks), which cannot be changed Once features have been selected for an iteration, no changes are allowed Complete features before moving to the next one All this helps reducing the cone of uncertainty of requirements (Mc Connell)  Key To SuccessIdentify what the customer values Identify stakeholders and make sure they have a vested interest in the project’s success Make sure there is a customer representative (single point of contact) Favor consensus in team decisions, whenever possible Break large tasks into smaller tasks Focus on delivery, not process compliance Master technical details and skills required to succeed Facilitate communication channel between all involved parties Have people put their ego in their pocket Practice open information as much as possible and necessary Use feedback, both from customer and development team to improve Avoid long term planning  Conclusion Agile methods are not silver bullets for all situations. They are best when developing a new software application from scratch or for continuous integration projects. However, waterfall remains more appropriate when upgrading an ERP or when converting an existing application from one technology to another. The most famous Agile methods applying Agile principles and values are Scrum and Extreme Programming (XP). There is also Adapative Software Development, Crystal methods, Dynamic Solutions Delivery Model (DSDM), Feature-Driven Developpment (FDD), Lean Development and Pragmatic Programming.   Reference: Introduction To Agile Principles from our JCG partner Jerome Versrynge at the Technical Notes blog. ...

Google Guava Cache

This Post is a continuation of my series on Google Guava, this time covering Guava Cache. Guava Cache offers more flexibility and power than either a HashMap or ConcurrentHashMap, but is not as heavy as using EHCache or Memcached (or robust for that matter, as Guava Cache operates solely in memory). The Cache interface has methods you would expect to see like ‘get’, and ‘invalidate’. A method you won’t find is ‘put’, because Guava Cache is ‘self-populating’, values that aren’t present when requested are fetched or calculated, then stored. This means a ‘get’ call will never return null. In all fairness, the previous statement is not %100 accurate. There is another method ‘asMap’ that exposes the entries in the cache as a thread safe map. Using ‘asMap’ will result in not having any of the self loading operations performed, so calls to ‘get’ will return null if the value is not present (What fun is that?). Although this is a post about Guava Cache, I am going to spend the bulk of the time talking about CacheLoader and CacheBuilder. CacheLoader specifies how to load values, and CacheBuilder is used to set the desired features and actually build the cache. CacheLoader CacheLoader is an abstract class that specifies how to calculate or load values, if not present. There are two ways to create an instance of a CacheLoader:Extend the CacheLoader<K,V> class Use the static factory method CacheLoader.fromIf you extend CacheLoader you need to override the V load(K key) method, instructing how to generate the value for a given key. Using the static CacheLoader.from method you build a CacheLoader either by supplying a Function or Supplier interface. When supplying a Function object, the Function is applied to the key to calculate or retrieve the results. Using a Supplier interface the value is obtained independent of the key. CacheBuilder The CacheBuilder is used to construct cache instances. It uses the fluent style of building and gives you the option of setting the following properties on the cache:Cache Size limit (removals use a LRU algorithm) Wrapping keys in WeakReferences (Strong references used by default for keys) Wrapping values in either WeakReferences or SoftReferences (Strong references used by default) Time to expire entires after last access Time based expiration of entries after being written or updated Setting a RemovalListener that can recieve events once an entry is removed from the cache Concurrency Level of the cache (defaults to 4)The concurrency level option is used to partition the table internally such that updates can occur without contention. The ideal setting would be the maximum number of threads that could potentially access the cache at one time. Here is an example of a possible usage scenario for Guava Cache. public class PersonSearchServiceImpl implements SearchService<List<Person>> {public PersonSearchServiceImpl(SampleLuceneSearcher luceneSearcher, SampleDBService dbService) { this.luceneSearcher = luceneSearcher; this.dbService = dbService; buildCache(); }@Override public List<Person> search(String query) throws Exception { return cache.get(query); }private void buildCache() { cache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(1000) .build(new CacheLoader<String, List<Person>>() { @Override public List<Person> load(String queryKey) throws Exception { List<String> ids = luceneSearcher.search(queryKey); return dbService.getPersonsById(ids); } }); } } In this example, I am setting the cache entries to expire after 10 minutes of being written or updated in the cache, with a maximum amount of 1,000 entires. Note the usage of CacheLoader on line 15. RemovalListener The RemovalListener will receive notification of an item being removed from the cache. These notifications could be from manual invalidations or from a automatic one due to time expiration or garbage collection. The RemovalListener<K,V> parameters can be set to listen for specific type. To receive notifications for any key or value set them to use Object. It should be noted here that a RemovalListener will receive a RemovalNotification<K,V> object that implements the Map.Entry interface. The key or value could be null if either has already been garbage collected. Also the key and value object will be strong references, regardless of the type of references used by the cache. CacheStats There is also a very useful class CacheStats that can be retrieved via a call to Cache.stats(). The CacheStats object can give insight into the effectiveness and performance of your cache by providing statistics such as:hit count miss count total load timme total requestsCacheStats provides many other counts in addition to the ones listed above. Conclusion The Guava Cache presents some very compelling functionality. The decision to use a Guava Cache really comes down to the tradeoff between memory availability/usage versus increases in performance. I have added a unit test CacheTest demonstrating the usages discussed here. As alway comments and suggestions are welcomed. Thanks for your time. ResourcesGuava Project Home Cache API Source Code for blog series  Reference: Google Guava Cache from our JCG partner Bill Bejeck at the Random Thoughts On Coding blog. ...

Predictability – Making Promises you can Keep

Speed – being first to market, rapid innovation and conducting fast cheap experiments – is critically important to startups and many high tech firms. This is where Lean Startup ideas and Continuous Deployment come in. And this is why many companies are following Agile development, to design and deliver software quickly and flexibly, incorporating feedback and responding to change. But what happens when software – and the companies that build software – grow(s) up? What matters at the enterprise level? Speed isn’t enough for the enterprise. You have to balance speed and cost and quality. And stability and reliability. And security. And maintainability and sustainability over the long term. And you have to integrate with all of the other systems and programs in your company and those of your customers and partners. Last week, a group of smart people who manage software development at scale got together to look at all of these problems, at Construx Software’s Executive Summit in Seattle. What became clear is that for most companies, the most important factor isn’t speed, or productivity or efficiency – although everyone is of course doing everything they can to cut costs and eliminate waste. And it isn’t flexibility, trying to keep up with too much change. What people are focused on most, what their customers and sponsors are demanding, is predictability – delivering working software when the business needs it, being a reliable and trusted supplier to the rest of the business, to customers and partners. Enterprise Agile Development and Predictability Steve McConnell’s keynote on estimation in Agile projects kicked this off. A lot of large companies are adopting Agile methods because they’ve heard and seen that these approaches work. But they’re not using Agile out of the box because they’re not using it for the same reasons as smaller companies. Large companies are adapting Agile and hybrid plan-based/Waterfall approaches combining upfront scope definition, estimating and planning, with delivering the project incrementally in Agile time boxes. This is not about discovery and flexibility, defining and designing something as you go along – the problems are too big, they involve too many people, too many parts of the business, there are too many dependencies and constraints that need to be satisfied. Emergent design and iterative product definition don’t apply here. Enterprise-level Agile development isn’t about speed either, or “early delivery of value”. It’s about reducing risk and uncertainty. Increasing control and visibility. Using story points and velocity and release Burn Up eporting and evidence of working software to get early confidence about progress on the project and when the work will be done. The key is to do enough work upfront so that you can make long-term commitments to the business – to understand what the business needs, at least at a high level, and estimate and plan this out first. Then you can follow Agile approaches to deliver working software in small steps, and to deal with changes as they come in. As McConnell says, it’s not about “responding to change over following a plan”. It’s having a plan that includes the ability to respond to change. By continuously delivering small pieces of working software, and calibrating their estimates with real project data using velocity, a team working this way will be able to narrow the “cone of uncertainty” much faster – they’ll learn quickly about their ability to deliver and about the quality of their estimates, as much as 2x faster than teams following a fully sequential Waterfall approach. There are still opportunities to respond to change and reprioritize. But this is more about working incrementally than iteratively. Kanban and Predictability Enterprise development managers are also looking at Kanban and Lean Development to manage waste and to maintain focus. But here too the value is in improving predictability, to smooth work out and reduce variability by finding and eliminating delays and bottlenecks. It’s not about optimization and Just-in-Time planning. As David Anderson explained in his keynote on Delivering Better Predictability, Business Agility and Good Governance with Kanban, senior executives care about productivity, cost and quality – but what they care about most is predictability. The goal of a good software development manager is to be able to make a customer promise that their organization can actually meet. You do this by keeping the team focused on the business of making software, and trying to drive out everything else: eliminating delays and idle time, cutting back administrative overhead, not doing work that will end up getting thrown away, minimizing time wasted in multi-tasking and context-switching, and not starting work before you’ve finished the work that you’ve already committed to. Anderson says that managers like to start on new work as it comes in because “starting gives your customer a warm comfortable feeling” – until they find out you’ve lied to them, because “we’re working on it” doesn’t mean that the work is actually getting done, or will ever get done. This includes fixing bugs – you don’t just fix bugs right away because you should, you fix bugs as they’re found because the work involved is smaller and more predictable than trying to come back and fixing them later. Teams can use Kanban to dynamically prioritize and control the work in front of them, to balance support and maintenance requirements against development work and fixed date commitments with different classes of service, and limit Work in Progress (WIP) to shorten lead times and improve throughput, following the Theory of Constraints. This lets you control variability and improve predictability at a micro-level. But you can also use actual throughput data and Cumulative Flow reporting to project forward on a project level and understand how much work the team can do and when they will be done. What’s interesting to me is seeing how the same ideas and methods are being used in very different ways by very different organizations – big and small – to achieve success, whether they are focused on fast iterations and responding to rapid change, or managing large programs towards a predictable outcome.   Reference: Predictability – Making Promises you can Keep from our JCG partner Jim Bird at the Building Real Software blog. ...

JSON-Schema generation in Jersey

So in my previous post I talked about a proposal to allow the use of JSON-Schema in a WADL, this post looks at how to get this working with a recently build of Jersey. You are going to have to download / reference 1.16SNAPSHOT until 1.16 is released. If you are using Maven this should be quite straight forward to update your dependencies assuming you already have jersey and jersey-json. You are just going to need to add a dependency on the ‘jersey-wadl-json-schema’ artefact from the ‘com.sun.jersey.contribs’ group to get the new feature. If you are outside of Maven the easiest thing to do would be to download the latest jersey-archive and then the jersey-wadl-json-schema jar. How you deploy these is tool specific, but if you are using WLS then here are some specific notes on how to upgrade the version of Jersey. Once you have this working, you need to create a WadlGeneratorConfig class in order to enable this new grammar generation: package jersey;import com.sun.jersey.api.wadl.config.WadlGeneratorConfig; import com.sun.jersey.api.wadl.config.WadlGeneratorDescription; import com.sun.jersey.wadl.generators.json.WadlGeneratorJSONGrammarGenerator;import java.util.List;public class JsonGeneratorConfig extends WadlGeneratorConfig {@Override public Listconfigure() { return generator(WadlGeneratorJSONGrammarGenerator.class).descriptions(); } } This can then be registered in a variety of ways, here is an example using a servlet init param. Note also that to make this example simple that we are using the Jersey POJO mapping; but whilst writing this blog I noticed that this setting affected the format of the JSON version of the WADL in case you try this. <?xml version = '1.0' encoding = 'ISO-8859-1'?> <web-app xmlns='http://java.sun.com/xml/ns/javaee' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd' version='3.0'> <servlet> <servlet-name>jersey</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.WadlGeneratorConfig</param-name> <param-value>jersey.JsonGeneratorConfig</param-value> </init-param> <init-param> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey</servlet-name> <url-pattern>/resources/*</url-pattern> </servlet-mapping> </web-app> So I put together a really simple echo service, just to check this is all working: package jersey;import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces;@Path('/echo') public class EchoResource {@GET @Produces('application/json') public EchoBean echo() { EchoBean bean = new EchoBean(); bean.setMessage('Hello'); return bean; }@POST @Consumes('application/json') @Produces('application/json') public EchoBean echo(EchoBean echo) { return echo; }}andpackage jersey;public class EchoBean { public EchoBean() { super(); }private String message;public void setMessage(String message) { this.message = message; }public String getMessage() { return message; }} This very simple example results in the following WADL with the JSON-Schema elements referenced: <?xml version = '1.0' encoding = 'UTF-8'?> <ns0:application xmlns:ns0='http://wadl.dev.java.net/2009/02'> <ns0:doc xmlns:ns1='http://jersey.java.net/' ns1:generatedBy='Jersey: 1.16-SNAPSHOT 11/19/2012 12:59 AM'/> <ns0:grammars/> <ns0:resources base='http://localhost:7103/Jersey/resources/'> <ns0:resource path='/echo'> <ns0:method id='echo' name='GET'> <ns0:response> <ns0:representation mediaType='application/json' xmlns:ns2='http://wadl.dev.java.net/2009/02/json-schema' ns2:describedby='application.wadl/echoBean'/> </ns0:response> </ns0:method> <ns0:method id='echo' name='POST'> <ns0:request> <ns0:representation mediaType='application/json' xmlns:ns3='http://wadl.dev.java.net/2009/02/json-schema' ns3:describedby='application.wadl/echoBean'/> </ns0:request> <ns0:response> <ns0:representation mediaType='application/json' xmlns:ns4='http://wadl.dev.java.net/2009/02/json-schema' ns4:describedby='application.wadl/echoBean'/> </ns0:response> </ns0:method> </ns0:resource> </ns0:resources> </ns0:application> The URI application.wadl/echoBean contains this simple JSON-Schema definition: { 'type' : 'object', 'properties' : { 'message' : { 'type' : 'string' } }, 'name' : 'echoBean' } Now there are a number of limitations in the current design, not least that the generated schema doesn’t take into account any notation settings. But I thought this would be enough to provoke feedback on whether this feature would be useful generally. There appears to be a growing interest in JSON-Schema both around the net and internally to Oracle, so it would be interesting to see whether this description becomes more common.   Reference: JSON-Schema generation in Jersey from our JCG partner Gerard Davison at the Gerard Davison’s blog blog. ...

Google Guava – Futures

This post is a continuation of my series on Google Guava, this time covering Futures. The Futures class is a collection of static utility methods for working with the Future/ListenableFuture interface. A Future is a handle to an asynchronous task, either a Runnable or Callable, that was submitted to an ExecutorService. The Future interface provides methods for: getting the results of a task, checking if a task is done, or canceling a task. The ListenableFuture interface extends the Future interface and adds the ability to set a completion listener to run once a task is finished. To create a ListenableFuture you first need to decorate an ExecutorService instance like so:           ExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); Now all submitted Callables/Runnables will return a ListenableFuture. MoreExecutors can be found in the com.google.common.util.concurrent package. ListenableFutures were covered in the previous post. There are too many methods in Futures to effectively cover in one post, so I am only going to cover: chain, transform, allAsList and successfulAsList. Throughout this post, I will refer to Futures and ListenableFutures interchangeably. Chain The chain method returns a ListenableFuture whose value is calculated by taking the results from an input Future and applying it as an argument a Function object, which in turn, returns another ListenableFuture. Let’s look at a code example and step through it: ListenableFuture<List<String>> indexSearch = luceneSearcher.searchAsync('firstName:martin');Function<List<String>, ListenableFuture<List<Person>>> queryFunction = new Function<List<String>, ListenableFuture<List<Person>>>() { @Override public ListenableFuture<List<Person>> apply(final List<String> ids) { return dataService.getPersonsByIdAsync(ids); } };ListenableFuture<List<Person>> results = Futures.chain(indexSearch, queryFunction,executorService);Line 1 is executing an asynchronous search using Lucene and will return a list of id’s that represent the primary key of a person record stored in a database. (I created a small index where the only data stored in Lucene is the id’s and the rest of the data was indexed only). Lines 4 – 11 are building the function object where the apply method will use the results from the search future as input. The future returned from apply is a result of the call to the dataService object. Line 12 is the future that is returned from the chain call. The executorService is used to run the function once the input future is completed.For additional clarity, here is what the searchAsync and getPersonsByIdAsync methods are doing. These method calls are from lines 2 and 8 respectively, in the previous code example: public ListenableFuture<List<String>> searchAsync(final String query) { return executorService.submit(new Callable<List<String>>() { @Override public List<String> call() throws Exception { return search(query); } }); }public ListenableFuture<List<Person>> getPersonsByIdAsync(final List<String> ids) { return executorService.submit(new Callable<List<Person>>() { @Override public List<Person> call() throws Exception { return getPersonsById(ids); } }); } The chain method has two signatures:chain(ListentableFuture, Function) chain(ListenableFuture, Function, ExecutorService)When determining which method to use there are a few points to consider. If the input future is completed by the time chain is called, the supplied function will be executed immediately in the calling thread. Additionally, if no executor is provided then a MoreExecutors.sameThreadExecutor is used. MoreExecutors.sameThreadExecutor (as the name implies) follows the ThreadPoolExecutor.CallerRunsPolicy, meaning the submitted task is run in the same thread that called execute/submit. Transform The transform method is similar to the chain method, in that it takes a Future and Function object as arguments. The difference is that a ListenableFuture is not returned, just the results of applying the given function to the results of the input future. Consider the following: List<String> ids = .... ListenableFuture<List<Map<String, String>>> dbRecords = dataService.getPersonDataByIdAsync(ids);Function<List<Map<String, String>>,List<Person>> transformDbResults = new Function<List<String>, List<Person>>() { @Override public List<Person> apply(List<Map<String, String>> personMapList) { List<Person> personObjList = new ArrayList<Person>(); for(Map<String,String> personDataMap : personMapList){ personObjList.add(new Person(personDataMap); } return personObjList; } };ListenableFuture<List<Person>> transformedResults = Futures.transform(dbRecords, transformDbResults, executorService);On line 2 an asynchronous database lookup is performed On line 4 a function object is being created, but on line 8, notice the return type is List<Person>The transform method has the same overloaded method calls as chain, with the same caveats. AllAsList The allAsList method will take an arbitrary number of ListenableFutures either as varargs or in the form of an Iterator<ListenableFuture>. A ListenableFuture is returned whose value is a list of all of the results of the inputs. The values returned in the list are in the same order as the original list. If any of the input values were cancelled or failed then the returned ListenableFuture will be cancelled or fail as well. Canceling the returned future from the allAsList call will not propagate down to any of the original tasks submitted in the list. ListenableFuture<List<Person>> lf1 = getPersonsByFirstNameFuture('martin'); ListenableFuture<List<Person>> lf2 = getPersonsByFirstNameFuture('bob'); ListenableFuture<List<List<Person>>> lfResults = Futures.allAsList(lf1, lf2); //assume lf1 failed List<List<Person>> personLists = lfResults.get() //call results in exception   SuccessfulAsList The successfulAsList method is very similar to allAsList, but is more forgiving. Just like allAsList, successfulAsList returns a list of results in the same order as the input list, but if any of the inputs failed or were cancelled the corresponding value in the list is null. Canceling the returned future will not cancel any of the original inputs as well. ListenableFuture<List<Person>> lf1 = getPersonsByFirstNameFuture('martin'); ListenableFuture<List<Person>> lf2 = getPersonsByFirstNameFuture('bob'); ListenableFuture<List<List<Person>>> lfResults = Futures.successfulAsList(lf1, lf2); //assume lf1 failed List<List<Person>> personLists = lfResults.get(); List<Person> listOne = personLists.get(0) //listOne is null List<Person> listTwo = personLists.get(1) //listTwo, not null   Conclusion Hopefully this was helpful in discovering the usefulness contained in the Futures class from Google Guava. I have created a unit test that shows example usages of the methods described in this post. As there is a fair amount of supporting code, I have created a project on gihub, guava-blog. This project will also contain the source code from my previous posts (Monitor, ListenableFuture) on Guava. As always comments and suggestions are welcomed. ResourcesGuava Project Home Futures API Source Code for blog series  Reference: Google Guava – Futures from our JCG partner Bill Bejeck at the Random Thoughts On Coding blog. ...
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below: