Showing posts with label Tools. Show all posts
Showing posts with label Tools. Show all posts

Friday, April 08, 2022

Git for Windows - tips

Some time ago I described how to install Git For Windows and how to use it in IntelliJ Idea. See here for details. I realised that from time to time I go back to those things:

  • modifying git config files and trying to find them
  • working with passwords
  • using different editor for commit message

Let's take a closer look.

Modifying git config files and trying to find them.

Git uses three different config files (usually named .gitconfig) at three different levels: 

System


Location: [your_git_for_windows_instalation_path]/etc/.gitconfig or  [your_git_for_windows_instalation_path]/mingw64/etc/.gitconfig.  

Purpose: contains values applied to every user on the system and all their repositories. If we want to read/write from/to this file we have to pass --system option. Because this is a system configuration file, you may need superuser privilege to make changes to it.


Global


Location: [windows_user_directory]/.gitconfig

Purpose: contains values applied to certain (usually logged in) user on the system and all repositories this user works with. If we want to read/write from/to this file we have to pass --global option.


Project


Location: [project_directory]/.gitconfig

Purpose: contains values applied to certain project. If we want to read/write from/to this file we have to pass --local option, or use no option. When changing values in certain project/git repository we have to execute this command being located in that project.

Working with passwords.


During installation process Git For Windows offers to install Git Credential Manager (GCM) - a tool for storing passwords in a secured way. 

But what if want to enter password every time when we push/pull code from remote repository? We can select "None" when Git installer asks for manager. But what if we already installed it and we want to remove it? We have to entirely remove below entry from system config file:  

[credential] 
    helper = manager

Git will start to ask for passord every time, but it will do it using OpenSSH popup window. If we want to disable it in order to enter password directly from command line (or in terminal window in IntellJ), we have to add empty entry for system config file by executing this command: 

git config --system core.askpass ""

If You really want to not to enter password every time during pull/push  with remote repository it is better to use SSH keys.

Using different editor for commit message.


By default Git For Windows offers to install vim as a default editor for commit messages. It is XXI century, we have many great editors under Windows, so do not do this mistake and do not install this archaic editor for linux geeks ;) Why? Let's demonstrate it with example.

1. We have a "Hello World" java application maintained by Git:


2. When we commit changes and in the commit command we pass commit message, we will not find any issues with the vim:


3. But let's use a commit command where no commit message is passed and we expect an editor to open and let us put message there. W use git commit command without "-m" option:


As we see vim is opened in the terminal and after start insertion mode (press Insert) we can type in commit message. Now we have to save the commit message. As You know we have to press Esc in vim to exit insert mode and type something like :wq!. 

Good luck :) When You press Esc focus is switched to the Main.java file instead of terminal where vim is opened. It is a known issue in IntelliJ when using Git in its terminal: https://stackoverflow.com/questions/67848200/how-do-i-commit-a-git-message-in-intellijs-terminal

In short: You have to change Esc key binding to switch focus under IntelliJ (assign different key not only remove Esc). Or if You have luck and do left-click (on some area different than file edit window) with Esc, You may sooner or later exit from insert mode:


After typing :wq! we see that commit is complete with our message:


You can now say: "What a problem, just change this binding if You still want to use git from terminal.  Or just use excellent graphic integration with git from IntelliJ". I would say: "Maybe it is high time use excellent external editor which I use every day instead of archaic one which I have to configure in unusual way".

4. Solution: use external editor instead of vim (here I will use Sublime).

First we define default editor in git system config file using this command:

git config --system core.editor "'C:/Dodatkowe/Sublime/subl.exe' -w"

Now we check if there are any entries about core.editor in global config file and specific project config file (which may override system setting). If  we find any, remove them. Now let's try to use Sublime as editor:


After typing in git commit Sublime editor is opened in new window, where we can type in our commit message. Please notice what IntelliJ displays in terminal: 

hint: Waiting for your editor to close the file...

Yes, it is wating until You save the file and close Sublime (when using vim it is also display this message, but exiting there is harder ;)). So lets save the file by Ctrl+S and close the Sublime:



It works without changing anything in IntelliJ.


Sunday, January 13, 2019

Gather all hammers inside toolbox - revisited

It's been a long time since I wrote something here. When I started this blog, one of the first thing I wrote about was how to set up development environment. It was ten years ago - see here. A lot of things changed in Java world in this time. Let's try to set up everything again using modern and most popular tools now.

What are we going to do?
  1. Install Java JDK - we still have Java like in the past, however significant changes were done by Oracle last time.
  2. Install IntelliJ Idea  - an IDE, as replacement for Eclipse.
  3. Install Git as version control system for our source code.
  4. Write a sample Java "Hello World" application to check if installed IDE and Java works.
  5. Use Git with our "Hello World" application.
  6. Install Apache Maven for dependency management in our projects.
As before, all things will be installed in C:\Development

Installing Java


We all get used to that Java is free to use either for personal or commercial purpose. It was true for Java 8 and older versions until 1st January 2019. Starting from 1st Jan 2019 Oracle announced end of public updates of Java SE 8. It simply means If You use Java in commercial purpose and You want get updates for Your Java SE 8, from 1st January 2019 You have to pay for this.

Why Java 8, what about other versions like 9,10,11...? From Java 8, every three years Oracle will relese Java version known as Long Time Support (LTS). First LTS is Java 8, second is Java 11 - it means that Java 9 and 10 is no longer supported now. Changing licensing model for commercial use means that You have to pay for the updates/support for each LTS version starting from 8 (from 1st Jan 2019). See more here.

So what are options? We can:
1. Stay with latest available Java 8 from Oracle (JDK 8u192) without possibility to update anything - we don't have security updates, but we are free of charge.
2. Become Java Commerical User and pay for latest JDK (11 at the time of writing)
3. Use OpenJDK from Oracle - this is free Java for commercial use, but each new version is publicly available in 6-month interval, with 6-month support/updates available. So every half a year You have to update used OpenJDK on Your own.
4. Use a Java based on OpenJDK but with long-term support - for example Amazon Corretto 11 available here.

Let's use JDK 8 from Oracle from point 1. If You want to use latest free Java with LTS You can use Amazon Corretto from point 4 - just download .zip file and extract it for exmple into C:\Development\Java\AmazonJDK\Java11_64bit

Step 1: Download 64 bit version of JDK 8u192 or Windows from here.
Step 2: Create directory C:\Development\Java\OracleJDK\Java8_64bit and start the installer:


Remove installing public JRE and choose previously created directory:


Step 3: After succesfull install create system variable named JAVA_HOME with value C:\Development\Java\OracleJDK\Java8_64bit then modify Path system variable by adding %JAVA_HOME%\bin at the end.

Step 4: Verify Java installation by opening command line and type java -version and javac -version. You should see informationa about Java installed:


Java is installed.

Installing IntelliJ Idea


Step 1: Create directory C:\Development\Jetbrains\Idea
Step 2: Download and install an application JetBrains Toolbox from here. This is an application to maintain all products from Jetbrains (IntelliJ Idea manufacturer). It allows to automatically update installed tools.


Step 3: Configure toolbox.

Choose created directory in step 1. Do not forget to  click apply after choosing it. If You have any license from Jetbrains, log in into your account now - You will not have to provide license when installing tools:


Now You can choose a tool to install:


After click on a tool, it will be installed into the previously selected directory:


Just click on tool to launch it. You can also change settings of the tool being installed, like update plan, memory consumption and so on:


IntelliJ Idea is installed. Start it, then go thru some creator in order to perform basic settings (You may leave all the options default).

Installing Git


Git will be used to track changes we make in our projects files. 

Step 1: Download Git for Windows from here
Step 2: Create directory C:\Development\Git. Run the downloaded git installer and choose created directory as the installation target: 


Install Git using all defaults (including vim as default editor), but allow git to be used from command line:





Step 3: Verify installation and basic configuration. 

Open command prompt and execute command git -version to see if git responds. After that configure user and email by typing commands (replace XYZ with Your value):
 
git config --global user.name "XYZ"
git config --global user.email "XYZ"

Below screen shows all those commands and their results:


Step 4: Make IntelliJ aware of installed Git.

Open settings and type Git in search box. Go to Git settings and set path to git.exe:


That's all. Git is installed and configured in IntelliJ Idea.

"Hello World" - sample java application


Step 1: Create directory C:\Development\Projects

Step 2: Run Idea. You will see initial screen for creating/opening/downloading a project. Choose create new project:


Step 2: Choose Java project type:


Idea is shipped with its own JDK. We would like to use our own JDK. Press button New ans select the JDK directory C:\Development\Java\OracleJDK\Java8_64bit (or another directory like C:\Development\Java\AmazonJDK\Java11_64bit if You use Amazon Corretto)Then press Next.

Step 3: Choose project type from template: 

 
 Step 4: Choose project name and location (use projects directory created in step 1): 


Step 5: Sample application is ready. You can start is using green "play" button:



Step 6 (optional): Leave only our installed JDK for future projects. 

As mentioned above, Idea comes with built in JDK. We can disable showing this JDK as a option to select for future projects and leave only those we installed in C:\Development\Java\OracleJDK\Java8_64bit. In order to do it open project properties and find Platform SDK. Then choose JDK provided by Idea and delete it:


Then select our installed Java and change its name:


From now this is only one and thus default Java to use in Java projects. Of course You can add other JDK version like OpenJDK.

That's all. Idea is configured and ready for Java development.

"Hello World" - sample java application with Git


Using git is beyond of the scope of this blog :) There are many great tutorials explaining the nature of git - for example this one. I will show how to add a git support to the existing project (Hello World created earlier).

Step 1: Convert existing projest into git respository. 

Open project location (C:\Development\Projects\Test) and using context menu (right mouse click) select option Git Bash Here. Git will open its terminal with path set to the project. Now enter command git init:


This will create empty repository:


The project is now maintained by Git.

Step 2: Verify git integration under IntelliJ Idea. 

Open Test project in Idea to see that it is recognized as a git project now:


Step 3 (optional): Use git command directly from IntelliJ Idea.

Idea has great integration with Git, however it is possible to use git commands entered by hand directly in Idea - just like we use them in Git Bash. We can use Idea's terminal and set it to open Git Bash under the hood. Go to the settings and find options for Termimal. Set shell path to point to the Git Bash executable script with some additional options:


Now we can execute git command in Idea's terminal:


Installing Maven


Maven will be used for dependency managment, building and running future apps. Idea comes with bundled Maven, so we do not have install our version. But similar to installing Java, we will install our own version of Maven.

Step 1: Create directory C:\Development\Maven. Then download Maven (binary zip archive) from here and unpack it to the created directory.

Step 2: Create directory C:\Development\Maven\repository for artifacts downloaded by Maven:



Step 3: Tell Maven to use created above directory as a repository. 

Locate Maven settings file named settings.xml and add a line inside:


Step 4: Add Maven's bin folder to the system PATH variable in order to use maven commands from console.

Step 5: Verify if Maven is installed correctly. 

Open command line and execute command: mvn -version. You should see similar information:


Note 1: Maven displays information about Java used. That's why You have to install Java before and set JAVA_HOME variable.

Note 2: There is no need to set up MAVEN_HOME or M2_HOME system variable like it was done for previous versins of Maven.

Now we can tell IntelliJ Idea to use installed Maven instead of bundled. Open settings, type Maven in search field. Idea will show settings for Maven. Choose Maven installation directory. We may notice that Idea will display recognized version of selected Maven installation and local respoitory path will change to the value set in step 3:


Please note that this setting is not global - it is only for currently opened project. If we want to use our manually installed Maven in other projects, we have to repeat above step in those projects.

Wednesday, September 21, 2011

Tomcat - using Realm to protect access to JSF application (part 2 of 2)

Note: below description uses Eclipse Indigo, Tomcat 7.0.28, MyFaces 2.1.7
 
Requirements:
  • understanding basics of Tomcat's Realm
You will learn:
  • how to define users and roles in own web applications (JSF 2.0 as example)
  • how to use encrypted passwords for realm users instead od plain text
In the previous post I described how to configure access to Tomcat's server administration application using Tomcat's Realm elements. The whole thing boiled down to write a few lines of text in server.xml file. But how does it look like when we have to do it from scratch in our application?

Step 1. Let's create very simple JSF application which has only 3 pages:
  • /index.html - main page with two buttons navigating into two pages:
  • /unrestrictedPage.xhtml - page always accessible and visible to anyone
  • /restricted/restrictedPage.xhtml - page and directory available only for valid users
The complete application structure will look like:



Step 2: we have to add a privilleged user named admin with password adminpass who belongs to role privillegedUsers (You can choose any user login, password and role name). Just simply add this line:
<user username="admin" password="adminpass" roles="privillegedUsers" />
into [tomcat directory]\conf\tomcat-users.xml file.

Step 3: configuring application. We have to modify web.xml of our sample application by adding following text:
<web-app>
...
    <security-role>
        <description>
              All persons belong to that role have access to restricted application area.
        </description>
        <role-name>privillegedUsers</role-name>
    </security-role>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Restricted</web-resource-name>
            <url-pattern>/faces/restricted/*</url-pattern>
            <url-pattern>/restricted/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>privillegedUsers</role-name>
        </auth-constraint>
    </security-constraint>

    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>Restricted access</realm-name>
    </login-config>
...
</web-app>
First we defined a role named privillegedUsers - the same we put in tomcat-users.xml file above. Second we have to defined prottected parts of our application, by providing proper URL pattern. Please note that we have two entries here: /restricted/* - everything in this directory is protected in case someone typed this part manually in browser's address bar,  /faces/restricted/* - JSF adds "faces" prefix when navigating between pages, so the URL is a little bit different and we have to watch for this also. After that we have to define a role which is allowed to access to the protected parts. This is privillegedUsers role defined earlier. At the end we have to define the way how the authentication is done - the simplest way is BASIC, which displays predefined form with credentials.

Now we are ready to deploy our application on Tomcat and run it. It should look like this:


when we try to access to restricted area. In order to do this we have to put credentials for user defined in step 2 (admin, adminpass).

Note: there is a little trick here, for the button "Restricted area" - see index.xhtml page source code:
<h:commandButton value="Resricted area" action="/restricted/restrictedPage.xhtml?faces-redirect=true" />
<h:commandButton value="Unrestricted area" action="/unrestrictedPage.xhtml" />
Because JSF internally by default makes forward to other page, browser is unaware what has happened and display URL from one step back. In such case our URL security patterns will not match anything, and restrictedPage.xhtml will be displayed without asking for login and password! In order to make protection work we have to perform full redirection for that action in order to force browser to fetch target URL and display it. For JSF applications it is better to use filters or Spring Security in order to avoid such dirty tricks.

Encrypted passwords.

As You probably have seen, passwords vor valid users are stored inside tomcat-users.xml file as a plain text. There is a possibility to store them in encrypted form, using MD5. Here is what needs to be done:

Step 1: using Eclipse modify Tomcat server.xml and its <Realm> atrribute into:
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" digest="MD5"/>
Step 2: in web.xml change <auth-method> from BASIC to DIGEST

Step 3: for user admin and his previous password adminpass we have to generate its md5 equivalent using Tomcat's digest.bat file (located in [tomcat directory]\bin folder) :

digest.bat -a md5 admin:"Restricted access":adminpass

"Restricted access" is a realm name taken from <auth-method> tag from web.xml. Those names must match, if name contains spaces, it must be surrounded with "".


Step 4: using Eclipse modify Tomcat's tomcat-users.xml file:
<user username="admin" password="db7bc05adcf611fc779f32a4e680cc01" roles="privillegedUsers" /> 
where password was taken as a result of executing command from step 3.

-------------------------------------------
Download source files:

Note: make sure that Java, Eclipse and Tomcat are properly installed and configured for running the project (additional configuration may be required if different directories are used).

Eclipse complete sample project is here (with all required libraries).

Tuesday, September 13, 2011

Tomcat - change default application, protecting access to web applications using Realm (part 1 of 2)

Note: below description uses Eclipse Indigo, Tomcat 7.0.28,

Requirements:
  • installed Java (description here)
  • installed and configured Eclipse (description here)
  • installed and confiured Tomcat for the Eclipse (description here)
You will learn:
  • how to change default Tomcat application
  • how to allow users access to Tomcat's server administration application using Tomcat's Realm

Let's assume that You have Tomcat which is configured to work in Eclipse. When You start Tomcat (using Eclipse or standard scripts from Tomcat's distribution) and type in the browser URL http://localhost:8080, You will see Tomcat's default application:


This application is located in the [tomcat directory]\webapps\ROOT folder. If You want to change this page, just edit content of file index.jsp and index.html. If You want to completely remove this application, just remove complete ROOT folder.
Removing is not the best choice, because Tomcat is shipped with a special applications for server administration. You can access those applications using links in red square. Try to click on any link - You should see screen with login and password prompt:


Those parts are protected using Tomcat Realm. What is Realm? Realm is a set of valid users (defined by user name and password) and roles where those users belong. The idea is to configure access to web application only for valid users from certain roles. But where are those users and roles stored? It depends on a implementation of a realm - they can be stored in database, in LDAP, or in xml file. Tomcat's server administration application uses xml file to define users' access. Let's try to set up some users able to start that application.

Step 1: using Eclipse open server.xml from the Servers, and make sure that entry <Realm classname="org.apache.catalina.realm.UserDatabaseRealm" resourcename="UserDatabase"></Realm> exsits between <Engine> tags, outside <Host&gt tags - it means that this realm will be used for all hosts and all applications on that  hosts:


Step 2: using Eclipse open tomcat-users.xml from the Servers and add an entry for the user who will be able to access Tomcat's server administration application:


By default UserDatabaseRealm uses [tomcat directory]\conf\tomcat-users.xml file to load users and their roles into memory on server startup. In order to allow defined users to access administration application, they need to belong to roles named manager-status, manager-gui and admin-gui. After changes made, restart Tomcat server and try to access Tomcat's administration application giving username and password from tomcat-users.xml file. If everything was set up OK, You should see mentioned applications.

You may wonder why we used here roles named manager-status or manager-gui or admin-gui. Those role names come from Tomcat's server administration application specific settings, stored in the web.xml file. In the next post I will show how to protect own application (JSF2 application will be used as an example) and how to define own roles.

Wednesday, August 03, 2011

SSL in Tomcat under Eclipse (part 2 - certificate from CA)

Requirements:
  • You should be able to generate self signed SSL certificate and integrate it into Tomcat, as described in previous post.
You will learn:
  • how to obtain and install a real SSL certificate from well known Certificate Authority (CA)
In the previous post I described the complete procedure of generating self signed SSL certificate and integrating it into Tomcat. In this post I would like to focus on the example with real certificate obtained from CA - I will use Thawte as example.

Note: let's assume that You created an application which is going to be visible under the following URL: http://www.myapp.com.

Step 1: generating self signed certificate for domain www.myapp.com.

This is exactly the same step to step 1 in previous post. You have to execute the following command:

keytool -genkey -alias myappcert -keyalg RSA -keystore myapp.keystore

Step 2: Generate Certificate Signing Request (CSR).

You have to generate a special request, which will be send to the CA. You have to execute command:

keytool -certreq -keyalg RSA -alias myappcert -file certreq.csr -keystore myapp.keystore

Generated request is saved as a certreq.csr file, which will be send to CA. CA will use this file to generate certificate signed by them.

Important: You have to use exactly the same alias (in this example: myappcert) for step 1 and step 2.

Step 3: Getting certificate from CA.

Usually certificate are delivered in PKCS#7 or X.509 format. For the first one, the file with certificate will have .p7b extension, for the second one - .cer. Sometimes You can get such certificate also by email as a pure text - for the X.509 format, certificate will be placed between tags -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----, for PKCS#7 certificate will be placed between tags -----BEGIN PKCS7----- and -----END PKCS7-----. Then You have to copy the certificate content (including those begin/end tags!) and save this as a .cer or .p7b file (You can use Notepad for that). Now You are ready to import Your signed certificate.

Step 4: importing signed certificate.

a) as a .p7b (PKCS#7) format:
Acording to the Thawte, when You obtained Your certificate as a .p7b file, You need only one command to import and install this certificate in Your keystore:

keytool -import -alias myappcert -trustcacerts -file signed_cert.p7b  -keystore myapp.keystore

where signed_cert.p7b is a signed certificate obtained from CA.

b) as a .cer (X.509) format:
According to the Thawte, when You obtained Your certificate as .cer file,  You need to download Primary and Secondary Intermediate CAs and import them. They are delivered as .p7b format (i.e. intermediate.p7b). I should import them first, using command:

keytool -import -trustcacerts -alias intermediatecerts  -file intermediate.p7b -keystore myapp.keystore

and then import my certificate (it is in .cer file signed_cert.cer) using this command:

keytool -import -trustcacerts -alias myappcert -file signed_cert.cer -keystore myapp.keystore

where signed_cert.cer is a signed certificate obtained from CA.

Problem and workaround:
Both above ways seems to be simple, but... when I was buying some time ago a web SSL certificate from Thawte, I receive certificate as a pure text in e-mail. Certificate was in X.509 format (I had tags ----BEGIN/END CERTIFICATE-----). I created a signed_cert.cer file from that e-mail content. Then I tried to install intermediate certificates like it was described in Thawte documentation. Unfortunately it didn't work. The first command for importing intermediate certificates failed with error:

keytool error: java.lang.Exception: Input not an X.509 certificate

It seems that keytool does not work with .p7b format (I used JDK 1.6.0_16), so I expect that even if I get my certificate as .p7b file (complete, without need to import intermediate certificates as in a) subpoint) it will also not work. I took a .p7b file with intermediate certificates, opened it under Windows, and for each certificate found inside i exported it as a X.509 DER certificate, giving each file .cer extension. So I had three .cer (X.509) files: signed_cert.cer, thawte_primary.cer, thawte_secondary.cer. Now I had to import intermediate certificates and after that import my signed certificate with those commands:

keytool -import -trustcacerts -alias primary -file thawte_primary.cer -keystore myapp.keystore
keytool -import -trustcacerts -alias secondary -file thawte_secondary.cer.cer -keystore myapp.keystore
keytool -import -trustcacerts -alias myappcert -file signed_cert.cer -keystore myapp.keystore

Now import was OK. So the general workaround rule (if there are any troubles) is: get all needed certificates in X.509 form, import intermediate certificates (if any required) and import Your signed certificate at the end.

Important: You have to use exactly the same alias (in this example: myappcert) like You used in step 1 and step 2, except for importing intermediate certificates - You can use whatever alias You like.

Step 5: copy Your myapp.keystore file into Tomcat's /conf directory

Step 6: modify Tomcat configuration to use SSL certificate

It is exactly the same as step 3 in previous post.


That's all.

Monday, August 01, 2011

SSL in Tomcat under Eclipse (part 1 - self signed certificate)

Requirements:
  • installed Java (description here)
  • installed and configured Eclipse (description here)
  • installed and configured Tomcat for the Eclipse (description here)
You will learn:
  • how to set up Tomcat for SSL connection using self signed certificate under Eclipse
When You want to secure Your application SSL is the most natural choice. In order to make Your application be recognized as trusted by browser, You can by a buy a certificate from well known certificate authority (CA), which will be generated for the domain Your application uses. If You do not care about being recognized as trusted service, but instead You just want to encrypt the data exchanged between server and client's browser, You can use Your own self signed SSL certificate. In this post I will show how to generate such SSL certificate and how to set up Tomcat (from the Eclipse level) to use generated certificate.

Note: let's assume that You created an application which is going to be visible under the following URL: http://www.myapp.com.

Step 1: generating self signed certificate for domain www.myapp.com.

Go into Your Java bin directory (i.e C:\Development\Java\bin). Then open Windows console (under Windows Vista/7 open the console with Administrator right) and type in command:

keytool -genkey -alias myappcert -keyalg RSA -keystore myapp.keystore

where myappcert is the name of the certificate being generated and myapp.keystore is a file where certificate will be stored. You will be asked about the password for created the myapp.keystore file. Type in "mypass", press Enter and type it again and press Enter again. Then You will be asked for some details about You:



Please note that for the first question about first and last name I gave answer www.myapp.com. This is very important - this name (known as CN - Common Name) will be used for the checking if certificate on the page we visit was generated for the same URL which we typed in in the browser.
At the end You will be asked for the password for the newly created certificate. The password must be the same as one used for myapp.keystore file ("mypass"). Do not type antyhing, just press Enter to use the same password. Your myapp.keystore file containing myappcert certificate is ready.

Step 2: copy Your myapp.keystore file into Tomcat's /conf directory

Step 3:  modify Tomcat configuration to use SSL certificate.

Make sure that Your Tomcat is configured with Eclipse and works OK without SSL (start Tomcat from Eclipse and type in http://localhost:8080 in the browser). Stop Tomcat if it is running. Then open server.xml file form the "Servers" view:



and locate default element for standard HTTP connections (marked red). Then add additional element for the SSL connection (next to existing one):
<Connector
        SSLEnabled="true"
        clientAuth="false"
        keyAlias="myappcert"
        keystoreFile="conf/myapp.keystore"
        keystorePass="mypass"
        maxThreads="200"
        port="8081"
        scheme="https"
        secure="true"
        sslProtocol="TLS"
 /> 

Please note that next to some specific SSL settings, we set the location of the keystore file, the password for that file and certificate name to be use. SSL connection uses port 8081, where normal HTTP connection
uses port 8080.

Note 1: all modification of server.xml file were done from Eclipse level, using "Servers" view. If You want to use Eclipse WTP for starting Tomcat (like I do so far) You can't edit this file from elsewhere. Eclipse WTP overrides original Tomcat configuration files by files visible under "Servers" - changes done outside Eclipse will not be visible for WTP.

Note 2: I added element specific for SSL next to existing element for standard non encrypted HTTPS connections. This is second issue directly connected with Eclipse WTP - when You remove standard connector for HTTP, Eclipse will close Tomcat after a time set in "Timeouts" section in the Tomcat settings:



Some people try to extend the timeout time into long period, but still after this period Eclipse kills Tomcat process, as if Tomcat was not properly started in the required time. Unfortunately there is no way to set timeout into ifinite time - the only way to fix this under WTP is to leave standard HTTP element in Tomcat's server.xml file.

Step 4: that's all. Tomcat is configured to work with SSL. 

Try to enter the URL: https://localhost:8081. If You see Tomcat's page, everything works OK (You can see certificate warning - You Need to add security exception for that certificate). Of course You can still open the same Tomcat page by standard HTTP (You have two elements), just enter http://localhost:8080 URL.

Wednesday, July 27, 2011

Tomcat OutOfMemoryError: Heap space/PermGen space

Note: below description uses Tomcat 7.0.28

Have You ever seen such error in Your logs? Probably yes. It simply means that available memory for Tomcat was consumed and nothing left. To be precise: available memory for JVM which Tomcat uses to run.

What causes this error? It can be caused by memory leaks in the application or the applications has big requirements "by design", even if there are no memory leaks. For the first case You should use some profiling tools to find and fix memory leaks - perhaps this might help without need to change memory settings for Tomcat JVM. If You are sure that Your application has no memory leaks, the only way is to increase memory used by Tomcat JVM. See below how to do that - please note that I described modifying Tomcat memory settings when it is installed as a service under Windows OS.

32-bit Windows
The main problem here is that 32-bit OS is able to see no more than 3,2GB of RAM, even if You have 4GB or more physically installed. This is upper limit of memory that can be use - in theory. However, in practise You will not be able to use more than 1 to 1,5GB of RAM for Tomcat's JVM - the rest of memory is used by OS itself and installed software.

64-bit Windows
Let's assume that You need to assign more than 1,5GB of RAM for Tomcat JVM. Therefore You need 64-bit OS with at least 4GB of RAM (for example 64-bit Windows Professional supports up to 192GB of RAM). Of course You must also use 64-bit JDK - when You use 32-bit JDK under 64-bit OS, You will again face the limit of 3,2GB RAM. You also must use 64-bit version of Tomcat (as it contains Windows service wrapper to use with 64-bit JVMs on 64-bit Windows platforms). Below You will find complete list of all needed steps:

Step 1: make sure You are using 64-bit Windows OS. 

Step 2: install 64-bit JDK and set $JAVA_HOME to the installation directory. 

Step 3: download .zip file with 64-bit Tomcat for Windows (file: apache-tomcat-[version]-windows-x64.zip). 

Step 4: extract Tomcat and go into Tomcat's /bin directory.

Step 5: open service.bat file and locate the line with --JvmMS and --JvmMX parameters, and modify it with new values memory, eg:

%EXECUTABLE%" //US//%SERVICE_NAME% ++JvmOptions "-Djava.io.tmpdir=%CATALINA_BASE%\temp" ++JvmOptions "-XX:MaxPermSize=1024m" --JvmMs 2048 --JvmMx 4096

Note: PermSize is set in different way than heap which has predefined JvmMS and JvmMX flags.

Step 6: open Windows console with administrator rights, then go into Tomcat /bin and execute command:

service.bat install tomcat6

Step 7: start service with command:

net start tomcat6

Note 1: You can skip point 5 and execute directly point 6. After that just start tomcat6w.exe which is a GUI tool for managing the service. You can set memory values there.

Note 2: as an alternative to above steps, You can download Tomcat service installer (file: apache-tomcat-[version].exe) which performs service installation, and then use tomcat6w.exe tool for tune memory settings.

That's all. Your Tomcat service should use provided memory settings.