Friday, January 15, 2016

Set OS X Environment Variables

There are several ways to set environment variables for Mac OS X:
  • For command line applications running in a console / terminal
  • For GUI applications run from Spotlight (desktop)
  • For both command line and GUI applications

Here is a Stack Overflow thread discussing how to set environment variables:
Setting environment variables in OS X?

Set environment variables for command line applications in terminal


Edit .bash_profile or .profile or .bashrc in your user directory (~ or /Users/username), something like this:
# User specific environment and startup programs
 
PATH=/usr/local/bin:/usr/local/git/bin:$PATH:$HOME/bin
export ORACLE_HOME=/Users/myuser/Oracle/instantclient_11_2
export DYLD_LIBRARY_PATH=$ORACLE_HOME
export LD_LIBRARY_PATH=$ORACLE_HOME
#DYLD_LIBRARY_PATH=/Users/myuser/Oracle/instantclient_11_2/lib
 
export PATH
#export DYLD_LIBRARY_PATH
 
alias ll="ls -l"

Set environment variables for GUI applications


Note: Starting with Yosemite (version 10.10), this method is no longer used.  See the "DEPRECATED AND REMOVED FUNCTIONALITY" at the end when you "man launchctl".

Edit /etc/launchd.conf
sudo vi /etc/launchd.conf
Add environment variables like this:
# Set environment variables here so they are available globally to all apps
# (and Terminal), including those launched via Spotlight.
#
# After editing this file run the following command from the terminal to update
# environment variables globally without needing to reboot.
# NOTE: You will still need to restart the relevant application (including
# Terminal) to pick up the changes!
# grep -E "^setenv" /etc/launchd.conf | xargs -t -L 1 launchctl
#
# See http://www.digitaledgesw.com/node/31
# and http://stackoverflow.com/questions/135688/setting-environment-variables-in-os-x/
#
# Note that you must hardcode the paths below, don't use enviroment variables.
# You also need to surround multiple values in quotes, see MAVEN_OPTS example below.
 
#Java:
setenv JAVA_VERSION 1.7
#Mac OS X JAVA (1.6.0_65) is here:
#setenv JAVA_HOME /System/Library/Frameworks/JavaVM.framework/Home
#setenv JAVA_HOME /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
 
#JAVA 1.7 is here (see /usr/bin/java*):
setenv JAVA_HOME /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home
 
 
#Maven:
setenv M2_HOME /opt/maven
setenv MAVEN_OPTS "-Xmx1024M -XX:MaxPermSize=512m"
 
#Oracle:
setenv NLS_LANG /Users/myuser/Oracle/instantclient_11_2
#setenv ORACLE_HOME /Users/myuser/Oracle
#setenv DYLD_LIBRARY_PATH /Users/myuser/Oracle/instantclient_11_2
#setenv LD_LIBRARY_PATH /Users/myuser/Oracle/instantclient_11_2
#setenv TNS_ADMIN /Users/myuser/Oracle/instantclient_11_2/network/adminsetenv JAVA_HOME /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home
 
#Other:
setenv GROOVY_HOME /Applications/Dev/groovy
setenv GRAILS_HOME /Applications/Dev/grails
setenv NEXUS_HOME /Applications/Dev/nexus/nexus-webapp
setenv JRUBY_HOME /Applications/Dev/jruby
You can also set environment variables for applications started by Spotlight from the command line, although they will only be available until the computer is rebooted.  You do it like this:
launchctl setenv M2_HOME /opt/maven
It will be available to GUI applications that launch from Spotlight but will disappear when the computer is shut down.  If you want the environment variables to remain after rebooting edit /etc/launchd.conf.

Set Path


There is only one reliable way to set the path for both the command shell and the GUI.  Modify /etc/paths.
sudo vim /etc/paths

Mac OS X Screen Capture

How to take screen shots:

Capture entire screen: Cmd-Shift-3 (⌘⇧3)

Capture part of screen: Cmd-Shift-4 (⌘⇧4)
  • drag crosshair pointer to select the area
  • hold Shift (⇧) or Option (⌥) while you drag to resize selection
  • to cancel, press Esc before releasing mouse button
Capture specific window: Cmd-Shift-4 (⌘⇧4)
  • press Space bar
  • move camera pointer over window to highlight it, then click
For more flexible options including waiting a specified time to take screenshot, use the Grab app. Access it one of these 3 ways:
  • From Finder window, Applications > Utilities > Grab.app
  • Launchpad > Other > Grab
  • Spotlight, Cmd-Space bar (⌘Space bar) > Grab
See Mac keyboard shortcuts for more.

Maven Setup in IntelliJ IDEA

On Mac OS X

Mac OS X bundles its own version of Maven.  So does IntelliJ.  I installed a third, newer version, which is the one I use from the command line.

When I check which Maven I'm using on the command line ("which mvn") it shows /opt/maven/bin/mvn.

When I check the version ("mvn -v") it shows the Maven home directory is /opt/maven.

By default IntelliJ uses the Mac OS X-installed Maven.  This causes problems when creating a project from existing Maven sources (pom.xml) because it can't find the repository.

If you see numerous errors related to not being able to find or use dependencies when you compile a project with Maven in IntelliJ and you can see the .jar files it should be using are in the local repository (/Users/username/.m2/repository/...) but Maven can't see them, check which Maven it's using.

Navigate to IntelliJ IDEA > Preferences.  Select Build, Execution, Deployment > Build Tools > Maven.  The Maven home directory and version should be the same as the one reported when you do "mvn -v" and the User settings file and Local repository should typically be located under .m2 in your user home directory; for example, /Users/myuser/.m2/settings.xml and /Users/myuser/.m2/repository. If they are not, set them to the one you use.

If the directory is hidden, you can select the "Show Hidden Files and Directories" button.


Now you will be able to select a hidden directory.


For showing hidden files and directories in Finder (outside of IntelliJ), see "Show Hidden Folders / Directories in Finder".

When the maven home directory is selected, IntelliJ will display the version number so you can verify it.


Once Maven is set correctly in IntelliJ all the errors should resolve.

Thursday, January 14, 2016

No @XmlRootElement annotation

If you get "Expected elements are (none)" in a javax.xml.bind.UnmarshalException, you probably don't have an @XmlRootElement annotation in the Java object that your code is unmarshalling to.

For example, this error:
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"customer"). Expected elements are (none)
when unmarshalling this XML:
<?xml version="1.0" encoding="UTF-8"?>
<customer id="100">
    <age>23</age>
    <name>Daffy Duck</name>
</customer>
to this class, is fixed by adding the annotation @XmlRootElement to the class so it looks like this:
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "customerType", propOrder = {
        "id",
        "name",
        "age"
})
public class Customer {

    @XmlElement
    String name;
    @XmlElement
    int age;
    @XmlAttribute
    int id;

}

Web Services With JSON and XML

XML and JSON are the most popular formats for exchanging data over the Internet.  JSON has become more popular recently because it's less verbose than XML.  For example, this XML:
<geonames>
    <country>
        <countrycode>AD</countryCode>
        <countryname>Andorra</countryName>
    </country>
    <country>
        <countrycode>AR</countryCode>
        <countryname>Argentina</countryName>
    </country>
</geonames>
Looks like this in JSON:
{"geonames": [
    {
        "countryCode": "AD",
        "countryName": "Andorra"
    },
    {
        "countryCode": "AR",
        "countryName": "Argentina"
    }
]}
JSON uses fewer characters, takes up less space and is easier to read.

Because JSON and XML representations of data can be used almost interchangeably, many web services are offered in both versions for convenience.  Here are a couple showing postal codes in London's W1J postal area:

XML:
http://api.geonames.org/postalCodeSearch?postalcode=W1J&maxRows=2&username=demo

JSON:
http://api.geonames.org/postalCodeSearchJSON?postalcode=W1J&maxRows=2&username=demo

They have slightly different URL endpoints, postalCodeSearch and postalCodeSearchJSON, and they return the same data, just in different formats.

Using Java to Produce and Consume RESTful Web Services


Java is one of the oldest and most popular languages for web development, especially for applications deployed on web servers. It includes packages to simplify producing and consuming RESTful web services. In addition, there are many popular Java community-built APIs for web services. Some of the APIs are so popular that they have been incorporated into the Java JDK.

JAXB - Java Architecture for XML Binding


Java objects can be serialized into an XML string using JAXB. Likewise, an XML string that represents a Java object can deserialized into a Java object. Serializing is called "marshalling" and deserializing is called "unmarshalling". Java classes to be marshalled into XML are marked up using annotations from the javax.xml.bind.annotation.* namespace, for example, @XmlRootElement and @XmlElement.

JAXB includes a couple tools to simplify creating annotated Java classes or XML schemas:

xjc - creates annotated Java classes from an XML schema (XSD file)

schemagen - creates an XML schema from annotated Java classes

See here for examples and usage.

(show example Java class, XML and XML schema)

JAX-RS - Java API for RESTful Web Services


JAX-RS is the Java API for RESTful Web Services that simplifies creating and consuming web services using XML and JSON.  There are several popular implementations:
I'll talk about Jersey because it's the one I know best.  I use Jersey 1.19, the last version of Jersey before version 2. Version 2 has features I don't find useful.

Jersey uses a reference implementation (RI) of JAXB version 2.x or higher to serialize Java objects to XML and deserialize XML to Java objects.

Since JAXB 2.x or higher is included in the Java JDK starting with Java 6, no additional dependency is required if you're using Java 6, 7, 8 or higher.  Here are the versions of JAXB included with Java 6 and 7.

To serialize the JAXB beans (Java classes) to JSON and deserialize JSON to JAXB beans when using the MIME media type application/json, you do need to include an additional dependency. With Maven, it looks like this:
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-json</artifactId>
    <version>1.19</version>
</dependency>
See 11.4.1.1. JAXB RI (reference implementation) for more.

Jersey XML Support

Jersey JSON Support





Set Cmder (ConEmu) console emulator to open new tab in current directory with Bash shell

Windows is a truly bad operating system for almost everything except games. Unfortunately sometimes we have to use it for web development. I...