Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 3 of 4
Using an editor that's not joined at the hip to a compiler will show how well you really know the libraries you use every day. Unfortunately, the deck is stacked against you. The proliferation of code completion has allowed some libraries to give in to baroque tendencies, burying nearly every class five packages deep and naming it with an entire sentence of camel-cased words. Java code has mutated from plain text into something that nearly requires machine assistance to edit.
This doesn't just limit options for editing verbose libraries; it makes coding in a creative flow quite impossible. Instead of translating mental logic into computer instructions with confidence, a programmer relying on command completion works like a lazy actor constantly calling out for the next line. There is some hope of reversing the trend, but for now using a simple editor will require determined typing and a ready access to API references.
And for those references, the way out of the hole is not so slippery after all. Because Maven repositories can hold not only compiled packages but their sources and Javadocs as well, it's possible to obtain documentation for a project without regressing to Internet hunting and gathering -- that is, when your builder is hackable. (Sorry, Maven.)
def doc_tasks(jar_spec)
artifacts(jar_spec).map do |a|
doc_a = artifact(a.to_hash.merge({:classifier=>'javadoc'}))
doc_a.extend SoftFail
file(_(LIB_DOCS) + '/' + a.to_spec => doc_a) do |task|
unzip(task.name => doc_a) if File.exist? doc_a.name
end
end
end
The Ruby function for Buildr illustrated in Listing 4 accepts artifact specifications and returns an array of tasks that will,
if invoked, download and extract Javadocs paired with those artifacts into the project subdirectory specified by LIB_DOCS. The function could go into a Rakefile, or into another file included by it. Because Buildr's artifacts method can handle all manner of nested artifact specifications, so can lib_doc_tasks.
The procedure quickly runs into a problem: not all libraries maintain corresponding Javadoc artifacts. Normally, Buildr's
artifact task will abort the build on a download failure, but we don't want to abort, nor do we want to manually purge an
artifact tree of those that don't have matching Javadocs. The solution, then, is the ad hoc SoftFail module in Listing 5, which overrides the failure method to warn only.
module SoftFail
def fail_download(remote_uris)
puts "Can't find javadoc #{to_spec}\n"
end
end
From inside a Buildr project, call lib_docs with some specs, and add all the created tasks as prerequisites to the new lib_docs task in Listing 6.
doc_tasks(WICKET).each { |t| task :lib_docs => t }
Now you can sit back, go offline, and really get to know those libraries you've been using for the past few years.
Editing and compiling is nice, but the destiny of all software code is execution. And these days, most of it is executed in the name of serving Web pages. Here the road to a simple and flexible toolset turns away from finicky servlet containers and leads to a landscape of server embedding.
If it seems strange to serve Web requests directly from an application, that's only because the Servlet API has from its inception taken a different approach. But today the HTTP protocol is so fundamental, so much a part of the software zeitgeist, that it makes perfect sense to serve requests from an application -- just as we initiate requests internally with a library like HttpClient.
Jetty is a very popular embeddable servlet container. By linking to its JARs (under org.mortbay.jetty at the Maven repo) you can start a server from a main() function in short order, as shown in Listing 7.
public static void main(String[] args) throws Exception
{
Server server = new Server();
WebAppContext web = new WebAppContext();
web.setContextPath("/");
web.setWar("src/main/webapp");
server.addHandler(web);
SelectChannelConnector httpConn = new SelectChannelConnector();
httpConn.setPort(8080);
server.setConnectors(new Connector[] { httpConn });
server.start();
System.out.println("Ready at http://localhost:8080/");
server.join();
}
This could be run from a packaged JAR, but it's most convenient to run it before packaging from a builder that knows your
classpath. To run with buildr myproj:run, add the run task in Listing 8 to a Buildr project.
task :run => :compile do
java('example.CalcServer',
:classpath => compile.classpath + [compile.target.to_s])
end
Or, if the exec-maven-plugin is configured as shown in Listing 9, you could run from Maven with mvn exec:java.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<mainClass>example.CalcServer</mainClass>
</configuration>
</plugin>
Either way, you'll want to add shortcuts for these commands to your editor. Embedding a server doesn't just make it easy to run Web apps in a builder with no plug-ins or other configuration; it also means that such apps can be run inside any IDE as plain Java applications with no container configuration, allowing for the maximum use of running code replacement. Speaking of which, aren't we going to miss code replacement in a decentralized toolset?
make in build and purpose.
java.net package.
Archived Discussions (Read only)