Yakov Fain's Blog

My notes about everything in IT

Tic-Tac-Toe in JavaFX

with 7 comments

Finished writing the JavaFX chapters for the second edition of my Java 24 Hour Trainer. It included a sample code of the Tic-Tac-Toe game. The front end is done in FXML and the application logic is written in Java.

fig_19_18

Using FXML allows to substantially minimize the amount of Java code. This application has 200 lines of code, namely:

Tic-Tac-Toe.fxml: 45 lines
Main.java: 27 lines
TicTacToeContoller.java: 118 lines
application.css: 12 lines.

The FXML and CSS files can be created and modified by people who do not know Java at all (i.e. graphic designers). I haven’t implemented a couple of menus, which would add a couple of dozens lines to the code base. Pretty concise, isn’t it? The source code of the Tic-Tac-Toe project is available among other code samples at https://github.com/yfain/java24hourtrainer2ndedition. I’ve developed this in Eclipse IDE with the E(fx)clipse plugin that generated an initial project for me. At the time of this writing NetBeans 8 IDE has the best support of JavaFX followed by IntelliJ IDEA 14, and then goes Eclipse with E(fx)clipse plugin.

Written by Yakov Fain

November 20, 2014 at 6:22 am

Posted in java

Tagged with ,

Have you shortened your talk yet?

with one comment

Attention span is getting shorter and shorter. At least mine. I can’t do the same thing for 50 minutes straight, can you? Books became thinner. In the past getting a 1500-page book on programming for $40 would be considered a good deal. Now people don’t want to buy books that have more than 500 pages. In my recent book project the publisher decided to not include a 60-page chapter in the printed version, but offered it as a free online bonus chapter. The chapter content was good, but marketers said that thinner books sell better.

IT conferences should follow the same trend. 50-minute presentations are so last century! Some conferences include ignite talks. They last 5-10 minutes, and ideally, the slides should be flipped automatically to force presenters stay focused. This is called Pecha Kucha.

I can share a secret with you: I can deliver a 50-min presentation in 25 min. Or in 15. Or in 5. Just tell me how much time I have, and I’ll remove the irrelevant content. It’s like extracting juice concentrate.

Shorter presentations would require better concentration not only from the speakers, but from the audience as well. There is no time for checking emails, tweets, or reading the news. As a matter of fact, the conference organizers wouldn’t need to pay outrageous amounts of money for providing this flaky Wi-Fi connections for the audience. No time for Internet browsing.

A typical IT conference runs for 3-4 days averaging 7 presentation slots per track daily. What if each presentation would run for half the time – 25 minutes? A rare conference would run for more than two days. This translates into cost savings for both conference organizers and those who pays for a trip to the conference. For those who who are not in the know, I have another secret to share. Remember that airline-quality lunch that you got for free? The conference organizers paid anywhere from $50 to a $100 for each plate.

Can software developers absorb 14 presentations a day? Yes, we can. But realistically, none of the conferences can offer 14 interesting presentation a day. Except one. TED. BTW, I don’t remember ever watching a TED presentation that was longer than 25 minutes, and they were all great!

Can IT conferences follow the leader? Yes they can. Last month I was participating in the HTML5Dev/IOTA conference in San Francisco. Take a look at the schedule. It was based on 20-min slots. But if a speaker wanted to talk for 50, he would get 2 slots + 10 minute break. It worked like charm.

Pretty often attendees find themselves in a wrong auditorium after the first 5 minutes into the talk. Some of them are shy to simply walk out. 50 minutes of their time wasted. If the presentations were shorter, they would have wasted only 20 minutes!

Anyway, this blog is getting too long too, but as someone said, “Sorry, I din’t have time to write you a shorter letter”.

Written by Yakov Fain

November 13, 2014 at 1:43 pm

Posted in java

IT book publishers may extinct soon

with 3 comments

Not sure how IT book publishers can survive these days. People are intoxicated with free content. During American Civil War soldiers were bringing liquor to the camps by hiding it in their boots (a.k.a. boot-legging). But this is the ancient history of America. With soft media, there is no need to hide anything in the boots. You can find almost any content online for free. I’ll give you one of the examples that directly relates to me.

After spending lots and lots of hours writing the book “Enterprise Web Development”, preparing code samples and going through several rounds of editing, the book is finally in print. Lots of people besides the authors were involved in the process. During the entire process the drafts of the all chapters were available online for free. Thank you O’Reilly Media! The idea was to build a community while the book is being worked on.

Now the book is printed. Booksellers get it from the publisher for about 50% of the list price. The publisher paid the authors an advance, which is ours to keep even if not a single copy of the book is sold. The publisher takes a risk. If the book sells well, the author(s) will get a dollar or two in royalties for each sold copy. We’ll split the royalties for this book (if any) between four coauthors, so it’s clearly a not-for-profit project for us. Now check this out:

freebooks

Two thousands of free downloads just at this pirate site. It’s great for the authors that the book is popular. All authors are working programmers, and our income doesn’t depend on book sales. But this book is a good PR for us and our company (all work for Farata Systems). Read the book, and hire us for your next consulting project! Book writing worked for us really well so far. Our company exists since 2006 and we never had even a single salesman. PR works. It sounds like a paradox, but the more bootlegged copies will be distributed, the better it is for us!

But what about the publishers? How they are supposed to make a living? I simply don’t know. It’s sad to see how the IT sections in the bookstores are shrinking, but this trend will continue.

Written by Yakov Fain

November 11, 2014 at 10:16 pm

Posted in java

Programming to Interfaces in Java

leave a comment »

Seasoned Java programmers are programming to interfaces. What does it means?

Let’s consider a simple example. Let’s say I’ve declared a variable customers of type ArrayList:

ArrayList<Customer> customers = new ArrayList<>(3);

While this code is correct,  there a better way of declaring the variable customers:

List<Customer> customers = new ArrayList(3);

You can read the first example as follows: “I want to declare a variable customers that will have all access to all API offered by the class ArrayList“. The second version means the following: “I want to declare a variable customers that has a behavior declared in the List interface”. The first example declares a variable of a specific implementation of the List interface – ArrayList. Now rake a look at this code example:

ArrayList<Customer> customers = new ArrayList<>(3);

// The code to populate customers with instances of 
// Customer is omitted for brevity

int totalElem = customers.size();

// Iterate through the list customers and do something with each
// element of this collection

for (int i=0; i<totalElem;i++){
    Customer currentCustomer= customers.get(i);
    System.out.println(currentCustomer);
  }
}

ArrayList implements several interfaces besides List, which means that it has more methods that the List defines.  But if you read the documentation on the List interface, you’ll see that among others it includes the methods as add(), get(), and size() , which are the only ones used with our collection customers. If this is all we need, declaring a variable customers of type List gives us more flexibility. If later we decide to switch to a different implementation of the List (e.g. LinkedList instead of ArrayList ) we won’t need to change the type of the variable customers.

You may say that changing a variable declaration from ArrayList to LinkedList it’s not a big deal – it’s still the same line of code. But it may be a bigger deal if, say you program needs to pass the object referred by customers to another object’s method that also was declared with the argument of type ArrayList:

processCustomers (ArrayList<Customer> customers){

...
}

Now we need to change both the variable and the method argument declarations . In large projects such a refactoring may become a time consuming process.

If you just need a behavior defined in a particular interface (e.g. List), declare the variable of this interface type rather than of a concrete implementation (e.g. ArrayList) of this interface.

P.S. Here’s the Java 8 way of writing the above loop, which is not relevant for the blog subject:

customers.forEach( customer -> System.out.println(customer));

Written by Yakov Fain

October 26, 2014 at 2:34 am

Posted in java

Tagged with

Java Programmers-Terrorists

with 5 comments

Java has a pretty powerful mechanism of error handling. But sometime programmers ignore it. Recently I’ve seen the following post in one of the production support chat rooms:

Developers, please don’t do this:

 } catch (IOException e) {
     //do nothing, just ignore it
 } finally {

this is better:

 } catch (IOException e) {
      logger.error(e,e);
 } finally {

The poster of this message has demonstrated what being overly polite means. I’m not as polite as the guy who wrote this and want to say that Java developers who quietly ignore exceptions should be tracked down and fired. They can be considered terrorists who plant time bombs into applications.

Handling programming errors is a must. Writing an empty catch clause is the worst thing that could be done. It’s like a time bomb that will definitely blow the program up one day, and finding such bombs is usually a time consuming process. Some people want to save a couple of seconds required to log the error, which eventually will cost dearly to the QA and support teams. Don’t cut corners, exception handling should be taken very seriously if you consider yourself a professional software developer.

Written by Yakov Fain

October 24, 2014 at 4:01 pm

Posted in java

Tagged with

Java is short for JavaScript. Not!

with one comment

Here’s  is a quote from the About page  of the Web site ehow.com: “eHow is your one-stop online resource for life’s challenges. Professionals in every field come together to offer expert advice, backed by the additional support of a can-do eHow community.

Experts are also human beings and sometimes they make mistakes too. But when I’ve read the following article I was stunned:

javaisjavas

Guys and girls, I’m not an eHow-grade expert, but I’ve been doing both Java and JavaScript for while. Trust me, the above description is absolutely wrong! Please ignore. Also, if you know any of the 35 people who found this helpful, get in touch with them and tell them the truth!

There is well known statement that “Java is to JavaScript as ham is to hamster”. So I’m looking forward to a new article at eHow that will be a creative interpretation of the Wikipedia definition:

“Hamster, aslo known as ham for short, is processed pork foodstuff, which undergoes preservation through curing, smoking, or salting. Hamsters are traditionally made only from the hind leg of swine, and referred to that specific cut of pork.”

Written by Yakov Fain

October 12, 2014 at 2:18 pm

Posted in java

Tagged with ,

GlassFish, Open MQ, and the Ear-Eye Problem

with one comment

Yesterday I’ve been updating code examples for the messaging chapter for the 2nd edition of my Java book. While doing this, I ran into an issue, then fixed it, but the cause and the solution illustrate the situation that we call “Ear-Eye”, which comes from and old joke popular in the USSR, where TV propaganda was stating that everything is great while people had hard time finding food in store. Here’s the joke:

An old lady comes to a medical center saying that she needs to see an Ear-Eye specialist. The receptionist replied, “There is no such specialization in medicine. Why would you need such a doctor?” The old lady answered, “What I hear on the radio, I don’t see in the real life.”

In programming, we have similar situations quite often – you look at the code everything looks perfect, but it doesn’t work no matter how long you look at it. In such cases you should call a colleague simply saying “I got an Ear-Eye problem”. An extra pair of eyes usually helps. After looking at the monitor for half an hour, I realized that I got an Ear-Eye situation, but it was not a one piece of code, but required a two server setup so it was not a quick thing for explain to a colleague. Eventually, I fixed it myself and am happy to share my story with you.

I’ve been using Java GlassFish 4.1 as an application server, and Open MQ 5.1 as a JMS provider. You can use Open MQ separately, but it’s conveniently bundled with GlassFish. While most of the JMS code samples show how to send/receive messages from Java EE clients using JNDI, it may give novice Java developers a false feeling that this is the only way to do messaging.

So I updated my old code samples to illustrate how to use JMS 2.0 goodies in standalone clients talking directly to Open MQ server. Started Open MQ from the command line with the imqbrokerd script, configured the queue, tested the sender and receiver and all worked as the doctor ordered (no, not that doctor). For those, who are not in the know, Open MQ runs on port 7676 by default. Here’s my standalone JMS sender:

public class DirectMessageSender{
 public static void main(String[] args){

   ConnectionFactory factory;
	 
   factory = new com.sun.messaging.ConnectionFactory();  

	try( JMSContext context = factory.createContext("admin","admin")){

		factory.setProperty(ConnectionConfiguration.imqAddressList,
                                        "mq://127.0.0.1:7676,mq://127.0.0.1:7676");
		      Destination ordersQueue = context.createQueue("TradingOrdersQueue");	  
	          JMSProducer producer = context.createProducer();
	      
	          // Send msg to buy 200 shares of IBM at market price	      
	          producer.send(ordersQueue,"IBM 200 Mkt");
	          
	          System.out.println("Placed an order to TradingOrdersQueue");
	                    
	 } catch (JMSException e){
	           System.out.println("Error: " + e.getMessage());
	 } 
 }		
}

And this is the standalone receiver:

public class DirectObjectMessageReceiver implements MessageListener{

	ConnectionFactory factory = new com.sun.messaging.ConnectionFactory();  
	JMSConsumer consumer;
	
	DirectObjectMessageReceiver(){
		try( JMSContext context = factory.createContext("admin","admin")){
			factory.setProperty(ConnectionConfiguration.imqAddressList(
                               "mq://127.0.0.1:7676,mq://127.0.0.1:7676");
		    
			Destination ordersQueue = context.createQueue("TradingOrdersQueue");	  	        
			consumer = context.createConsumer(ordersQueue);
		    
			consumer.setMessageListener(this);
		      
		      System.out.println("Listening to the TradingOrdersQueue...");
		      
		      // Keep the program running - wait for messages
		      Thread.sleep(100000);
		    
		   } catch (InterruptedException e){
	           System.out.println("Error: " + e.getMessage());
	       }
		    catch (JMSException e){
		           System.out.println("Error: " + e.getMessage());
		    } 
	}

    public void onMessage(Message msg){
    	
      try{
       System.out.println("Got the message from TradingOrdersQueue: " +
                          msg.getBody(Order.class));
       
       System.out.println("\n === Here's what toString() on the message prints \n" + msg);
       
      } catch (JMSException e){
    	  System.err.println("JMSException: " + e.toString());
      }
    }

 public static void main(String[] args){
	  new DirectObjectMessageReceiver();
 }	 
}

As you see, the code is has several lines specific to Open MQ implementation, which is not great, but gives me a segway to explain the benefits of JNDI and resource injection. Then I explained how to map GlassFish JNDI queue name to a physical queue in the Open MQ server. So here’s the servlet that serves as a JMS sender, and the JNDI name OutgoingTradeOrders is mapped to a physical queue named TradingOrdersQueue.

@WebServlet("/MessageSenderServlet")
public class MessageSenderServlet extends HttpServlet {
	
	  @Resource(lookup ="java:comp/DefaultJMSConnectionFactory")  // JNDI name
	  ConnectionFactory factory;
	  
	  @Resource(lookup = "OutgoingTradeOrders")  // JNDI name
	  Destination ordersQueue;

	  
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
			  throws ServletException, IOException{	
		
		try( JMSContext context = factory.createContext("admin","admin")){
  
		   JMSProducer producer = context.createProducer();
		      
		   // Send msg to buy 200 shares of IBM at market price	      
		   producer.send(ordersQueue,"IBM 200 Mkt");
		          
		   System.out.println("Placed an order to OutgoingTradeOrders");
	  }
	}
}

Got my Open MQ server running, then deployed the servlet and started GlassFish. The servlet obediently sent a message to the queue OutgoingTradeOrders. Basically, I wanted to implement the following workflow:

figure_30-10

The rest seemed to be easy – I wanted to run my standalone message receiver against the Open MQ server to prove that it’s getting messages from TradingOrdersQueue. Started the receiver, it printed “Listening to the TradingOrdersQueue…” and nothing else. Where is the message that the servlet sent? Is there something wrong with the queue names mapping? Started the Open MQ admin console – looks good, the TradingOrdersQueue is there. Started GlassFish Admin Tool – the OutgoingTradeOrders is properly mapped to TradingOrdersQueue.

Then I decided run the servlet again to send a second message to the queue. Maybe the first message got stuck somewhere and the second one would push it out? Nope, no miracles. Tested again the standalone sender and the receiver – work fine. But where are the servlet’s messages?

What would you do in this situation? Correct, it’s time to take a peek into the queue from the servlet’s code to see if is anybody there. Added QueueBrowser to the servlet, which properly showed me the messages sent by the servlet – they were sitting nicely next to each other in the OutgoingTradeOrders queue. Man!

Added the QueueBrowser to the standalone message receiver – the TradingOrdersQueue is empty. What next? I knew this was an Ear-Eye case, but still it would be nice if I could have blamed someone, wouldn’t it? Should I open a ticket at the GlassFish JIRA? Or is it an issue of Open MQ?

Later. I decided to walk my doggy (his name is Sammy) out. During the walk I was thinking about that case when two group of workers started building a tunnel from both sides of the river hoping to meet in the middle, but built two tunnels instead. When I came back, I decided to see if there is something fishy with the port numbers.

I have the only distribution of GlassFish which has the only subdirectory called mq, where the Open MQ software resides. So in both cases (imqbrokerd and GlassFish) I’d be starting the same instance of the Open MQ server, right? Wrong! While imqbrokerd starts it on port 7676, GlassFish start the embedded OpenMQ on port 27676, which is not written in their admin guides. If found a system variable JMS_PROVIDER_PORT deep inside in the GlassFish file glassfish/domains/domain1/config/domain.xml!

This was a situation with tho tunnels! The standalone clients were sending messages to the server running on port 7676, while the servlet was pumping messages to the Open MQ instance running on the port 27676! After changing the port from 277676 to 7676 everything started working!

I would have caught this bug a lot faster, but the GlassFish Admin console was showing me the physical queue TradingOrderQueue that I configured on the server running on port 7676! That’s why I was sure that I was working with the only instance of Open MQ. This is clearly a design flow in the GlassFish Admin Console – instead of showing the physical queues by actually connecting to the Open MQ server, they just read if from the config file.

Anyway, the Ear-Eye issue is resolved. That’s all folks.

Written by Yakov Fain

October 9, 2014 at 9:05 pm

Posted in java

Follow

Get every new post delivered to your Inbox.

Join 151 other followers