79

I would like to put JDK tools.jar as compile dependency. I found some examples that indicate to use the systemPath property like the following:

<dependency>
  <groupId>com.sun</groupId>
  <artifactId>tools</artifactId>
  <scope>system</scope>
  <systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>

The problem is that the path is not correct for Mac Os X (however it is correct for Windows and Linux). For it, the correct path is ${java.home}/../Classes/classes.jar.

I am looking for a way in order to define a maven property such that if system is detected as Mac Os X, value is set to ${java.home}/../Classes/classes.jar, otherwise it is set to ${java.home}/../lib/tools.jar (like it is possible to do with ANT). Does someone has an idea ?

Laurent
  • 12,925
  • 13
  • 47
  • 75
  • Possible duplicate of [Declare maven dependency on tools.jar to work on JDK 9](https://stackoverflow.com/questions/35240134/declare-maven-dependency-on-tools-jar-to-work-on-jdk-9) – user7610 Apr 11 '19 at 07:24
  • @user7610 This is not a duplicate, this question addresses the pre-Java 9 situation. The duplicate you suggest handles the post-Java 9 situation. – Mark Rotteveel Apr 12 '19 at 16:03

8 Answers8

47

That's what profiles are for, extract the path to a property, setup profiles for windows, OSX, etc, and define the property values appropriately.

Here's the doc page that discussing profiles for OSes: Maven Local Settings Model

It should endup looking something like this:

  <profiles>
    <profile>
      <id>windows_profile</id>
      <activation>
        <os>
          <family>Windows</family>
        </os>
      </activation>
      <properties>
        <toolsjar>${java.home}/../lib/tools.jar</toolsjar>
      </properties>
    </profile>
    <profile>
      <id>osx_profile</id>
      <activation>
        <os>
          <family>mac</family>
        </os>
      </activation>
      <properties>
        <toolsjar>${java.home}/../Classes/classes.jar</toolsjar>
      </properties>
    </profile>
  </profiles>
Matthias
  • 3,486
  • 2
  • 29
  • 38
sblundy
  • 58,164
  • 22
  • 117
  • 120
  • I'm running OS X 10.7 (Lion) and this worked for me, except the funny thing was I already had a *nix profile for linux boxes (unix). With both of those profiles in there, it was ignoring my profile for mac. So I could either change the path for the *nix profile entry or I had to comment out the profile for that profile so it would see my profile for mac – Mark J Miller Oct 17 '11 at 20:23
  • 3
    If you need to support both Apple Java 6 (`Classes/classes.jar`) and Oracle Java 7 (`lib/tools.jar`) on OS X, this won't work, but @Laurent's answer will. – Matt McHenry Dec 04 '12 at 21:48
  • 1
    http://stackoverflow.com/a/29585979 Seems to be a better answer for JDK 1.7, JDK 1.8, and El Capitan for me. – Paul Cunningham Feb 05 '16 at 16:25
  • what should be the path and name of this file ? – vivekanon Jun 07 '19 at 12:20
40

Thank you for introducing me maven profiles.

I have used profile as mentioned above and by activating a profile based on the presence of the desired file :

<profiles>
    <profile>
        <id>default-profile</id>
        <activation>
            <activeByDefault>true</activeByDefault>
            <file>
                <exists>${java.home}/../lib/tools.jar</exists>
            </file>
        </activation>
        <properties>
            <toolsjar>${java.home}/../lib/tools.jar</toolsjar>
        </properties>
    </profile>
    <profile>
        <id>mac-profile</id>
        <activation>
            <activeByDefault>false</activeByDefault>
            <file>
                <exists>${java.home}/../Classes/classes.jar</exists>
            </file>
        </activation>
        <properties>
            <toolsjar>${java.home}/../Classes/classes.jar</toolsjar>
        </properties>
    </profile>
</profiles>

I posted this answer to highlight a mistake in the previous post : the property section can only be used in activation section in order to activate a profile based on the existence of the specified property. In order to define a property, the properties section must be used like above.

Laurent
  • 12,925
  • 13
  • 47
  • 75
  • The good thing about the existence check of classes.jar is that it falls back to using tools.jar on the Mac platform. This might be important for future OpenJDK released on Mac ([link](http://openjdk.java.net/projects/macosx-port/)) as it would likely have a tools.jar and not classes.jar. – prunge Apr 12 '11 at 04:48
  • +1 because this tests for the actual file we are after and does not rely on OS detection (which is not necessary anyway) – Stefan Haberl Sep 09 '13 at 15:42
  • Closer, but http://stackoverflow.com/a/29585979 was a better solution ultimately (for JDK 1.7/1.8 and El Capitan) at least. – Paul Cunningham Feb 05 '16 at 16:26
9

Hi I know you guys are all smart, but it caused me couple of days to figure out the answer is not complete - both the profile and the dependency is necessary. I hope no one will waste time on this again. Please see my complete code below:

<profiles>
    <profile>
        <id>osx_profile</id>
        <activation>
            <activeByDefault>false</activeByDefault>
            <os>
                <family>mac</family>
            </os>
        </activation>
        <properties>
            <toolsjar>${java.home}/../Classes/classes.jar</toolsjar>
        </properties>
        <dependencies>
            <dependency>
                <groupId>com.sun</groupId>
                <artifactId>tools</artifactId>
                <version>1.6.0</version>
                <scope>system</scope>
                <systemPath>${toolsjar}</systemPath>
            </dependency>
        </dependencies>
    </profile>
</profiles>
Jianyu
  • 403
  • 5
  • 10
  • 2
    The `dependencies` section inside the profile is not necessary. It is enough to have this declared, once, outside of the profile and then have the profiles determine the correct value for the `toolsjar` property. – Edward Samson Oct 24 '12 at 01:54
  • 1
    This dependency is only needed for mac, better to only declare inside this profile – Jianyu Dec 01 '12 at 07:20
  • Shouldn't the line `${java.home}/../Classes/classes.jar` rather be `${java.home}/../lib/tools.jar` ? – Jens Jun 21 '13 at 08:28
7

Somehow, the eclipse in windows fails to pick up {java.home}. So, I had to set JAVA_HOME instead of java.home. JAVA_HOME was set in Run->Run Configurations->Environment. This worked for me with standard JDK(not Apple JDK).

<profiles>
        <profile>
            <id>windows-profile</id>
            <activation>
                <activeByDefault>true</activeByDefault>
                <file>
                    <exists>${JAVA_HOME}/lib/tools.jar</exists>
                </file>
            </activation>
            <properties>
                <toolsjar>${JAVA_HOME}/lib/tools.jar</toolsjar>
            </properties>
        </profile>
        <profile>
            <id>mac-profile</id>
            <activation>
                <activeByDefault>false</activeByDefault>
                <file>
                    <exists>${java.home}/../lib/tools.jar</exists>
                </file>
            </activation>
            <properties>
                <toolsjar>${java.home}/../lib/tools.jar</toolsjar>
            </properties>
        </profile>
    </profiles>


    <dependencies>
        <dependency>
                <groupId>jdk.tools</groupId>
                <artifactId>jdk.tools</artifactId>
                <version>jdk1.8.0</version>
                <scope>system</scope>
                <systemPath>${toolsjar}</systemPath>
            </dependency>
        </dependencies>
Animesh Sharma
  • 2,850
  • 1
  • 13
  • 29
  • 1
    This is an old question asked in many places. Because this is 2016 and I'm using El Capitan with JDK 1.7 and JDK 1.8 both installed it's my opinion that this is the simplest and cleanest way to resolve this problem in both STS (Eclipse) and Maven (command line) without having to create symlinks or somehow doctor the installed system. It worked the first time for me. :) :) :) – Paul Cunningham Feb 05 '16 at 16:21
7

I found a solution in Q: Declare maven dependency on tools.jar to work on JDK 9

As the actual maven wizardry is quite elaborate, surprising to newcomers and a subject of future improvements, it is better not co copy-paste it around. Hence this module exists so you do not have to know or care about the details. ~~ https://github.com/olivergondza/maven-jdk-tools-wrapper

<dependency>
  <groupId>com.github.olivergondza</groupId>
  <artifactId>maven-jdk-tools-wrapper</artifactId>
  <version>0.1</version>
</dependency>
user7610
  • 17,196
  • 7
  • 97
  • 120
1

The comment of Edward is correct.

You need the profile AND you need the dependency outside of the profiles block. The profile just determines which value ${toolsjar} is gonna get.

<dependencies>
    <dependency>
        <groupId>jdk.tools</groupId>
        <artifactId>jdk.tools</artifactId>
        <version>jdk1.8.0</version>
        <scope>system</scope>
        <systemPath>${toolsjar}</systemPath>
    </dependency>
</dependencies>
Marty
  • 598
  • 4
  • 21
0

Proper instructions for beginners

First Add this profile to Pom.xml file above tag or somewhere else in it.

<profiles>
    <profile>
        <id>default-profile</id>
        <activation>
            <activeByDefault>true</activeByDefault>
            <file>
                <exists>${java.home}/../lib/tools.jar</exists>
            </file>
        </activation>
        <properties>
            <toolsjar>${java.home}/../lib/tools.jar</toolsjar>
        </properties>
    </profile>
    <profile>
        <id>mac-profile</id>
        <activation>
            <activeByDefault>false</activeByDefault>
            <file>
                <exists>${java.home}/../Classes/classes.jar</exists>
            </file>
        </activation>
        <properties>
            <toolsjar>${java.home}/../Classes/classes.jar</toolsjar>
        </properties>
    </profile>
</profiles>

then Correct JRE path

Goto :

Windows > Preferecnes > Installed JREs

selected intalled JRE and double click on it or from right menu click edit and then make sure JRE Home path is inside JDK something like:

C:\Program Files\Java\jdk1.8.0_181\jre

if you have installed JRE seperatly then eclipse would have picked standalone JRE like:

C:\Program Files\Java\jre1.8.0_181\

so change it to JRE which come with JDK:

C:\Program Files\Java\jdk1.8.0_181\jre

user889030
  • 2,795
  • 2
  • 29
  • 41
-11

my solution:

  1. put the Sun's tools.jar to the $JAVA_HOME/lib
  2. make a symlink in the $JAVA_HOME/.. named lib where target will be $JAVA_HOME/lib
sra
  • 23,629
  • 7
  • 52
  • 88
toTem
  • 11
  • 1
  • 8
    It's not a good solution because it implies to perform some actions on each machine where the JAR file must be put in the classpath. – Laurent Aug 24 '10 at 18:09
  • I tried this and variations of this based on solutions I found elsewhere and did not get the results I expected. – Paul Cunningham Feb 05 '16 at 16:29