Managing Authentication in Tomcat with JDBC Realms

After few times ago, we have used session to managing authorization for accessing Jsp pages, now let’s try to make another authentication for a web application by using Realms.

On Apache or any similar web server, we use Realms authentication by include a file called .htaccess to a directory, so only the listed users can access the content of those directory.

Just like the Apache, Realm is a feature of Tomcat which handles an authentication for the user who would like to access all the resources on a web application. Realm controls the roles of each listed user, these roles are references for tomcat to rule out which users can access which web application. By default Realms is flexibility supported by Tomcat. This flexibility mean is Tomcat is supporting this authentication with several ways that we can use as use as we like. The Realms authentication methods already supported by Tomcat are:

  1. File based authentication (The Memory Realms). With this method, the authentication processed by reading a file called tomcat-users.xml that exist on <Tomcat-Folder>/conf/tomcat-users.xml, this file contains a list of users with their roles.
  2. Database (JDBC) authentication(The JDBC Realms). This method is using database as storage of user list and its roles. On Tomcat 5.5, by default, there’s a few database software which is already supported for this JDBC Realms methods. In order to use this method we have to install the database connector by copying the database connector library such as mysql-connector.jar onto <Tomcat-Folder>/common/lib/.
  3. JNDI authentication (JNDI Realms). On this authentication method, Tomcat will validate user and its roles by reading the web directoryservice, such as LDAP. When using this authentication method the JNDI providers have to installed to Tomcat by copying the libraries on to <Tomcat-Folder>/common/lib/ folder.

From those above Realms authentication, we will try the second method which is Database (JDBC) authentication(The JDBC Realms) as out try-it-out now. We will use mysql database as storage of users list and its roles. While the scenarios of our try-it-out today are bellows:

  • Create a database as a storage which can hold users list and its roles.

  • Create a mysql username and password, this username is dedicated for a database that we have created on first step, and this username only had read privileges.

  • Activate Realm JDBC configuration on Tomcat.

  • Create web application configuration in order to make this web application support Realms.

On above scenarios, actually we only do once from step 1 to step 3, means the configuration from step 1 to step 3 will became permanent on Tomcat environment. While the step 4 is optional, means every web application that we will deploy later is may to use this Realm authentication, and may not use too, so it’s depends on us to decide whether a web application will using Realm authentication or not. And then if we want to add user with its roles, so the modification will only do inside mysql database.

And now let’s run out one by one the scenarios above. For the first scenario, please create a database and its tables on mysql database, just like mysql query bellows:

create database tomcat_server;
use tomcat_server;
-- Table structure for table `user_auth` --
CREATE TABLE IF NOT EXISTS `user_auth`
  ( `USERNAME` varchar(30) NOT NULL default '',
  `PASSWORD` varchar(30) NOT NULL default '',
   PRIMARY KEY (`USERNAME`) )
ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- Dumping data for table `user_auth` --
INSERT INTO `user_auth` (`USERNAME`, `PASSWORD`) VALUES ('admin', 'admin99'), ('mojo', '7mono7');
-- Table structure for table `user_role` --
CREATE TABLE IF NOT EXISTS `user_role`
  ( `ROLE_NAME` varchar(30) NOT NULL,
    `USERNAME` varchar(30) NOT NULL )
    ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- Dumping data for table `user_role` --
INSERT INTO `user_role` (`ROLE_NAME`, `USERNAME`) VALUES ('tomcat', 'mojo'), ('manager', 'admin'), ('admin', 'admin');

These Query, can also directly executed by copy-paste onto mysl console, just remember the database, tables, users, and roles for the next configuration or scenarios.

Let’s continue with the 2nd scenario which is creating dedicated mysql username and password which only have read only privileges access. Why read-only privileges access? Because we have to be careful to give an access privileges on database user, especially the context of this Realms is related with the access of our whole web application. For this 2nd scenario, these is only my suggestion, but if you want to make a database user with more access privileges than this scenario for your next development, go a head (All by your own risk). Below is a sample query which can accommodate the 2nd scenario.

grant select on tomcat_server.* to 'tomcat-user'@'localhost' identified by 'tomcat55';

On above query, we make a user named tomcat-user and the password is tomcat55, grant select is a command of mysql database that this user have the read-only access to tomcat_server database.

And then let’s continue to the 3rd scenario, which in this scenario, we will activate the Realm configuration with JDBC methods on Tomcat. Realm configuration placed on servlet.xml file which is located on <Tomcat-Folder>/conf/ folder. So we have to modify this file in order to activate Realm with JDBC method. There are two steps to do in this 2nd scenario. The steps are:

  1. Activate Realm Configuration.

    Find and modify the servlet.xml just like bellow:

    <Realm className="org.apache.catalina.realm.UserDatabaseRealm" 
          resourceName="UserDatabase"/>
  2. Activate and modify the JDBC Realm configuration refers to 1st scenario that we did before. Modify the server.xml file just like below:

     <Realm className="org.apache.catalina.realm.JDBCRealm" 
               driverName="com.mysql.jdbc.Driver" 
               connectionURL="jdbc:mysql://localhost/tomcat_server" 
               connectionName="tomcat" connectionPassword="tomcat55" 
               userTable="user_auth" userNameCol="USERNAME" 
               userCredCol="PASSWORD" userRoleTable="user_role" 
               roleNameCol="ROLE_NAME" /> 

    Lets discuss a bit for our review of above configuration, in this configuration we are using com.mysql.jdbc.Driver for mysql-connector driver, and the we are using tomcat as a name for database username and for the database password we are using tomcat55 to create connection into mysql database as we have created before on the previous scenarios. Please make sure that the value on this configuration is correct as we create the data on database at the previous scenario.

And then now we can run 4th scenario which is applying JDBC Realms authentication to our web application. Just create or use the existed web application to applying this Realms authentication. We can apply this Realms Authentication by modifying web.xml file which is located on <Tomcat-Folder>/webapps/<your’s-application>/WEB-INF/ folder.

The modification can be do by adding few lines just like below on our web.xml file:


<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://java.sun.com/xml/ns/javaee" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
            http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
            version="2.5"> 
<!--Access Configuration based on Realms--> 
   <security-constraint> 
      <web-resource-collection> 
         <web-resource-name>All Page</web-resource-name> 
         <url-pattern>/*</url-pattern> 
      </web-resource-collection> 
      <auth-constraint> 
         <role-name>tomcat</role-name> 
      </auth-constraint> 
   </security-constraint> 

   <login-config> 
      <auth-method>BASIC</auth-method> 
      <Realm-name>Tomcat-Advance-Authentication-Realm</Realm-name> 
   </login-config> 
    ... 
    ... 
<web-apps> 

On those lines above, all the authentication will be applied to whole resources on this web application, marked by line <url-pattern>/*</url-pattern>, and then for the authorization methods we are using BASIC.

That’s all, our try-it-out, using JDBC Realm on Tomcat as a validation for user to our web application resources. Please don’t you ever have a doubt to more explore for your own need and your own desires.

Thanks.

Menteng, Januari 26th 2008.

Josescalia.

Advertisements

Few Tips and Trick on Jsp and Servlet

On a web technology development using java programming language, we knew Servlet and Jsp. Servlet and Jsp came as presentation layer of a web application structure. Presentation layer is a layer which has responsibility to present view of processing result as the end of data flow process. When choosing servlet or jsp as a presentation layer, there’s must be some proper and suitable consideration referred to the purpose

Even though it’s just a presentation layer on a web application, Servlet and Jsp are also have some interest things to explore and use on our web application. Below are some tips and tricks which can be used on a Servlet and Jsp.

  1. Get parameter value from deployment descriptor(web.xml) using init Servlet method.

  2. Chek out this codes:

    public class SendMailServlet extends HttpServlet {
        private String smtpHost;
    
      public void init(ServletConfig config) throws ServletException {
        super.init(config);
        smtpHost = config.getInitParameter("smtpHost");
      }
     …………………………
    }
    

    Above code is a sample of a Send mail Servlet application. The process of send mail, must be need a SMTP Host as a server to send email in order to make email can be received to whom its send. In order to preventing hard-code, SMTP host name put it on a deployment descriptor (web.xml), so if there’s a change of a SMTP host name we don’t need to recode the source, recompile and redeploy the application, what we do is only change the value of a smtpHost parameter on web.xml and the application can run normally with a little modification.

    And of course below is cut code of a web.xml where the value of this parameter defined.

    <servlet>
            <servlet-name>sendMessage</servlet-name>
            <servlet-class>org.mojo.mail.web.servlet.SendMailServlet</servlet-class>
            <init-param>
                <param-name>smtpHost</param-name>
                <param-value>smtp.speed.net.id</param-value>
            </init-param>
    </servlet>
    

    And for the process flow are, when the first time this Servlet initialized and the application server will call the init method on this Servlet, and then this method will fill up the smtpHost variable with the value taken from the deployment descriptor where the Servlet defined.

  3. Using RequestDispatcher Interface to throw a process to another servlet.

  4. Its become an interesting chosen, when we made a scenario that each servlet will handling each different task. Such as there’s a Servlet which only handle send mail process, or a Servlet which only handle displaying error message, etc. with this type of scenario, we will be able to trace error, that’s possible to happen on a process flow, because each process have a different module.

    With this kind of scenario, we must need a throw of a process from one servlet to another servlet.To throw a process from one servlet to another servlet, we can use a RequestDispatcher interace. Chek out these codes:

    public class Test1Servlet extends HttpServlet{
    
         public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
            System.out.println("doGetInvoked");
            throwToServlet(req, res);
           }
        public void doPost(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
            System.out.println("doPost Invoked");
            throwToServlet(req,res);
           }
        private void throwToServlet(HttpServletRequest req, HttpServletResponse res)
             throws IOException, ServletException {
            System.out.println("This Process wil throw to another servlet");
            RequestDispatcher rd = getServletContext().getNamedDispatcher("Test2");
            rd.forward(req,res);
          }
    }
    

    On above servlet class codes we can see there’s a line

    RequestDispatcher rd = getServletContext().getNamedDispatcher(“Test2”);

    This line is a line where the servlet will get ServletContext that declared on web.xml, and this line followed by below line

    rd.forward(req,res);

    and this line is a line which telling the application to throw a process to another servlet named Test2.

    Practically, don’t forget to add servlet Test2 definition on web.xml

    And if we want to throw the process flow to another servlet, but the thrown came from jsp, we do little modification of the line, so the changes will be look like below:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%
      RequestDispatcher rd = getServletConfig().getServletContext().getNamedDispatcher("Test2");
      rd.forward(request,response);
    %>
    

    There’s an addition of a getServletConfig methods on initialized line of RequestDispatcher interface, and for the parameter of forward method is fill up with request and response that default on jsp class.

  5. Using sendRedirect method to throw a process to another URL.

    If on 2nd trick we used RequestDispatcher interface to throw a process to another servlet, in this trick we will use sendRedirect method to throw a process to another URL. The differences about this trick with 2nd trick is the 2nd trick only throw a process to a servlet that located at the same web-app context, while this trick it’s not just throwing a process to same web-app context but also throw using cross URL or different URL.

    To throw a process to another URL, please take a look below codes:

    public class Test1Servlet extends HttpServlet{
    
         public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
            System.out.println("doGetInvoked");
            throwToURL(req,res);
           }
        public void doPost(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
            System.out.println("doPost Invoked");
            throwToURL(req,res);
           }
         private void throwToURL (HttpServletRequest req, HttpServletResponse res)
             throws IOException, ServletException {
            System.out.println("This Process wil throw to another URL");
            res.sendRedirect("Test2");
          }
    }
    

    On the above code, a line that telling the system to throw a process to another URL is appeared on res.sendRedirect(“Test2”);

    And if we want to do it on jsp, just modify the word res.sendRedirect into response.sendRedirect. Because once again, response variable already set by default on jsp file type, so we don’t have to make a variable for the ServletReponse class. The last but not least, of course, the URL-Mapping for this Test2 have to be declared on web.xml, except the target URL is not on our web-app context.

    Notes : The differences between 2nd tips and this tips from browser side is: the URL address on the 2nd trick didn’t change when the throwing process executed, while in this trick the URL address will change.

  6. Handling Null Value when parse out the parameter on HTTP Method.

  7. On HTTP Post or HTTP Get process, jsp will parse all the parameter that thrown from a form and then the other process will be executed after all the parameters defined. Some times when we parse the parameter on Jsp, we often have Null Value and that can cause the process is unable to continue, because jsp catch NullPointerException. Practically Null Value happens because the parameter that will parse didn’t bring a value form its feeder. So when the parse process executed, NullPointerException Error catch. To prevent this, we can make a default value for a variable that will responsible to carry out the value of parsed parameter.

    Please take a look below codes:

    <%
    String sId = request.getParameter("ID") == null ? "1" : request.getParameter("ID").trim();
    String sName= request.getParameter("Name") == null ? "" : request.getParameter("Name");
    %>
    

    On the above codes, we can see that String sId will be filled up by the value of parsed ID parameter, if the thrown ID parameter have Null value, then by default sId variable will be filled up with value 1. And its also happen with a catching process of Name parameter, but this parameter will fill up with the “” value if the value is not bound in the Name parameter.

And that’s it, few tips and tricks on servlet and jsp which become our discussion this time. I hope this helpful, and please you can use it for your own need.

 

Menteng, 18 Januari 2008

I Hope this will helpfull.

 

Josescalia.

Windows Delayed Write Failed On Maxtor One Touch 4 Mini

maxtoronetouch4miniOn December 26th 2008, I bought a external hard-drive, Maxtor One Touch 4 Mini with 160 GB capacity and it cost about 750.000 IDR. At the first time I use this external hard-drive I was very disappointed, I cannot use this external hard-drive at all. When I plugged in USB device to my laptop, my Windows XP cannot recognize this new hardware. At first time, I suspected this Windows XP cannot recognize this hardware, then I switch my operating system into Linux Open Suse, the other operating system that I‘ve been choose for my own computer, but the fact, I got one more disappointed feel, this Open Suse also cannot recognize this new hardware.

Well I think there’s nothing wrong with my laptop or the operating system. It must be this external hard-drive got some error when it comes out from its vendor. Anything broken maybe or I don’t know, obviously this is about this external hard-drive and its not about my chosen operating system, so I decide to returning back to the shop where this external hard-drive have been bought by me. At the shop, this hard-drive checked by the technician of the shop. And the result of this checking is make feel better, indeed this external hard-drive had something broken that can make it can be used. Then the shop replaces this external hard-drive with the other new external hard-drive that was still same type and same capacity with the broken one.

Before I took home this new external hard-drive, the technician makes sure that this new hardware is on good condition by trying first by him self. Indeed this one is on good condition and ready to use, so I agreed to take it home with me as a replacement of the broken one.

At home, I started to use this hard-drive to save the data which is very important to me. Because, indeed, I bought this external hard-drive in order to backing up all the important data. Backing up the data became a part of my computer activity.

Actually, I want to split this external hard-drive into two partitions, but I can only do that 2 days after, because I didn’t have a software on my laptop that have an ability to split the partition of this external hard-drive. Well as a customer I thought, I want to know the quality of the stuff that I bought rite? So I planned to do some test on this external hard-drive. My first simple test is copying the large size of files from my laptop into this external hard-drive. So I try to test it by copying a file that have 500 MB of its size with one single copy and one single paste, the result is not bad, this new external hard-drive capable to receive the data directly from a single copy-paste for 500 MB size of files. Actually this test is goes to USB cable, to find out whether this USB cable is capable or not to transferring the 500 MB file size.

And then I try to copy-paste a data file that have 1GB of size, and the result is still good, but when I try to copy-paste a data file that have 2GB file size, this hardware is apparently showing its weakness. When the data copying into this external hard-drive, and the progress just reached 45% of copied file, there’s an alert balloon showing up at the bottom-corner of my desktop windows, “Windows Delayed Write Failedand bla..bla..bla… now I can found out that this external hard-drive was cannot resist for transferring data file that large then 2 GB file size. And then I try to delete the failed copied file, but I feel so disappointed, this failed copied file cannot be deleted, when I try to delete, there’s a windows dialog showed up, telling that this failed copied file cannot be deleted. So I try to delete the file using Dos Console, and it still cannot delete. I try to switch to Linux open suse, and its still same, its still cannot be delete, so I left this failed copied file. I will remove it by formatting this external hard-drive and split its partition into 2 partitions. So this external hard-drive will have clean storage.

Two days later, I split this external hard-drive into 2 partitions with same size, each of this partition have 80 GB capacity. And then I try to do above test again, this test was failed the windows still have this windows delayed write failed.

And then I format again, and do the splitting once again, and do the test once again, but now I’ll test this external hard-drive using Linux operating system. Its little weird, the result that goes with Linux, found there’s none of this external hard-drive had some error, the copy of 2GB of file size was run properly, there’s no corrupted file found.

Hmm, I started to think, maybe there’s a problem with my Windows XP when the 1GB file size or above being copy to the external hard-drive. I tried to find out by browse Microsoft web site on FAQ and Bugs page. And I also search another web site or articles in the internet. By these browsing, I can make some statement that there are problems on the Windows system cache when we copy the data with a large size onto external hard-drive. Even the answer of Microsoft website about this problem focused on the failed of the external hard-drive connector, such as USB cable, etc, I still keep the statement that this is all about Windows XP system cache problem.

Then I try to find out once more by browse the internet, the possibility of any one else having same problem like me and how he or she solve the problem. After two days, finally I found a related article, and in these article also written how to solve these problem. Unfortunately, I forgot the link, but the important thing is, this link is not the Microsoft website or this external hard-drive vendor web site, but some one else which have same problem with me.

Ok, the focus of this problem fixing process is, by enlarging Windows system cache. I used software to change to change this windows system cache. I know this software also from the article that I’ve read before. This software name is Cacheman made by Outer Technologies. This software is not free, and I used version 5.0. I used this version because we can still use this software even we don’t do any registration. :P

After the installation of this software is successful on my Windows XP, refer to the article I made some changes on my Windows XP system cache, and then I restart my Windows XP and make some test again just like before.

The test by copying 2GB file size to the external hard-drive running well, there’s no more Windows Delayed Write Failed, I’m happy. Then I try to copy file that larger then 2GB of file size and its still have no problem at all. After do test by copying 5GB file size onto this external hard-drive and its success, I stop the test, and I think the test is finish.

I’ve planned to test for a week, before I can make a decision that this test is really-really passed. And when this article written I still cannot found a same problem with before. Then I decide that Windows Delayed Write Failed that happen on my external hard-drive is solved, I can use this external hard-drive normally.

Below are the steps, when I’m using Cacheman5.0 to change my Windows XP system cache in order to solve the Windows Delayed Write Failed problem that happen on my brand new Maxtor One Touch 4 Mini 160 GB.

On show wizard menu, I choose all, and for the entire window that showed up, here are the details:

1.Disk Cache: choose Balance
2.Icon Cache: choose Set large maximum Icon Cache size
3.Unload DLLs from Memory: choose Enable
4.Disable Paging Executive: choose Enable
5.IO Page Lock Limit: choose Large IO page lock limit value
6.Disable NTFS last access update: choose Enable
7.Disable creation of short filenames: choose Enable
8.Reserve more space for the Master File Table: not enable (don’t check)
9.Defragment hard disk when idle: choose Enable
10. Hung App Timeout: choose Optimize
11. Wait to Kill App / Service Timeout: choose Optimize
12. Menu Show Delay: choose Optimize
13. Filename Completion: not enable (don’t check)

That’s it, Windows system cache setting using Cacheman on my Windows XP, to prevent Windows Delayed Write Failed problem.

Menteng, January 4th, 2009

I Hope this will helpful

Josescalia

Find Out Prime Number with Java Application

One day, there’s some one came to me and intent to start learning Java programming, she asked a lot about Java and it’s technology. One of her question based on her story-told is how can we make a Java application which is able to generate an array of prime number?, the problem is, I have forgotten what is the definition of prime number it self, so we had a problem to make the application that will appropriate with her idea. ha..ha..ha..(what an excuse…!!!).

Yesterday, I remembered that, and I go Googling, to find out what is prime number definition. From the Indonesian version of wikipedia site, I found prime number definition, but I tried to make my own comprehension of this prime number, Prime Number is a real number beginning with 2, this prime number is a number that is not exactly divisible by any number less then it self, except 1. That’s my comprehension of prime number, so let’s take a number and try to check with my comprehension, lets take 15 as a sample. Is 15 is prime number?, we will arrange our inspection like this :

  1. Is 15 is more or equals to 2 (15 >= 2 ) ?, because first condition of prime number is real number that start from 2.
  2. Is 15 exactly divisible by a numbers started from 2 until 14 ?, because other condition of prime number is a number that is not exactly divisible by any number less then it self, except 1.

OK, let’s run this inspection one by one, for the first step of the inspection, 15 is fulfill the condition of a prime number, meaning that 15 >= 2 is true or correct. And then let’s continue with the 2nd step of the inspection. Is 15 is exactly divisible by 2, and the result is 15 got reminder when it devise b,y 2, because 15/2 =7 and the reminder is 1. The checking is continue by devise again with next number which is 3, at this division, it’s clear that 15 is not a prime number, because 15 devise by 3 is got no reminder. And we can assume that 15 is not a prime number because 15 is exactly divisible by 3.

Now, let’s take a new number to check, the new number is 17, and we will check whether this 17 is a prime number or not using same inspection above. For the first check, it’s clear that 17 is highest than 2, and for 2nd inspection, let’s take a look the picture below:

17 / 2 = 8 remind 1
17 / 3 = 5 remind 2
17 / 4 = 4 remind 1
17 / 5 = 3 remind 1
17 / 6 = 2 remind 5
17 / 7 = 2 remind 3
17 / 8 = 2 remind 1
17 / 9 = 1 remind 8
17 / 10 = 1 remind 7
17 / 11 = 1 remind 6
17 / 12 = 1 remind 5
17 / 13 = 1 remind 4
17 / 14 = 1 remind 3
17 / 15 = 1 remind 2
17 / 16 = 1 remind 1

On the above picture we can see that 17 always got reminder when we devise it by any number that less then 17, except 1. And now we can assume that 17 is a prime number.

How about, if with those steps we try to make a Java application that have an ability to check a number whether is a prime number or not. OK, let’s try to make an application that have an ability to check a number whether it’s prime number or not, here comes the codes:

package org.mojo.blog.app.integer; //ignore this, if this program is not on package

public class isPrimeApplication {

    public static void main(String[] args) {
        int valueToCheck = 17; // value to check
        boolean isPrime = false;
        if (valueToCheck >= 2) {
            isPrime = true; // first check and assume it's prime number
            // try divide valueToCheck
            // with all number less than it self
            // and begining from 2
           for (int i = 2; i < valueToCheck; i++) {
            if (valueToCheck % i == 0) {
                    //if divides exactly so stop the loop and it must be not prime
                    isPrime = false;
                    break; // no need to check again
                }
            }
        }
        System.out.println("is " + valueToCheck + " Prime ? ");
        System.out.println("the answer is " + isPrime);
    }
}

In above codes, we can see that we have 2 variables, valueToCheck and isPrime, and the process flow will look like exactly same with the inspection above, where :

  1. if (valueToCheck > = 2) is first inspection, the number which entering this block will temporary assumed as prime number.
  2. for (int i=2; i < valueToCheck; i++), we will do loop, start from 2 until the value of checked number minus 1 (valueToCheck – 1) . And then we will do checking, if from this loop operation there’s a number can exactly divisible, then stop the loop, cos that number is not a prime number clearly.

Hmm, what if we continue the development of this application become an application that have an ability to find out prime numbers of given range, such as, find out prime numbers between 0-50. It looks like, we can make it by adding just one looping-logic before the existed loop. Let’s take a look of this codes :

package org.mojo.blog.app.integer; //ignore this, if this program is not on package

public class PrimeAdvance {

    public static void main(String[] args) {
//      int valueToCheck = 17; // value to check
        int nRange = 50;
        boolean isPrime = false;

        for (int i = 2; i <= nRange; i++) {
            if (i >= 2) {
                isPrime = true; // first check and assume it's prime number
                // try divide valueToCheck
                // with all number less than it self
                // and begining from 2
                for (int j = 2; j < i; j++) {
                    if (i % j == 0) {
                        //if divides exactly so stop the loop and it must be not prime
                        isPrime = false;
                        break; // no need to check again
                    }
                }
            }
            if(isPrime){
                System.out.println(i);}
        }
        //System.out.println("is " + valueToCheck + " Prime ? ");
        //System.out.println("the answer is " + isPrime);
    }
}

On the above code, we can see that we just add one looping-logic before the existed looping. And then we add lines to check if i is prime number, then print out i to console. And we put this lines inside the block of looping the range data that will check.

That’s it, a little story about the my wondering of prime number, triggered by friend’s story. You can use it freely if it’s helpful for your case, and it’s freely too for you to develop mode if you have any brand new idea.

To more understand the prime number it self, here’s a link of Java program source code, that I have added some console print out, in order to watch the process of finding out a prime number from a given range

 

I hope this helpfully

Menteng, 01 January 2009

josescalia