5

I have a java project which uses .properties files for configuration. On the server, when launching, I set the classpath to include a folder which contains all the properties files. On my local machine, I'd like to point to a different folder.

I'm looking to add to the classpath, ideally for all projects, but adding it to each project is also fine. I've tried changing the Run > VM Options to include classpath, but with that change it can't find the main class, and I get java.lang.NoClassDefFoundError. I've also tried changing nbactions.xml directly to set the classpath to -classpath ~\MyFolder\;%classpath, but this has the same problem.

To add to the difficulty, the server is running linux while my local machine is running Windows.

Dave
  • 44,275
  • 12
  • 65
  • 105
  • See my answer. It solve your problem in way that only NB configs are modified. I have same requirements as you and spent 2 hours in order to get working solution. Great question +1 – gavenkoa Mar 11 '15 at 16:33

5 Answers5

11

I stuck with topic-starter issue also for a long time. My goal - put config files for debug purpose in project root and extend classpath to ${basedir}, so this code:

String appConfigLocation = System.getProperty("config.location");
if (appConfigLocation == null) {
    logger.error("System property 'config.location' is not set...");
    System.exit(1);
}
InputStream appConfigStream = Main.class.getClassLoader().getResourceAsStream(appConfigLocation);
if (appConfigStream == null) {
    logger.error("Can't find resource {} in classpath, fix 'config.location'...", appConfigLocation);
    System.exit(1);
}
Properties appProps = new Properties();
try {
    appProps.load(appConfigStream);
} catch (IOException ex) {
    System.out.println("IO error during loading of {}...", appConfigLocation);
    System.exit(1);
}

read configs from ${basedir}. I like that instead of putting them to src/main/resources.

Check sources of ExecMojo.java for v1.2.1 http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.mojo/exec-maven-plugin/1.2.1/org/codehaus/mojo/exec/ExecMojo.java?av=f :

if ( CLASSPATH_TOKEN.equals( args[i] ) ) {
    commandArguments.add( computeClasspathString( null ) );
}

and and v1.3.2 http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.mojo/exec-maven-plugin/1.3.2/org/codehaus/mojo/exec/ExecMojo.java?av=f:

if ( args[i].contains( CLASSPATH_TOKEN ) ) {
     commandArguments.add( args[i].replace( CLASSPATH_TOKEN, 
                           computeClasspathString( null ) ) );
}

So update NB config Execute goals to new version:

process-classes org.codehaus.mojo:exec-maven-plugin:1.3.2:exec

and use complex -classpath args in exec.argsparams:

exec.args=-classpath %classpath:.:"${basedir}" \
    -Dconfig.location=app.properties \
    -Dlogback.configurationFile=logback.xml \
    ${packageClassName}

Fix any action you need to have such behavior:

enter image description here

See also:

gavenkoa
  • 45,285
  • 19
  • 251
  • 303
  • 2
    Jeyendran has posted a comment on this as an answer (likely due to insufficient rep to add comments), which I'll reproduce here in case it's useful to future visitors: Only change I had to do was replace the classpath separator ":" by ";" in the "-classpath" argument, because I am running on Windows. For Unix/Linux/Mac, ":" as described by @gavenkoa would work perfectly. – Dave Feb 10 '16 at 20:54
5

Hi I had a similar need to give NetBeans7.4 a classpath to a jar with a driver outwith Maven dependencies e.g. c:\Program Files\Java\jdk1.7.0_25\db\lib\derby.jar in a Java Maven project called MyProject.
As you were thinking with the Run > VM Options, I would suggest the following:
1) right-click on MyProject to open project Properties
2) in 'Project Properties' pop-up, select 'Actions'
3) locate 'Run pproject' among the 'Actions' and select it
4) edit in 'Set Properties' text box entering
exec.args=-cp %classpath;.;"c:\Program Files\Java\jdk1.7.0_25\db\lib\derby.jar" biz.letsweb.derbyconnect.App exec.executable=java exec.workingdir=c:\Users\Tomasz\Documents\NetBeansProjects\DerbyConnect\target\classes
Alternatively edit nbactions.xml analogically. Once I did this, I could simply run the project inside NetBeans by pressing green arrow.

  • `ExecMojo.java` has `if ( CLASSPATH_TOKEN.equals( args[i] ) ) { commandArguments.add( computeClasspath( null ) ); } ` so your `-cp %classpath;.;/path/to` isn't worked by design for 1.2.1 - which come with NetBeans 8.1, but already fixed in 1.3.2... So you need to update NB **execute goals** value. Se my answer. – gavenkoa Mar 11 '15 at 16:05
  • Yes! Was looking for this for days. – eggmatters Mar 15 '17 at 03:16
0

what about having the properties included as ? and those you use locally only have in a 's and activate that profile on local machine?

mkleint
  • 2,281
  • 1
  • 14
  • 17
0

This is how I've been adding classpath to many of my projects

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>com.nitinsurana.policereports.GUI</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
coding_idiot
  • 13,526
  • 10
  • 65
  • 116
  • Is it possible to set this up for only the local machine? I want one classpath for the server and another for local testing (as I said, one runs linux and the other Windows, so they don't translate very well) – Dave Nov 14 '13 at 12:57
  • you have to create separate profiles for each. [This](http://maven.apache.org/guides/introduction/introduction-to-profiles.html) can be a good start. – coding_idiot Nov 14 '13 at 13:26
0

An outside the box solution I ended up using for my similar case in NetBeans 7.3.1:

Adding files to java classpath at runtime

private static void addSoftwareLibrary(File file) throws Exception {
  Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
  method.setAccessible(true);
  method.invoke(ClassLoader.getSystemClassLoader(), new Object[]{file.toURI().toURL()});
}

This gives me a hacky way to add files to my classpath at run time via program arguments. Related notes I compiled while researching:


To include a dependency for compilation only, not runtime set: Dependency Scope

<dependency><scope>provided</scope>...</dependency>

To exclude a dependency from the shaded jar, set: Exclude

<exclude>groupId:artifactId[[:type]:classifier]</exclude>

To copy resources to the target directory from outside the typical source directory: Copy Resources

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.7</version>
        <executions>
          <execution>
            <id>copy-resources</id>
            <!-- here the phase you need -->
            <phase>validate</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>target/extra-resources</outputDirectory>
              <resources>          
                <resource>
                  <directory>extra-resources</directory>
                </resource>
              </resources>              
            </configuration>            
          </execution>
        </executions>
      </plugin>
    </plugins>
    ...
  </build>
  ...
</project>

Note that the base path for directory is the project home. The linked post has <filtering>true</filtering> which can cause "invalid mark" in Netbeans 7.3.1.

Community
  • 1
  • 1
DKATyler
  • 914
  • 10
  • 16