Featured FREE Whitepapers

What's New Here?

apache-maven-logo

Maven Fluido Skin and Javadoc class diagrams

I have been using Maven sites for a while, and am very happy with it. I didn’t like to have to update my projects after Maven 3, but that was all right, Maven 3 brought many new cool things. However, there were two things that annoyed me: lack of a nice and modern skin, and browsing Javadoc of complex code. The thought of creating a custom Maven skin even crossed my mind, but I never had time to read about it. But the world is full of good and talented people! Like the guys from 99soft. They created Maven Fluido Skin, and donated it to Apache Software Foundation. It’s built on top of Twitter’s Bootstrap and available from Maven central repository. In order to use it in your Maven project, all that you have to do is add the following settings into your src/site/site.xml: <skin> <groupId>org.apache.maven.skins</groupId> <artifactId>maven-fluido-skin</artifactId> <version>1.2.1</version> </skin> Here’s a list of some projects using Maven Fluido Skin (hopefully, in the near future Apache Commons and other projects will adopt this skin as default too ):Maven Fluido Skin tap4j TestLink Java APIRegarding the Javadoc browsing, there’s a nice trick too: add class diagrams. I have seen a new Javadoc template in Apache Commons mailing list, but it was a work in progress, so for now I will stick with class diagrams. These diagrams are generated when you execute the javadoc or the site goals, using graphviz. And there is more. You can click on the diagram classes, as they have a link to the Java class that they reference to. You can find instructions for setting up the diagram generation in Apache Maven web site, or looking at examples (I prefer the latter). But basically, you will need graphviz installed, and something like the following XML snippet in your project pom.xml. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.7</version> <configuration> <doclet>gr.spinellis.umlgraph.doclet.UmlGraphDoc</doclet> <docletArtifact> <groupId>gr.spinellis</groupId> <artifactId>UmlGraph</artifactId> <version>4.4</version> </docletArtifact> <additionalparam> -inferrel -inferdep -quiet -hide java.* -collpackages java.util.* -qualify -postfixpackage -nodefontsize 9 -nodefontpackagesize 7 -edgefontname 'Trebuchet MS' -nodefontabstractname 'Trebuchet MS' -nodefontclassabstractname 'Trebuchet MS' -nodefontclassname 'Trebuchet MS' -nodefontname 'Trebuchet MS' -nodefontpackagename 'Trebuchet MS' -nodefonttagname 'Trebuchet MS' </additionalparam> </configuration> </plugin> Here’s how a diagram looks like (source: http://tap4j.org/apidocs/index.html):Have fun! And remember to check if your CI machine has graphviz installed too, otherwise you will have 404 in your Javadoc pages. Happy coding and don’t forget to share! Reference: Maven site tips: Maven Fluido Skin and Javadoc class diagrams from our JCG partner Bruno Kinoshita at the Kinoshita’s blog blog....
software-development-2-logo

The Myth of Start Up Costs

Conventional wisdom in the start-up community these days is that it has never been cheaper to start and build a company. It’s been written and re-written about, but I’ll summarize the logic as: You used to have to build your product, then write enormous checks to Oracle, Microsoft, IBM, Sun, etc to buy the hardware/software that you needed to run your business. Then, if you got big enough, you had to build a datacenter. Contrast that with today, where you simply need to sign up on AWS, get a subscription to Workday/SFDC, etc…and the costs of starting up have plummeted. Makes sense. Seems logical. But, it seems to me to be only part of the story. If now is the cheapest time ever to start a company, how do you explain this:Certainly, I could quickly speculate that companies are staying private longer than before and hence, need more capital. However, if you look at the data below, I’m not sure that argument holds up:My belief is that the cost of starting a company is essentially unchanged from 10-20 years ago. If anything, its a bit higher. (Note: obviously this depends on whether you look at year 1 costs or costs until liquidity or somewhere in-between year 1 and liquidity. I’m focusing on the latter two cases). So, why have the costs of starting a company and running it through the mid-years not changed, given that the costs of year 1 are substantially cheaper? I think there has been one substantial change to start-up economics, that very few are acknowledging or writing about: early stage companies have started paying salaries/benefits, etc that are on-par with what Fortune 500 companies pay. I see this over and over again…and its in all parts of the country. This is partially driven by a war on talent, but I don’t think its that simple. I believe the culture and expectations have changed and salaries/benefits are becoming table stakes, as opposed to a nice-to-have. There was a time when you joined a start-up for equity and/or stock options. While there is still some of that, most are joining for salaries/benefits, along with their interest in the mission of the company. This is a fundamental shift in start-up economics and I think it offsets ‘The Myth of Start Up Costs’. I’ll acknowledge that some of my data in this post in anecdotal and I certainly do not have extensive data on private companies. However, I am writing this based on what I’ve seen with my own eyes. Criticism and disagreement is welcome. Reference: The Myth of Start Up Costs from our JCG partner Rob Thomas at the Rob’s Blog blog....
spring-logo

Spring MVC Controller JUnit Testing

JUnit testing Spring MVC controllers is not an easy task. But recently, a new project (to be included in Spring soon) offers new tools to facilitate this. This post illustrates how to test a simple controller via JUnit tests. This code is a variation of the code used in JUnit Testing Spring Service and DAO (with In-Memory Database). It is available from Gihut in the Spring-MVC-JUnit-Testing directory. Test Configuration Classes These are identical to those required for Service and DAO testing. Controller Our controller: @Controller public class MyController {@Autowired private MyService myService;@RequestMapping(value = '/') public String home(Model model) {return 'index';}@RequestMapping(value = '/roundtrip') public String persistenceStatus(Model model) {MilliTimeItem retr = myService.createAndRetrieve(); model.addAttribute('RoundTrip', retr);return 'roundtrip';}}Controller Testing The following creates an instance of MockMvc to test simulated user requests: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes={ JpaTestConfig.class, TestConfig.class }) public class MyControllerTest {private MockMvc mockMvc;@Before public void setup() {mockMvc = MockMvcBuilders .annotationConfigSetup(JpaTestConfig.class, TestConfig.class) .build();}@Test public void testHome() throws Exception {mockMvc.perform(get('/')) .andExpect(status().isOk()) .andExpect(forwardedUrl('WEB-INF/pages/index.jsp'));}@Test public void testPersistenceStatus() throws Exception {mockMvc.perform(get('/roundtrip')) .andExpect(status().isOk()) .andExpect(forwardedUrl('WEB-INF/pages/roundtrip.jsp')) .andExpect(model().attributeExists('RoundTrip'));}} The / request tests the returned status and the URL mapping to the JSP page. The /roundtrip request makes sure the returned model does contain the Roundtrip attribute. Dependencies The Spring MVC test artifact is not yet available from maven’s central repository. It should be obtained from another repository: <repositories> <repository> <id>spring.test-mvc</id> <url>http://repo.springsource.org/libs-milestone</url> </repository> </repositories>The required dependency are: <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test-mvc</artifactId> <version>1.0.0.M1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-library</artifactId> <version>1.3</version> <scope>test</scope> </dependency> More Spring related posts here. Reference: Spring MVC Controller JUnit Testing from our JCG partner Jerome Versrynge at the Technical Notes blog....
html5-logo

JavaOne 2012: Building Mobile Apps with HTML5 and Java

I returned to Parc 55 (Mission conference room) to see Max Katz‘s (Exadel Developer Relations) ‘Building Mobile Apps with HTML5 and Java’ Birds-of-a-Feather (BoF) presentation. Specifically, Katz is in Developer Relations for Tiggzi, a cloud-based app platform.Katz only had a single slide before going into demonstration mode. He explained that this is a cloud-based tool as we waited for it to load. He stated by working on an example application to connect to Twitter via their exposed REST interfaces. He pointed out that because this example is based on JavaScript and jQuery, it can be used on any web browser. Katz made his example public and created a TinyUrl for it. Desktops could access http://tinyurl.com/javaone12m and mobile devices could access http://tinyurl.com/javaone12m1. It was pretty impressive to be able to reload/refresh the application as he worked on it on my laptop and on my Droid. It really drove home how easy this cloud-based solution is to use and deploy. It was one of the more impressive real-time demonstrations I’ve seen. Katz moved onto another example that accessed data from the database rather than from Twitter’s API. One of the nifty things he demonstrated was the reporting of the equivalent curl command for accessing the data via REST. All of Katz’s demonstrations were implemented within the Google Chrome web browser. I was surprised at how fluid the behavior was for the most part. It seemed to have responsiveness similar to a decent desktop Java IDE. I’d say that the tool’s interface itself is probably more complicated than the applications most developers would develop on it, but that could probably be said for Java IDEs as well. One of the audience members asked if Tiggzi supports SOAP. The answer was ‘no’ and that Tiggzi supports XML or JSON over REST only. Katz recognized that we ‘don’t want to buy stuff,’ but provided an overview of Tiggzi’s pricing strategy (pricing based on number of deployed applications and all plans have all features). He said that if you use promo code ‘javaone12‘ at tiggzi.com you can get the Pro Plan for a trial period. The title of the session seemed a little misleading as there was next to no coverage of Java other than mention that Twitter uses Java and the first example uses Twitter. The abstract seemed a bit misleading as there was no mention of Tiggzi-specific solution in that abstract. Those points being stated, I still did enjoy the presentation and found it interesting. It’s probably not something I’ll be able to use in the near future, but it was fun to see and think about the possibilities. Reference: JavaOne 2012: Building Mobile Apps with HTML5 and Java [Tiggzi] from our JCG partner Dustin Marx at the Inspired by Actual Events blog....
eclipse-logo

Giving up on Eclipse Juno

In my last blog I posted about my Eclipse 4.2 Juno setup; as much as a reference for me in case I needed to do a reinstall as anything else. What I didn’t talk about then was the issues I’ve been having generally with Juno. I had thought it was my own installation being screwy, but things haven’t improved much since. The main issues I’ve been hitting are:continued modal(!) exception dialogs on certain code completions general sluggishness with the editors HTML editors in particular that are sluggishI could possible live with the last two issues, but the first issue is driving me potty: I can get that modal dialog something like 4 times a minute when I’m into my groove. Not much fun… I’ve realized that I’ve started developing muscle memory to deal with it! As for the performance issues, it would seem that I am not alone, and that things aren’t likely to improve quickly. So, for me, it’s back to Eclipse 3.x. I’ve decided to go with Eclipse 3.7.2; there is an Eclipse 3.8 that was released at the same time as 4.2, but the Eclipse foundation didn’t create the usual distros, and my guess is that it’s not gonna receive much attention if it has bugs etc. Eclipse 3.7 was working just fine for me, so that’s what I’ll use for now. And, let’s see how things are in a year from now. If they don’t fix it, it could be the end of 10 years of using this IDE. PS: I know how this is meant to work: as a user of open source, it is one’s responsibility to contribute back to help improve the product. But my open source time is spent on Apache Isis, and Eclipse is just too big to be able to provide any meaningful help. Don’t forget to share! Reference: Giving up on Eclipse Juno from our JCG partner Dan Haywood at the Dan Haywood blog blog....
news-logo

Spring Shell Project Released

Spring Source released Spring Shell yesterday. Spring Shell is an interactive shell that can be easily extended with commands using a Spring based programming model. It has been extracted from the Spring Roo project by removing the OSGi dependencies and turned into a standalone project. This allows for an easier adoption by those who wish to use only interactive shell features. At the same time, this decoupling facilitates focusing into improving shell functionality and making it an easily reusable component across various projects. Some of its features include:POJO based programming model Spring classpath scanning features Inherits the Roo Shell Features Tab completion Contextual awareness Command Hiding Help assistance Scripting and script recording Command prompt customizationCheck out the Spring Shell page and the relevant documentation. Happy coding!...
play-framework-logo

Play 2.0 framework and XA transactions

XA transactions are useful and out of the box, Play 2.0 today does not have support for them. Here I show how to add that support: First off, some examples when XA is useful: - JPA uses two physical connections if you use entities from two different persistence.xml – those two connections might need to be committed in one transaction, so XA is your only option - Committing a change in a database and at the same time committing a message to JMS. E.g. you want to guarantee that an email is sent after you successfully commit an order to the database, asynchronously. There are other ways, but JMS provides a transactional way to do this with little overhead in having to think about failure. - Writing to a physically different database because of any of several political reasons (legacy system, different department responsible for different database server / different budgets). - See http://docs.codehaus.org/display/BTM/FAQ#FAQ-WhywouldIneedatransactionmanager So the way I see it, XA is something Play needs to ‘support’. Adding support is very easy. I have created a play plugin which is based on Bitronix. Resources are configured in the Bitronix JNDI tree (why on earth does Play use a config file rather than JNDI?! anyway…) You start the transaction like this, ‘withXaTransaction’: def someControllerMethod = Action { withXaTransaction { ctx => TicketRepository.addValidation(user.get, bookingRef, ctx) ValidationRepository.addValidation(bookingRef, user.get, ctx) } val tickets = TicketRepository.getByEventUid(eventUid) Ok(views.html.ticketsInEvent(eventUid, getTickets(eventUid), user, eventValidationForm)) }The ctx object is an XAContext (my own class) which lets you look up resources like a datasource, or set rollback in case of a failure. So the validation repo does this, using ScalaQuery (I used ‘withSession’ rather than ‘withTransaction!’): def addValidation(bookingRef: String, validator: User, ctx: XAContext) = { val ds = ctx.lookupDS("jdbc/maxant/scalabook_admin") Database.forDataSource(ds) withSession { implicit db: Session => Validations.insert(Validation(bookingRef, validator.email, new java.sql.Timestamp(now))) } }And the ticket repo does the following with JMS: def addValidation(user: User, bookingRef: String, ctx: XAContext) = {val xml = {bookingRef} {user.email}val qcf = ctx.lookupCF("jms/maxant/scalabook/ticketvalidations") val qc = qcf.createConnection("ticketValidation","password") val qs = qc.createSession(false, Session.AUTO_ACKNOWLEDGE) val q = qs.createQueue("ticketValidationQueue") //val q = ctx.lookup(QUEUE).asInstanceOf[Queue] val sender = qs.createProducer(q) val m = qs.createTextMessage(xml.toString) sender.send(m) sender.close qs.close qc.close }I’ve tested it with writing to MySQL and sending a JMS message to JBoss (HornetQ) and it seems to work well (except getting hornetQ to play with Bitronix was a bitch – see here: https://community.jboss.org/thread/206180?tstart=0). The scala code for the XA support is: package ch.maxant.scalabook.play20.plugins.xasupportimport play.api.mvc.RequestHeader import play.api.mvc.Results import play.api.mvc.Request import play.api.mvc.AnyContent import play.api.mvc.Result import play.api.mvc.Action import play.api.mvc.Security import play.api._ import play.api.mvc._ import play.api.data._ import play.api.data.Forms._ import ch.maxant.scalabook.persistence.UserRepository import bitronix.tm.TransactionManagerServices import java.util.Hashtable import javax.naming.Context._ import javax.naming.InitialContext import javax.sql.DataSource import bitronix.tm.BitronixTransaction import java.io.File import org.scalaquery.session.Database import org.scalaquery.SQueryException import scala.collection.mutable.ListBuffer import java.sql.Connection import java.sql.SQLException import org.scalaquery.session.Session import bitronix.tm.BitronixTransactionManager import javax.jms.ConnectionFactoryclass XAContext {private val env = new Hashtable[String, String]() env.put(INITIAL_CONTEXT_FACTORY, "bitronix.tm.jndi.BitronixInitialContextFactory") private val namingCtx = new InitialContext(env);var rollbackOnly = false def lookup(name: String) = { namingCtx.lookup(name) } def lookupDS(name: String) = { lookup(name).asInstanceOf[DataSource] } def lookupCF(name: String) = { lookup(name).asInstanceOf[ConnectionFactory] } }trait XASupport { self: Controller =>private lazy val tm = play.api.Play.current.plugin[XASupportPlugin] match { case Some(plugin) => plugin.tm case None => throw new Exception("There is no XASupport plugin registered. Make sure it is enabled. See play documentation. (Hint: add it to play.plugins)") }/** * Use this flow control to make resources used inside `f` commit with the XA protocol. * Conditions: get resources like drivers or connection factories out of the context passed to f. * Connections are opened and closed as normal, for example by the withSession flow control offered * by ScalaQuery / SLICK. */ def withXaTransaction[T](f: XAContext => T): T = { tm.begin//get a ref to the transaction, in case when we want to commit we are no longer on the same thread and TLS has lost the TX. //we have no idea what happens inside f! they might spawn new threads or send work to akka asyncly val t = tm.getCurrentTransaction Logger("XASupport").info("Started XA transaction " + t.getGtrid()) val ctx = new XAContext() var completed = false try{ val result = f(ctx) completed = true if(!ctx.rollbackOnly){ Logger("XASupport").info("committing " + t.getGtrid() + "...") t.commit Logger("XASupport").info("committed " + t.getGtrid()) } result }finally{ if(!completed || ctx.rollbackOnly){ //in case of exception, or in case of set rollbackOnly = true Logger("XASupport").warn("rolling back (completed=" + completed + "/ctx.rollbackOnly=" + ctx.rollbackOnly) t.rollback } } } }class XASupportPlugin(app: play.Application) extends Plugin {protected[plugins] var tm: BitronixTransactionManager = null override def onStart { //TODO how about getting config out of jar! val file = new File(".", "app/bitronix-default-config.properties").getAbsolutePath Logger("XASupport").info("Using Bitronix config at " + file) val prop = System.getProperty("bitronix.tm.configuration", file) //default System.setProperty("bitronix.tm.configuration", prop) //override with default, if not set//start the TM tm = TransactionManagerServices.getTransactionManager Logger("XASupport").info("Started TM with resource config " + TransactionManagerServices.getConfiguration.getResourceConfigurationFilename) }override def onStop { //on graceful shutdown, we want to shutdown the TM too Logger("XASupport").info("Shutting down TM") tm.shutdown Logger("XASupport").info("TM shut down") }}Use the code as you like, I’m giving it away for free :-) Just don’t complain if it don’t work ;-) It would be nice to see this plugin extended and turned into something a little more production ready. Even nicer would be for Play to support a transaction manager natively, including fetching resources out of JNDI. Happy coding and don’t forget to share! Reference: Play 2.0 framework and XA transactions from our JCG partner Ant Kutschera at the The Kitchen in the Zoo blog....
android-logo

Android ListView example with Image and Text

In this tutorial I am going to show you how to create an Android ListView with images and text. You will learn how to load an image from a resource and how to set text to TextView . Here is the screenshot of the finished ListView.Android List View example on Samsung Galaxy Y s5360ItemDetails class will help us to set and get item data : package com.jsupport.listviewimages;public class ItemDetails {public String getName() { return name; } public void setName(String name) { this.name = name; } public String getItemDescription() { return itemDescription; } public void setItemDescription(String itemDescription) { this.itemDescription = itemDescription; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public int getImageNumber() { return imageNumber; } public void setImageNumber(int imageNumber) { this.imageNumber = imageNumber; }private String name ; private String itemDescription; private String price; private int imageNumber;}ItemListBaseAdapter Which is extended from the BaseAdapter and sets item details and the image package com.jsupport.listviewimages;import java.util.ArrayList;import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView;public class ItemListBaseAdapter extends BaseAdapter { private static ArrayList<ItemDetails> itemDetailsrrayList; private Integer[] imgid = { R.drawable.p1, R.drawable.bb2, R.drawable.p2, R.drawable.bb5, R.drawable.bb6, R.drawable.d1 }; private LayoutInflater l_Inflater;public ItemListBaseAdapter(Context context, ArrayList<ItemDetails> results) { itemDetailsrrayList = results; l_Inflater = LayoutInflater.from(context); }public int getCount() { return itemDetailsrrayList.size(); }public Object getItem(int position) { return itemDetailsrrayList.get(position); }public long getItemId(int position) { return position; }public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = l_Inflater.inflate(R.layout.item_details_view, null); holder = new ViewHolder(); holder.txt_itemName = (TextView) convertView.findViewById(R.id.name); holder.txt_itemDescription = (TextView) convertView.findViewById(R.id.itemDescription); holder.txt_itemPrice = (TextView) convertView.findViewById(R.id.price); holder.itemImage = (ImageView) convertView.findViewById(R.id.photo);convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.txt_itemName.setText(itemDetailsrrayList.get(position).getName()); holder.txt_itemDescription.setText(itemDetailsrrayList.get(position).getItemDescription()); holder.txt_itemPrice.setText(itemDetailsrrayList.get(position).getPrice()); holder.itemImage.setImageResource(imgid[itemDetailsrrayList.get(position).getImageNumber() - 1]);return convertView; }static class ViewHolder { TextView txt_itemName; TextView txt_itemDescription; TextView txt_itemPrice; ImageView itemImage; } }ListViewImagesActivity package com.jsupport.listviewimages;import java.util.ArrayList;import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener;public class ListViewImagesActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);ArrayList<ItemDetails> image_details = GetSearchResults();final ListView lv1 = (ListView) findViewById(R.id.listV_main); lv1.setAdapter(new ItemListBaseAdapter(this, image_details));lv1.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> a, View v, int position, long id) { Object o = lv1.getItemAtPosition(position); ItemDetails obj_itemDetails = (ItemDetails)o; Toast.makeText(ListViewImagesActivity.this, 'You have chosen : ' + ' ' + obj_itemDetails.getName(), Toast.LENGTH_LONG).show(); } }); }private ArrayList<ItemDetails> GetSearchResults(){ ArrayList<ItemDetails> results = new ArrayList<ItemDetails>();ItemDetails item_details = new ItemDetails(); item_details.setName('Pizza'); item_details.setItemDescription('Spicy Chiken Pizza'); item_details.setPrice('RS 310.00'); item_details.setImageNumber(1); results.add(item_details);item_details = new ItemDetails(); item_details.setName('Burger'); item_details.setItemDescription('Beef Burger'); item_details.setPrice('RS 350.00'); item_details.setImageNumber(2); results.add(item_details);item_details = new ItemDetails(); item_details.setName('Pizza'); item_details.setItemDescription('Chiken Pizza'); item_details.setPrice('RS 250.00'); item_details.setImageNumber(3); results.add(item_details);item_details = new ItemDetails(); item_details.setName('Burger'); item_details.setItemDescription('Chicken Burger'); item_details.setPrice('RS 350.00'); item_details.setImageNumber(4); results.add(item_details);item_details = new ItemDetails(); item_details.setName('Burger'); item_details.setItemDescription('Fish Burger'); item_details.setPrice('RS 310.00'); item_details.setImageNumber(5); results.add(item_details);item_details = new ItemDetails(); item_details.setName('Mango'); item_details.setItemDescription('Mango Juice'); item_details.setPrice('RS 250.00'); item_details.setImageNumber(6); results.add(item_details);return results; } } Download the complete project: Android ListView Happy coding and don’t forget to share! Reference: Android ListView example with Image and Text from our JCG partner Chathura Wijesinghe at the Java Sri Lankan Support blog....
enterprise-java-logo

Hunting a Random Bug – A True Story

A few weeks ago, I finished a bug hunt for the RapidFTR open source project, which took me three evenings. I thought it might be worth sharing the story of the hunt. This article will describe what I did. I will give an overview of my journey to actually find the root cause of what was going on. My goal with this article is to highlight examples of techniques you can use, to actually track down strange and random bug. In the end, I found a pretty clear explanation what and why the problem happened. And it is not a coincidence, that there is a ‘random’ in the title of this article.Start – What was the problem The problem was, that when following the guide for using a development virtual machine, sometimes starting up the application took a long time and then failed. I had the issue right away, after starting the application twice. Other people had the same problem. I was told, nobody really knew, why it was behaving this way – but restarting the VM would probably fix it. It didn’t for me. But I enjoy digging into problems – so I wanted to know, what was going wrong.Rake File to Solr The error occurred when running rake app:run, sometimes. From running rake with --trace --verbose, the debug option, I was able to see, that the application was waiting for sunspot to start the Apache Solr search service. So the question was, where does the process take all the time? The good thing to start with was, that rake and sunspot are written in Ruby. So I read the code and added a few output statements to see, which statement took so long. It turned out, it was the Java process starting Solr.Digging into the Java Apache Solr sends some output to sdtout – but sunspot hides it from you. But as any output is very helpful when debugging, I wanted to see the output. I used ps -aux to find the exact command-line arguments sunspot was issuing and started the process manually from the command-line. Luckily, it still took some time – so I knew the problem was not in the Ruby Code. With the port mapper nmap I found out, that it took between 2 seconds to over 2 minutes to start the service. But the rake task only waited for 10 seconds. Now having the the console output, I could see, that Solr internally uses Jetty – and it was Jetty in version 6.1.3, which took all the time – in the case, it took the time. So I downloaded the tag for version 6.1.3 from source control and looked into the code. I found a system property called DEBUG which increases the output. I enabled it and saw that the last debug output, before it took so long, was something about starting the session service (I’ve lost pointer to the code – unfortunately). This didn’t really help me. I unsuccessfully tried to make the Jetty log work with log4j to eventually see more – but I failed and had to give up for the evening (the 2nd one).Debug the Java Code So if your not getting anything out of the log, you can still use a debugger. The code was however failing on the VM – an Ubuntu box, but not on my local machine. But fortunately Java has a remote debugger. I started the Java process with the remote debugging arguments and attached a listener in IntelliJ with the Jetty code from SVN. I tried to get the execution stopped at a breakpoint near the last log output – but this method was called very often and I didn’t get it to hit the breakpoint at the right moment. However, when something takes very long, it can be helpful just to stop the running process and look at the stack trace. So I stopped the execution and searched for the last method frame from Jetty, which was calling into the JDK – and there I found the following comment: //This operation may block on some systems with low entropy. See this page //for workaround suggestions: //http://docs.codehaus.org/display/JETTY/Connectors+slow+to+startup Log.debug('Init SecureRandom.'); _random=new SecureRandom();The Solution Finally – I did go to the Jetty wiki page referenced. I found out, that Java’s java.util.SecureRandom uses real entropy from the operating system – which can block when there is none available. The solution from the wiki page, just to use the normal java.util.Random, would have been difficult, because the configuration file lives deep inside sunspot and Solr. But the line ‘NB Some workaround reports use /dev/./urandom instead of /dev/urandom’ gave me a hint, were to look otherwise. I googled for the solution and found on Stack Overflow, that you can replace /dev/urandom random with /dev/./urandom in your Java process. This can be done by using the command-line argument -Djava.security.egd=file:/dev/./urandom or by replacing it in the file /usr/lib/jvm/java-6-openjdk/jre/lib/security/java.security (on an Ubuntu box). So what was the matter? Java’s secure random will not accept /dev/urandom as source for random numbers. /dev/urandom is unblocking, which means it will return random numbers which can be guessed – when there is no real entropy available. So Java defaults to /dev/random which will block and wait, until entropy is present. This is the reason, why blocking is very unlikely to occur on a production or development machine – however it did happen, when using a virtual machine, which does not have a lot of network traffic and IO. It happens especially often, when you restart an application often – as you tend to do, when something is not working. The fix is a little funny. Java rejects /dev/urandom based on the string. It does not reject /dev/./urandom which of course points to the same potentially unsafe random number generator.Last Words The fix introduces a potential security risk – but on a development virtual machine this is not a problem. As you can see, finding a bug or problem in a system involves to use techniques, which bring you nearer to the root cause. However, there is no golden path. Sometimes one technique will not get you any more information. So you will have to try a different technique. Sometimes your gut feeling might help you as well. Having arrived here, what are your thoughts on the story? Reference: Hunting a Random Bug – A True Story from our JCG partner Johannes Thones at the Johannes Thones blog blog....
apache-maven-logo

Maven Build Number Plugin – Sample Usage

Suppose we need to add a build number to some artifact (jar, war, etc.). Here I’d like to demonstrate the usage of buildnumber-maven-plugin. This post is based on:http://mojo.codehaus.org/buildnumber-maven-plugin/usage.html http://www.site.lalitbhatt.com/maven-build-number-plugin http://blog.peterlynch.ca/2009/11/buildnumber-maven-plugin-helpful.html http://apollo.ucalgary.ca/tlcprojectswiki/index.php/Public/Project_Versioning_-_Best_Practices#Build_VersioningWe have some project and need to include into jar manifest file sequential build number which isn’t based on VCS (SVN, Git, Mercurial, etc.) revision number. Let’s create appropriate pom.xml file and implement small demo to verify the result. Generate maven project $ mvn archetype:generate -DgroupId=org.halyph -DartifactId=buildNoTest\ -DarchetypeArtifactId=maven-archetype-quickstart \ -DinteractiveMode=false Create the pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelversion>4.0.0</modelversion> <groupid>org.halyph</groupid> <artifactid>buildNoTest</artifactid> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>buildNoTest</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <properties> <project.build.sourceencoding>UTF-8</project.build.sourceencoding> </properties> <!-- If you have access to scm then you can place actual url's. Otherwise with <revisionOnScmFailure /> you can give some fake URLs as follows. --> <scm> <connection>scm:svn:http://none</connection> <developerconnection>scm:svn:https://none</developerconnection> <url>scm:svn:https://none</url> </scm> <build> <resources> <resource> <directory>src/main/resources</directory> </resource> <resource> <directory>src/main/filtered-resources</directory> <filtering>true</filtering> </resource> </resources> <plugins> <plugin> <groupid>org.codehaus.mojo</groupid> <artifactid>buildnumber-maven-plugin</artifactid> <version>1.1</version> <executions> <execution> <phase>generate-resources</phase> <goals> <goal>create</goal> </goals> </execution> </executions> <configuration> <!-- doCheck and doUpdate actually talk to repository if it's true, Check would check that there are no local changes. Update would update it --> <docheck>false</docheck> <doupdate>false</doupdate> <!-- This ensures that even if we are not connected to scm than also take the version from local .svn file --> <revisiononscmfailure> <!-- Generate sequence build number based on: build number and timestamp --> <format>Build: #{0} ({1,date})</format> <items> <item>buildNumber\d*</item> <item>timestamp</item> </items> </revisiononscmfailure></configuration> </plugin> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-jar-plugin</artifactid> <version>2.1</version> <configuration> <archive> <!-- will put the entries into META-INF/MANIFEST.MF file --> <manifestentries> <implementation-version>${project.version}</implementation-version> <implementation-build>${buildNumber}</implementation-build> </manifestentries> </archive> </configuration> </plugin> </plugins> </build> </project>Create demo application to verify the results package org.halyph;import java.io.IOException; import java.util.ResourceBundle; import java.util.jar.Attributes; import java.util.jar.Manifest;public class App { public static void main( String[] args ) throws IOException { System.out.println('Verify Resource bundle' ); // Check filtered resources based on generated build number ResourceBundle bundle = ResourceBundle.getBundle( 'build' ); String msg = bundle.getString( 'build.message' ); System.out.println(msg);System.out.println('\nVerify Generated MANIFEST.MF Properties' );// Check Manifest file based on generated build number Manifest mf = new Manifest(); mf.read(Thread.currentThread().getContextClassLoader().getResourceAsStream('META-INF/MANIFEST.MF'));Attributes atts = mf.getMainAttributes();System.out.println('Implementation-Versio: ' + atts.getValue('Implementation-Version')); System.out.println('Implementation-Build: ' + atts.getValue('Implementation-Build')); } }Build application several time and Run $ mvn install $ java -cp target\buildNoTest-1.0-SNAPSHOT.jar org.halyph.App Verify Resource bundle Build: #3 (Jun 27, 2012)Verify Generated MANIFEST.MF Properties Implementation-Versio: 1.0-SNAPSHOT Implementation-Build: Build: #3 (Jun 27, 2012)SummaryWe should inform buildnumber-maven-plugin that we won’t use version control revision as build number via adding fake <scm> section into pom.xml and <revisionOnScmFailure /> into buildnumber-maven-plugin <configuration> Implemented custom build number format, see buildnumber-maven-plugin <configuration>/<format> and <configuration>/<items>. Added build number into jar manifest, see maven-jar-plugin pom.xml section Tested if generated build number can be properly added in filtered resourcescreated src\main\filtered-resources\build.properties file build.message=${buildNumber}added resource filtering, see section <resource> flag <filtering>true</filtering>Demo application verifying the filtered resources and build number in jar manifest fileYou can git clone this project https://github.com/halyph/blog-sandbox/tree/master/Maven/blogpost_062712 Reference: Maven Build Number Plugin – Sample Usage from our JCG partner Orest Ivasiv at the Knowledge Is Everything blog....
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
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:
Close