Glassfish changing master password and saving it to a file

Saving the master password when creating a domain is pretty straight forward just pass the --savemasterpassword flag when executing the create-domain command

${glassfish_install}/bin/asadmin create-domain --savemasterpassword mydomain
Enter admin user name [Enter to accept default "admin" / no password]> admin
Enter the admin password [Enter to accept default of no password]>
Enter the admin password again>
Enter the master password [Enter to accept default password "changeit"]>
Enter the master password again>
Default port 4848 for Admin is in use. Using 55187
Default port 8080 for HTTP Instance is in use. Using 55188
Default port 7676 for JMS is in use. Using 55189
Default port 3700 for IIOP is in use. Using 55190
Default port 8181 for HTTP_SSL is in use. Using 55191
Using default port 3820 for IIOP_SSL.
Using default port 3920 for IIOP_MUTUALAUTH.
Default port 8686 for JMX_ADMIN is in use. Using 55192
Using default port 6666 for OSGI_SHELL.
Using default port 9009 for JAVA_DEBUGGER.
Distinguished Name of the self-signed X.509 Server Certificate is:
[CN=mymachine,OU=GlassFish,O=Oracle Corporation,L=Santa Clara,ST=California,C=US]
Distinguished Name of the self-signed X.509 Server Certificate is:
[CN=mymachine,OU=GlassFish,O=Oracle Corporation,L=Santa Clara,ST=California,C=US]
No domain initializers found, bypassing customization step
Domain mydomain created.
Domain mydomain admin port is 55187.
Domain mydomain admin user is "admin".
Command create-domain executed successfully.

This will create a master-password file under

${glassfish_install}/glassfish/domains/mydomain/master-password

If you forgot to pass the --savemasterpassword flag when creating your domain you can still ask glassfish to generate this file for you by using the change-master-password command more info here

Just run the following command and enter the appropriate passwords when prompted. For this command to work the glassfish instance must be stopped

${glassfish_install}/bin/asadmin change-master-password --savemasterpassword 
Enter the new master password>
Enter the new master password again>
Command change-master-password executed successfully.
Note: If you did not specify a master password when you created your domain, the asadmin tool will use the default glassfish password : changeit

Glassfish asadmin without password

If like me you hate having to type your user/password combination every-time that you run the asadmin utility command you have 2 options

  1. Creating a password file and then using the --user --passwordfile options everytime you execute an asadmin command (ugh...)
  2. Using the asadmin login command and never think about your password again

Here's how you could implement both solutions :

1.- Creating the password file

First you will need to create a file following the directives that can be found here

AS_ADMIN_MASTERPASSWORD=mypassword
AS_ADMIN_USERPASSWORD=mypassword
AS_ADMIN_ALIASPASSWORD=mypassword
${glassfish_install}/glassfish/bin/asadmin  --user admin --passwordfile ${glassfish_install}/glassfish-password.txt list-applications mydomain

Now even though this works perfectly I find it a bit of a nag to have to write all this every-time I want to execute an asadmin command and sure I could write a bash script that wraps the underlying asadmin tool with the --user and --passwordfile options pre-generated but I just don't want to

2.- Using the asadmin login command

The one I prefer though is using the asadmin login command.

Basically what this command does is it prompts you for your glassfish credentials and then stores them in an encrypted file (.asadminpass) under the user's home folder

Here is how to use it :


${glassfish_install}/glassfish/bin/asadmin login 
Enter admin user name [default: admin]> admin
Enter admin password>
Login information relevant to admin user name [admin]
for host [localhost] and admin port [4848] stored at
[/home/user/.asadminpass] successfully.
Make sure that this file remains protected.

Once this is done you will be able to execute asadmin commands without being prompted for a password

${glassfish_install}/glassfish/bin/asadmin list-applications
Nothing to list.
Command list-applications executed successfully.

You can even store remote glassfish instances password by using the --host flag with the login command

[arte@arte-epg-api2 .ssh]$ /data/glassfish/bin/asadmin login --host myremotehost.com
Enter admin user name [default: admin]> admin
Enter admin password>
Login information relevant to admin user name [admin]
for host [myremotehost.com] and admin port [4848] stored at
[/home/user/.asadminpass] successfully.
Make sure that this file remains protected.

Glassfish cluster ssh node. Subsystem request failed error when creating a ssh node

Recently I stumbled upon a nasty and obscure error while configuring a glassfish 3.x cluster

I had all my ssh configuration properly in place with all my ssh keys between my nodes I could connect with no issues between the different machines by executing the ssh command :

[user@das~]$ssh machine1.com 

Even when I executed the asadmin command to setup the ssh configuration on the remote server everything comes up normally :

[user@das~]$ ./asadmin setup-ssh machine1.com
Successfully connected to user@achine1.com using keyfile /home/user/.ssh/id_rsa
SSH public key authentication is already configured for user@achine1.com
Command setup-ssh executed successfully.

But every-time I wanted to add a ssh node either by using the asadmin tool or the glassfish administration console I kept getting the following error message :

[user@das~]$ asadmin create-node-ssh --nodehost=machine1.com node1
remote failure: Warning: some parameters appear to be invalid.
SSH node not created. To force creation of the node with these parameters rerun the command using the --force option.
Could not connect to host machine1.com using SSH.
The subsystem request failed.
The server denied the request.
Command create-node-ssh failed.
Side-note: If you use the --force parameter as suggested by the asadmin tool, the create-ssh-node command will end successfully but problems will arise later

After searching for a bit I realized that the problem was with SSH configuration and not a really a glassfish error

As it turns out my hosting provider had disabled SFTP on the target machine's ssh configuration. Once found the solution was pretty simple, just un-comment or add the following line to your ssh_config file


Subsystem       sftp    /usr/libexec/openssh/sftp-server

You will probably need to restart sshd on the target machine

Once the sshd restarted head back to the DAS machine and try to create the ssh node again, if everything goes as planned you should get a similar output to this :

[das]asadmin create-node-ssh --nodehost=machine1.com node1
Command create-node-ssh executed successfully.

Context menu disappears in Intellij idea when right clicking and using eclipse keymap

As a former user of Eclipse I switched to the Eclipse keymap (the mac version can be found here) on Intellij Idea, but there was a bug that was pretty annoying, every-time i right clicked somewhere the context menu will quickly disappear unless I moved the mouse while clicking...

This was actually caused by a bug that was filled sometime ago and the workaround is pretty easy as stated in the bug page just remove the 'button3' mouse shortcut from the "show context menu" action in your IDE preferences

I made the small change to the XML file and filled a pull request with the author, so if it gets accepted it should take care of the bug

In any case you can either download the xml file once the pull request gets accepted or do it yourself from your IDE preferences as explained in the bug page :


Open Settings | Keymap, press Copy button to create an editable copy of the Eclipse keymap, in the copy find "Show Context Menu" action in the Other group, it has multiple shortcuts defined, delete "Button3 Click" from the list of shortcuts, press Apply. Context menu will no longer disappear after right click.

Redeploying to a remote glassfish with cargo (previous blog post follow up) - Solving the "application already registered error"

Sometimes right after you spent a whole day working on something (and blogging about it) you realize that there's actually an easier and faster way to accomplish the something.. d'oh (thank you very much brain

In my previous post here I was talking about an issue that I was having while trying to redeploy different versions of my application on the same glassfish context

To sum things up, the first time I deployed the application everything will work as expected but subsequent deployments will throw an error telling me that an application already exists for that context root (see message below) :

 Caused by: org.codehaus.cargo.util.CargoException: Deployment has failed: Action failed Deploying application to target server failed; Error occurred during deployment: Application with name myapp-1.4.8 is already registered. Either specify that redeployment must be forced, or redeploy the application. Or if this is a new deployment, pick a different name. Please see server.log for more details.

As it turns out you can use the cargo maven plugin to redeploy your application to your glassfish server as long as you still use the glassfish application versioning system described in my previous post, you can find more info on the versionning system here but basically glassfish will handle multiple versions of your application for a given context but having only 1 active at a given moment

You can exploit the versioning system by either using the naming convention {app-name}:{appVersion}.war or specifying the version in the glassfish deployment descriptor /WEB-INF/glassfish-web.xml

For some mysterious reason the I couldn't get the deployment working with the naming convention approach so I will be showing how to accomplish the remote redeployments using the deployment descriptor :

1.- Create deployment description (if necessary) and add the application version





    /myapp
    ${project.version}

2.- Configure your pom.xml

Once your deployment descriptor is configured you need to configure your pom.xml file to :

  1. Configure the maven war plugin to filter your deployment descriptor
  2. Configure your cargo plugin with the appropriate options corresponding to your environment


   4.0.0
   
      spring-mongodb:${project.version}
      
         ...
         
            org.apache.maven.plugins
            maven-war-plugin
            2.1.1
            
               false
               true
               
                  
                     ${basedir}/src/main/webapp/WEB-INF
                     true
                     WEB-INF
                     
                        **/glassfish-web.xml
                     
                  
               
            
         
         
            org.codehaus.cargo
            cargo-maven2-plugin
            1.1.2
            
               
                  glassfish3x
                  remote
               
               
                  runtime
                  
                     my-remote-glassfish.com
                     admin
                     mypass
                  
               
            
            
               
                  org.glassfish.deployment
                  deployment-client
                  3.1.1
               
            
         
         ...
      
   



3.- (Re)Deploy your application

Once you have your configuration files "configured" go to your command line (or configure a run goal in your favorite IDE) and run the following maven command (with your server started) :

   mvn clean package cargo:redeploy

If everything works as expected you should get the following output for your maven command

[INFO] --- cargo-maven2-plugin:1.1.2:redeploy (default-cli) @ spring-mongodb ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.208s
[INFO] Finished at: Thu Jul 04 20:35:06 CEST 2013
[INFO] Final Memory: 18M/221M
[INFO] ------------------------------------------------------------------------

Process finished with exit code 0
Note: Please be aware that every-time that you redeploy an app glassfish will enable the latest one (one enabled application per context) so if you don't want to keep older versions don't forget to periodically remove them with the asadmin command

Glassfish remote redeploy with maven and the mojo exec plugin

So a few days ago I run into a bug that took me almost a whole day to sort out..

I usually use cargo when I want to deploy an app to a running container but today I've spent several hours trying to make my app redeploy on a remote glassfish web profile server while working within my development/integration environment.

Just to give you some context in this environment I needed to continually deploy the same application on the same server but with different versions.

The first time I deployed the application everything will work as expected but subsequent deployments will throw an error telling me that an application already exists for that context root (see message below) :

 Caused by: org.codehaus.cargo.util.CargoException: Deployment has failed: Action failed Deploying application to target server failed; Error occurred during deployment: Application with name myapp-1.4.8 is already registered. Either specify that redeployment must be forced, or redeploy the application. Or if this is a new deployment, pick a different name. Please see server.log for more details.

Now the asadmin utility tool allows forcing a redeployment by using the --force=true option on the command line but it doesn't work if the WAR file name has changed as glassfish supports only one app per context root unless you use it in conjunction with Glassfish application versioning system but more on that later (see here)

I would argue that the "--force" param should deploy the WAR for a given context and overwrite the existing app regardless if you are using the versioning system or not but that's only my point of view

Side note : While doing some research on my problem I stumbled upon a forum post stating that when using the cargo:redeploy goal the --force=true parameter is used, at the moment I cannot find that blog post so I'm sorry..

So now let's get down to business, in this tutorial I will be showing how to use the codehaus maven exec plugin

Below are the steps that you should follow :

0.- Prerequisites

a. Glassfish versionning system naming conventions

Before beginning with this tutorial you must know that in order for it to work you need to use glassfish's versionning system with your applications otherwise it will always fail when trying to deploy an app for a given context but with a different war name (e.g. myapp-1.0.war -> myapp-1.1.war)

You can find more info on the versionning system here and here but basically glassfish will handle multiple versions of your application for a given context but allowing only 1 version of the application to be active at a given moment

For the versioning system to work you need to define a version for your WAR either in the glassfish-web.xml file or with the -name argument

In this tutorial we will be using the latest (the --name) argument

Please note that you need to respect a WAR file naming convention when versioning your applications (the value for the --name parameter), that convention is :

  {applicationName}:{applicationVersion}.war --> myapp:1.0.war
b. Access rights to Glassfish install path

You will also need to install(unzip) a glassfish instance in a place accessible to the the machine that will be executing the maven goal

c. Enabling asadmin secure admin feature

Lastly Glassfish's secure admin feature needs to be enabled in order to be allowed to do remote deploys; otherwise you will get an error message

[exec] HTTP connection failed with code 403, message

You can enable the secure admin feature by running the following command on your prompt (glassfish instance must be running)

  asadmin --host [host] --port [port] enable-secure-admin

Please note that you have to restart the glassfish instance in order for this functionality to be enabled.

1.- Installing a local glassfish instance

Go to the glassfish download website and download and unzip the appropriate glassfish version (ideally the same that the one of the remote server where you are trying to deploy your app) in a directory of your choice : e.g. /var/glassfish

2.- Defining the password file

You will then need to provide the asadmin tool with a password file since it's no longer supported as a command line argument

So go ahead and create a password file (let's name it glassfish.password) in the folder of your chice (e.g. /var/glassfish/). The file should be a properties files containing the following keys with the passwords values corresponding to your environment:

AS_ADMIN_MASTERPASSWORD=myPassword
AS_ADMIN_PASSWORD=myPassword
AS_ADMIN_USERPASSWORD=myPassword

Note: For this example the password will not be encrypted (you should encrypt it in your production environment). You can find more info on securing your master password in the glassfish documentation here here

3.- Configuring the exec plugin

Head up to your pom.xml file fire up your favorite editor and edit the POM file so it looks something like :





...

 /var/glassfish/bin/asadmin
  admin
  /var/glassfish/glassfish.password
  arte-epg-apipreprod.sdv.fr



....


   myapp
   
      
         org.codehaus.mojo
         exec-maven-plugin
         1.2.1
         
            ${glassfish.asadmin.executable}
            
               --user
               ${glassfish.user}
               --passwordfile
               ${glassfish.password.file}
               --host
               ${glassfish.remote.host}
               deploy
               --force=true
               --name=${project.build.finalName}:${project.version}
               --enabled=true
               ${project.build.directory}/${project.build.finalName}.war
            
         
         
            
               
                  exec
               
               verify
            
         
      
...
   


Please ensure that the value of the --name argument respects glassfish's application versioning naming conventions {appName}:{appVersion}.war

 mvn clean verify
Note: Here we are binding the execution of the goal to the verify phase but you can freely change that or use instead one of the plugin's goals directly from the command line.

4.- Sum-up and final thoughts

Firstly let me tell you that this method is probably not the cleanest way to get things done but for the time being, it will suffice... (at least to me :p)

Secondly, this is not a silver bullet, as sometimes I did encounter problems for example : if the database was not up and the application was marked as not enabled in the glassfish server, or the first time that I switched from deploying without glassfish versioning system to using glassfish's versioning system

Finally, I really don't like the fact that I need a local glassfish instance to deploy on a remote server, and I wonder if it's possible to achieve something similar using the glassfish deployment-client as a maven dependency and invoking the java classes inside the dependency or somehow extend the plugin to take into account force redeploys. So if I have some free time in the near future I will explore the possibility of accomplishing the same thing without needing a glassfish installed locally

Enabling reading stats on kobo devices with side loaded epubs

I'm a big fan of ereaders and I've own several of them, I currently own a Kobo Aura HD and I'm really happy with it, but there was something missing, something from the Kindle world that I really liked the "time remaining" feature

Kobo firmware 2.3 introduced some nice utilities, similar to what amazon brought with their Kindle Paperwhite, to enhance the reading experience, among them chapter pagination and "remaining time" for book and chapter

The issue with these features is that by default they are only available for EPUBs that you bought directly from Kobo since these are actually no longer EPUBs but KEPUBs (Kobo epubs) so that they can add these new gimmicks

But as usual Calibre comes to the rescue since someone has developed a plugin (which is actually an extended Kobo driver for calibre) that enables the Kobo specific stuff to side-loaded epubs

You can find it here and the mobileread thread where you can get more infos regarding this plugin

The plugin developer states that it should work with the Kobo Aura but that is "officially untested". Well I did test it with my Kobo Aura HD, and I can say (at least for the moment) that I had 0 issues with it and all works as expected ! (once I upgraded my Calibre version that was actually pretty stale)

OSX paste unformatted text / remove text formatting

So recently I found about what is for me one of the best keyboard shortcuts on OSX often I copy text from somewhere and whenever I paste it...