A good architect should lead be example. He should be able to fulfill any of the positions within his team. Withoug a good understanding of the full range of technology, an architect is little more than a project manager. It is perfectly acceptable for team members to have more in-depth knowledge in their specific areas, but it's difficult to imagine how team members can have confidence in their architect if the architect doesn't understand the technology.
The architect is the interface between the business and the technology team and must understand every aspect of the technology to be able to represent the team to the business without having to constantly refer others. Similarly the architect must understand the business in order to drive the team toward it's goal of serving the business.
Architects should be brought into the team at the earliest part of the project. They should not sit in an ivory tower dictating the way forward, but should be on the ground working with the team. Technology choices should be made pragmatically through hands on investigation or using advice from architect peers.
The Java Developer Journal
Tuesday, April 24, 2012
Tuesday, April 10, 2012
JSR 330 : Contexts and dependency injection for the Java EE platform
Using the JSR 330 API is pretty simple. First you define an injection point in a class, which wants to use a concrete implementation of a service
Injecting a service using annotations is an ok approach, but what I don't like is the lack of configuration options. What would for instance happen if I create two different implementations of the BusinessService interface and want to inject these two into different beans? Do I then have to also create two qualifier interfaces to distinguish between them? To me that sounds lame.
A possible JSR 330 implementation might configure it's beans in one major XML file. Would it be so hard to for instance have the qualifier configuration there instead? The benefits would be:
// injection-point; no get/set needed... @Inject private BusinessService service;Next you need to provide an actual implementation
public class DefaultBusinessService implements BusinessService { ... }If you have more versions of this service, you have to create a Qualifier annotation:
@Qualifier @Target( { TYPE, METHOD, FIELD }) @Retention(RUNTIME) public @interface FancyService { }You use the Qualifier to inject a more meaningful implementation of the service :
@Inject @FancyService private BusinessService fancyService;As you see, using JSR 330 is pretty simple. So, what's the drawback with this solution?
Injecting a service using annotations is an ok approach, but what I don't like is the lack of configuration options. What would for instance happen if I create two different implementations of the BusinessService interface and want to inject these two into different beans? Do I then have to also create two qualifier interfaces to distinguish between them? To me that sounds lame.
A possible JSR 330 implementation might configure it's beans in one major XML file. Would it be so hard to for instance have the qualifier configuration there instead? The benefits would be:
- No compile time dependencies to one given qualifier interface
- Changing the business service would just be a mather of changing the XML file
JSR 330 might work in a standalone project where the configuration never changes, but I really don't see how this should work in a large software system where configuration and requirements can change pr customer and installation...
Tuesday, April 3, 2012
What today's software developers need to know
Today's software developers don't have to worry about many things that their predecessors used to, like coding to minimize RAM consumption even if it means significantly longer execution time, or WAN connections maxing out at 14.4 kilobits per second. (Although, there may be some out of the fashion skills they could benefit from or that may yet regain relevance.)
However, the reverse is also true: there are many new skills and areas of expertise that today's software developers, hardware developers, system and network administrators, and other IT professionals need that simply didn't exist in the past. (Where "the past" could be anything from "more than three months ago" to five, ten, twenty or more years.)
Knowing what you need to know matters, whether you're just starting out as a software developer (or planning to become one), or are a "seasoned" professional who wants to keep your chops fresh so you can stay in, re-enter, or advance.
So here are what software developers that should add to their existing knowledge portfolio.
"Programmers don't learn that someone else is going to take care of the code they write," criticizes Sarah Baker, Director of Operations at an Internet media company. "They don't learn about release management, risk assessment of deploy of their code in a infrastructure, or failure analysis of their code in the production environment -- everything that happens after they write the code. They don't learn that a log is a communication to a operations person, and it should help an operations person determine what to do when they read that log."
However, the reverse is also true: there are many new skills and areas of expertise that today's software developers, hardware developers, system and network administrators, and other IT professionals need that simply didn't exist in the past. (Where "the past" could be anything from "more than three months ago" to five, ten, twenty or more years.)
Knowing what you need to know matters, whether you're just starting out as a software developer (or planning to become one), or are a "seasoned" professional who wants to keep your chops fresh so you can stay in, re-enter, or advance.
So here are what software developers that should add to their existing knowledge portfolio.
Using libraries
"One thing that strikes me as a new skill is the need to work with massive pre-packaged class libraries and template libraries in all the new languages, like Java or C++ or Python," says consultant and software developer Jeff Kenton. "It used to be that once you knew the language and a small set of system calls and string or math library calls, you were set to program. Now you can write complex applications by stringing library calls together and a little bit of glue to hold them all together. If you only know the language, you're not ready to produce anything."Asynchronous programming and other techniques
"Because of the move to cloud computing mostly through web-based interfaces, we are seeing an emphasis on asynchronous programming," says Itai Danan, founder of Cybernium a software development and web design consulting company. "Ten years ago, this was mostly used by transactional systems such as banks, hotels and airline reservations. Today, all but the simplest applications require asynchronous programming, mostly because of AJAX. This is a very different style of programming -- most things taught about software optimizations do not apply across the network boundary."A breadth of skills
"It's become more important to have a breadth of skills" says Ben Curren, CoFounder, Outright.com, which offers easy-to-use online accounting and bookkeeping software for small businesses. "For example, web developers these days need to understand customers, usability, HTML, CSS, Javascript, APIs, server-side frame works, and testing/QA.""Programmers don't learn that someone else is going to take care of the code they write," criticizes Sarah Baker, Director of Operations at an Internet media company. "They don't learn about release management, risk assessment of deploy of their code in a infrastructure, or failure analysis of their code in the production environment -- everything that happens after they write the code. They don't learn that a log is a communication to a operations person, and it should help an operations person determine what to do when they read that log."
Agile and collaborative development methods
"Today's developers need to have awareness of more agile software development processes," says Jeff Langr, owner, Langr Software Solutions, a software consultancy and training firm. "Many modern teams have learned to incrementally build and deliver high-quality software in a highly collaborative fashion, to continually changing business needs. This ability to adapt and deliver frequently can result in significant competitive advantage in the marketplace.Developing for deployability, scalability, manageability
"Sysadmins are likely to own the software for much longer than the developers -- what are you doing to make their stewardship pleasant enough that they look forward to your next deployment?" asks Luke Kanies, Founder and CEO of Puppet Labs: "This includes deployability and manageability. New technologies are often much more difficult to deploy on existing infrastructure because developers haven't had time to solve problems like packaging, running on your slightly older production OS, or connecting to the various services you have to use in production."Monday, April 2, 2012
Dependency injection
Dependency injection (DI) is an approach to the testing of computer programs, the purpose of which is both to improve the testability of a large software system and to simplify the deployment of software components within that system. DI is an example of a design pattern in object-oriented computer programming.
In a short time I will write about JSR-300 and why I don't like it.
Dependency injection involves at least three elements:
- a dependent consumer,
- a declaration of a component's dependencies, defined as interface contracts,
- an injector (sometimes referred to as a provider or container) that creates instances of classes that implement a given dependency interface on request.
The dependent object describes what software component it depends on to do its work. The injector decides what concrete classes satisfy the requirements of the dependent object, and provides them to the dependent.
In conventional software development the dependent object decides for itself what concrete classes it will use. In the dependency injection pattern, this decision is delegated to the "injector" which can choose to substitute different concrete class implementations of a dependency contract interface at run-time rather than at compile time.
Being able to make this decision at run-time rather than compile time is the key advantage of dependency injection. Multiple, different implementations of a single software component can be created at run-time and passed into (injected) the same test code. The test code can then test each different software component without being aware that what has been injected is implemented differently.
There has been several ways of doing dependency injection in your Java application. The idea behind them is well understood, but the actual realization is slightly different.: XML files or property files vs Java annotations or classes. Choosing between which framework to use can become a pretty religious discussion.In a short time I will write about JSR-300 and why I don't like it.
Friday, March 23, 2012
How to shutdown an ExecutorService
The new executor framework in Java 6 makes it dead easy to create components running in a background thread. Just create an executor, give it a java.util.Runnable and that's it. But how do you do a proper shutdown of a ExecutorService?
The next step is to wait for already running tasks to complete. In this example we will allow the running tasks to complete within pTimeout seconds. If they don't complete within the given amount of seconds, we invoke shutdownNow(). This method will invoke interrupt on all still running threads.
As a good practice we also make sure to catch InterrruptedException's and shutdown everything immediately.
1. pExecutorService.shutdown();First we invoke the shutdown method on the executor service. After this point, no new runnables will be started.
2. try {
3. if (!pExecutorService.awaitTermination(pTimeout, TimeUnit.SECONDS)) {
4. pExecutorService.shutdownNow();
5. }
6. catch (final InterruptedException pCaught) {
7. pExecutorService.shutdownNow();
8. Thread.currentThread().interrupt();
9. }
10. }
The next step is to wait for already running tasks to complete. In this example we will allow the running tasks to complete within pTimeout seconds. If they don't complete within the given amount of seconds, we invoke shutdownNow(). This method will invoke interrupt on all still running threads.
As a good practice we also make sure to catch InterrruptedException's and shutdown everything immediately.
Monday, March 12, 2012
What should you cache?
A good way of solving performance problems in an application is often to add caching at strategic layers of the application. But what should you cache?
For me, the single most important thing to cache is to everything that makes a network request.
Performing a network request will always have an overhead caused by the TCP/IP protocol, network latency, the network cards and the Ethernet cables. Even the slightest network hick up might cause huge performance issues in your application. A slow database will seriously decrease the performance of your application.
It is often not possible to cache everything that makes a network request, but not doing so should at least be a conscious decision and not just something you forgot to implement.
For me, the single most important thing to cache is to everything that makes a network request.
Performing a network request will always have an overhead caused by the TCP/IP protocol, network latency, the network cards and the Ethernet cables. Even the slightest network hick up might cause huge performance issues in your application. A slow database will seriously decrease the performance of your application.
It is often not possible to cache everything that makes a network request, but not doing so should at least be a conscious decision and not just something you forgot to implement.
Friday, March 9, 2012
Public methods and package private classes
Given these two classes
both in package org.mydomain. What will happen if I create a new instance of ConcreteClass in another package and try to invoke doSomething()? Will that work?
The answer to this question is it depends on the JDK.
The Sun JDK allows you to access a public method in a package private class. However, OpenJDK will throw
I'm not sure what the JDK specification says about this, but the moral is
Do not have public methods in package private classes.
class abstract AbstractClass {
public void doSomething() {
System.out.println("Hello world");
}
}
public class ConcreteClass extends AbstractClass {
}
both in package org.mydomain. What will happen if I create a new instance of ConcreteClass in another package and try to invoke doSomething()? Will that work?
The answer to this question is it depends on the JDK.
The Sun JDK allows you to access a public method in a package private class. However, OpenJDK will throw
java.lang.IllegalAccessException: Class MyClass can not access a member of class ConcreteClass with modifiers "public"
I'm not sure what the JDK specification says about this, but the moral is
Do not have public methods in package private classes.
Subscribe to:
Posts (Atom)