Javadoc examples: Comments and usage in Eclipse

 IT, Java  Kommentare deaktiviert für Javadoc examples: Comments and usage in Eclipse
Jul 052014
 

Javadoc for java Packages

It is also possible to add a comment / short description of a package. This can be done using a file called package-info.jave inside the package. When using eclipse, you can check the option „Create package-info.java“:

Create package-info.java

Create package-info.java

Change the default comment to something like this. Important: Use only one sentence and don’t forget the point at the end.

Change comment to something like this

Change comment to something like this

This will result in:

Package description

Package description

 

Using Javadoc for classes

To describe classes, you should start with a single sentence at the beginning. This sentence is used on the overview page of a package where all classes are listed (with a short description which is this sentence). Dont forget the point at the end.

The next paragraph contains a more detailed description that will be shown on the detail page of the class. Here you can use some html tags. In this case I used a list. After that you can add some javadoc parameter.

package com.pbo.Game;

/**
 * This Class represents the main class of the F1 Betting Game.
 * <p>
 * This Class handles all the database connection stuff, it creates the GUI
 * and it contains all the rules. See method: displayRules.
 * <br>
 * It also Starts the database connection, create instances of users and rankings and so on.
 * <ul>
 * 		<li>You can also</li>
 * 		<li>use a list</li>
 * 		<li>here in the description of the class</li>
 * </ul>
 * 
 * @author philipp
 * @version 0.1
 */
public class GameStarter {
    // your class here
}

Result of that comment:

Package Overview shows all classes with a short description

Package Overview shows all classes with a short description

 

Overview of one class

Overview of one class

 

Javadoc for methods

To describe methods you should begin with a short description in a single sentence. This sentence will be displayed in the method-overview of the class. After that sentence you should describe your method more detailed. This will be the description of the method. There you can use html-tags like linebreak <br> , lists <ul> , <li>, and more. You can create paragraphs by using the <p> tag. See the example below:

/**
 * This method displays all the rules for the game.
 * <p>
 * Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
 * eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
 * voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
 * clita kasd. <br>
 * Nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
 * sed diam voluptua.
 * <p>
 * Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
 * eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
 * voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
 * clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit.
 * <p>
 * Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
 * eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
 * voluptua dolor sit amet.
 * <ul>
 * <li>Rule 1 ...</li>
 * <li>Rule 2 ...</li>
 * <li>Rule 3 ...</li>
 * </ul>
 * 
 * @param userName
 *            The username of the Player
 * 
 * @param difficulty
 *            The difficulty of the game, from 1 to 10, where 1 is simple
 *            and 10 means strong
 * @return the status code after the game has finished. 1=won, 2=lost
 */
public int displayRules(String userName, int difficulty) {
	// your code goes here
	return 2;
}

Results in:

Javadoc Method Overview

Javadoc Method Overview

and:

Javadoc Method Details

Javadoc Method Details

 

Using javadoc ant task

 IT, Java  Kommentare deaktiviert für Using javadoc ant task
Jul 052014
 

Javadoc is a very powerful and helpful tool of java. You can document your source, as well as insert installation or configuration information. The usage of javadoc in ant is very comfortable, setup once, use every build.
Here is an example of a simple javadoc ant task:

<target name="createJavadoc">
	<!-- this classpath is only necessary when using 3rd party libs or annotation processing -->
	<path id="annotations.classpath">
		<fileset dir=".">
			<include name="lib/**/*.jar" />
		</fileset>
	</path>
	
	<!-- creata javaDoc for package com.pbo.* inside src folder. Store javadoc in folder javaDoc -->
	<javadoc packagenames="com.pbo.*" 
		sourcepath="src" 
		defaultexcludes="yes" 
		destdir="javaDoc" 
		author="true" 
		version="true" 
		use="true" 
		classpathref="annotations.classpath" 
		splitindex="true" 
		nonavbar="true"
		windowtitle="F1 Betting Game : Documentation">
			<doctitle>
				<![CDATA[<h1>F1 Betting Game</h1>]]>
			</doctitle>
		<bottom>
			<![CDATA[Copyright © Philipp Boss.<br/> <b>Please contact Philipp Boss in case of questions</b>]]>
		</bottom>
	</javadoc>
</target>

This task creates the javadoc for the package com.pbo.* inside the src-folder and stores the created doc files inside the javaDoc folder.

The parameter nonavbar hides the navigation bar in the created doc files. For my opinion this generates more „clean“ javadoc pages. The windowtitle is the title of the html-page (what you can see in your browser tab), the doctitle is the one beeing displayed inside the web page. The value of bottom is beeing displayed at the end of the page.

Here you can see the created page:

Javadoc created Webpage

Javadoc created Webpage

Configure ActiveMQ Web console for password secured broker / Queues

 IT, Java  Kommentare deaktiviert für Configure ActiveMQ Web console for password secured broker / Queues
Aug 162013
 

In my last post about ActiveMQ I showed how to configure ActiveMQ in order to secure the Queues by Username and Password.

In the last days I noticed, that the web console throws an exception when I try to click on one of the queues. I realized, that the webconsole couldn’t open the queue because it is password protected.

In the logfile there was an exception like this (see the bold words):

2013-08-15 17:09:23,486 | WARN  | Failed to add Connection ID:PBOSS-56722-1376579349017-3:1, reason: java.lang.SecurityException: User name [system] or password is invalid. | org.apache.activemq.broker.TransportConnection | ActiveMQ VMTransport: vm://localhost#1-1
2013-08-15 17:09:23,489 | INFO  | Connector vm://localhost Stopped | org.apache.activemq.broker.TransportConnector | qtp2024674927-37
2013-08-15 17:09:23,490 | WARN  | /admin/browse.jsp | org.eclipse.jetty.servlet.ServletHandler | qtp2024674927-37
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‚queueBrowser‘ defined in ServletContext resource [/WEB-INF/webconsole-query.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.apache.activemq.web.QueueBrowseQuery]: Constructor threw exception; nested exception is javax.jms.JMSException: User name [system] or password is invalid.

Ok, now we see, that the web console seems to use the username „system“ by default. But in my configuration the queues are secured by „superman“ and „boss“. So I have to „tell“ the web console this information. You can define that in the file: <activemq-home>/conf/credential.properties:

#this is the queue User
activemq.username=supermann
#this is the queue password
activemq.password=boss

Now you have to restart MQ and the web console will work fine 🙂

ActiveMQ Simple Authentication for Consumers and Producers

 IT, Java  Kommentare deaktiviert für ActiveMQ Simple Authentication for Consumers and Producers
Jul 032013
 

By default, ActiveMQ does not request a Username or password for consumers and producers. That means, everyone who knows your broker URL is able to connect to your broker and read your messages and/or send messages. For personal development this isn’t a big issue, but for business applications security plays an important role.

Because of that, I have played around with the authentication of consumers and producers on ActiveMQ brokers.

First of all you should know, that ActiveMQ supports a users and groups based authentication.In our example we would like to have two groups:

  • senders: they are allowed to send messages into queues (write access)
  • receivers: they are allowed to consume the messages (read access)

Setup groups and users for Receiver and Consumer:

To setup those two groups and one user for each group you have to add these lines (starting with „plugins“)  to your activemq.xml :

ATTENTION:  in earlier versions (I tested it also with 5.5.1) you have to insert the plugins-element in the correct alphabetical order. See also: http://activemq.apache.org/xml-reference.html –> Alphabetically ordered xml elements (5.4 – 5.5.1)

    <!--
        The <broker> element is used to configure the ActiveMQ broker.
    -->
    <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">

      <plugins>
        <simpleAuthenticationPlugin>
            <users>
                <authenticationUser username="superman" password="boss" groups="senders,receivers,admins" />
                <authenticationUser username="mySendingApp" password="manager" groups="senders" />
                <authenticationUser username="myReceivingApp" password="manager" groups="receivers" />
            </users>
        </simpleAuthenticationPlugin>
      </plugins>

Link groups and users to queues and topics

After that you need to grant rights to the created groups „senders“ , „receivers“ and „admins“. Add the following lines after the closing </simpleAuthenticationPlugin> tag:

<authorizationPlugin>
   <map>
       <authorizationMap>
           <authorizationEntries>
               <authorizationEntry queue=">" write="senders" read="receivers" admin="admins" />
	       <authorizationEntry topic="ActiveMQ.Advisory.>" write="senders" read="receivers" admin="admins,senders,receivers" />
           </authorizationEntries>
       </authorizationMap>
   </map>
</authorizationPlugin>

Explanation: You can specify different access rights for the single queues. In my example I allow all users from group „senders“ to write inside all queues. queue=“>“ stands for all queues. ActiveMQ uses the „>“ as Wildcard (see also the website-link below). Also I allow all receivers to read from the queue.

Maybe you are wondering about the second <authorizationEntry> . ActiveMQ-Clients creating Advisory-Topics for several reasons. For each queue a client connects to, the client tries to create a Advisory-Topic. That is the reason why I added the second line. This line defines that all clients (with correct password and username) are able to create Topics that are named „ActiveMQ.Advisory.*“.  More about ActiveMQs advisory stuff see website link below.

Now you can restart the ActiveMQ broker in order to read the new configuration.

Client side: connect to a username/password protected queue

Now we have to setup the client side to connect to a secured broker. The ConnectionFactory class provides a method called „createConnection“. There is an overloaded method of this: createConnection(String arg1 , String arg2) where arg1 is the username and arg2 is the password.

Here a short example for a listener connecting to a secured broker:

public void startListener() throws NamingException, JMSException, InterruptedException {

	// Create a JNDI API InitialContext object
	Properties props = new Properties();
	props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
	props.setProperty(Context.PROVIDER_URL, "tcp://" + server + ":61616");

	jndiContext = new InitialContext(props);
	connectionFactory = (ConnectionFactory) jndiContext.lookup("ConnectionFactory");
	destination = (Destination) jndiContext.lookup("dynamicQueues/" + queueName);

	// Connect to ActiveMQ
	connection = connectionFactory.createConnection(username, password);
	connection.setClientID(clientID);
	// this helps to ensure, that not 2 instances can connect to the broker simultaneously
	// because it is not allowed to connect to the same broker with the same clientID
	connection.start();
	session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

	MessageConsumer subscriber = session.createConsumer(destination);
	subscriber.setMessageListener(new MessageListener() {

		@Override
		public void onMessage(Message msg) {
			try {
				System.out.println("Message arrived by consumer-ID : " + clientID + " CONTENT = " + ((TextMessage) msg).getText());
			} catch (JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	});

	for (int i = 0; i &lt; 100; i++) {
		System.out.println("still alive .... " + i);
		Thread.sleep(10 * 1000);
	}
}

 

Have fun with simple secured JMS 😉

——————————————————————

Sources / Websites:

ActiveMQ Wildcards: http://activemq.apache.org/wildcards.html

ActiveMQ Sample Borker Config for secured JMS Connections: http://activemq.apache.org/complex-single-broker-configuration-stomp-only.html

ActiveMQ Advisory Topics: http://activemq.apache.org/advisory-message.html

Java API for ConnectionFactory:  http://docs.oracle.com/javaee/1.4/api/javax/jms/ConnectionFactory.html

 

Java Serialization – Example

 IT, Java  Kommentare deaktiviert für Java Serialization – Example
Mai 212013
 

First create an object that you want to store persistently (serialize). I use the object „Car“. Please ensure that your class implements the interface Serializable

package com.philipp.testing;

import java.io.Serializable;

public class Car implements Serializable {

	public enum Brand {
		BMW, Mercedes, Porsche, Audi
	};

	private Brand brand;
	private String model = "";
	private int hoursepower = 0;
	private int price = 0;

	public Car(Brand brand, String model, int hoursepower, int price) {
		super();
		this.brand = brand;
		this.model = model;
		this.hoursepower = hoursepower;
		this.price = price;
	}

	public Brand getBrand() {
		return brand;
	}

	// removed some "Getter" and "Setter" for this example..

	public void setPrice(int price) {
		this.price = price;
	}

}

Now create a „testing“ class that will create a new car and serializes it:

package com.philipp.testing;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import com.philipp.testing.Car.Brand;

public class testingTheSerialization {

	public static void main(String[] args) {

		// create a new Car
		Car myCar = new Car(Brand.Porsche, "911 Carrera S", 400, 20000);

		// now store the car in a file (serialize it):
		System.out.println("Serialize the car to file myCar.file");
		doSerialize(myCar);
		System.out.println("Serialization done");

		// now try to read the file and parse the object to a new car:
		Car myCarFromFile = null;
		myCarFromFile  =  (Car) doDeSerialize("myCar.file");
		System.out.println("Your car is: " + myCarFromFile.getBrand() +  " - " + 
								myCarFromFile.getModel() + " - " +
								myCarFromFile.getHoursepower() + "hourspower - " + 
								myCarFromFile.getPrice() + "Euro");

		System.out.println("Deserialization done...");

	}

	public static void doSerialize(Car myCar){
		FileOutputStream fos;
		try {
			fos = new FileOutputStream(new File("myCar.file"));
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			oos.writeObject(myCar);
			oos.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Uuups, something went wrong: " + e.getLocalizedMessage());
		}

	}

	public static Car doDeSerialize(String filename){
		Car myCar = null;
		try {
			FileInputStream fis = new FileInputStream(new File(filename));
			ObjectInputStream ois = new ObjectInputStream(fis);
			myCar = (Car) ois.readObject();
			ois.close();
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
			System.out.println("Uuups, something went wrong: " + e.getLocalizedMessage());
		}

		return myCar;
	}
}

The Output of this example is:

Serialize the car to file myCar.file
Serialization done
Your car is: Porsche - 911 Carrera S - 400hourspower - 20000Euro
Deserialization done...

And a file „myCar.file“ was created in your working directory.