This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 65450 - Doc to avoid setting of multiple classpathes with Free-Form Ant project
Summary: Doc to avoid setting of multiple classpathes with Free-Form Ant project
Status: NEW
Alias: None
Product: java
Classification: Unclassified
Component: Freeform (show other bugs)
Version: 5.x
Hardware: All All
: P3 blocker (vote)
Assignee: Tomas Zezula
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-09-29 22:43 UTC by oneway
Modified: 2010-01-11 04:28 UTC (History)
0 users

See Also:
Issue Type: ENHANCEMENT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description oneway 2005-09-29 22:43:11 UTC
Build 200509261930, JDK 1.5.0_05

An ant based project was successfully compiled.

Source package folder in the "Output" tab of the project properties shows
correct source folder. However, the editor still red-underlines (i.e. cannot
find symbol error) classes from the source forlder.
Comment 1 oneway 2005-09-30 01:13:34 UTC
I can debug the project and NB has no problem steping into the classes that are
shown in the editor with "Cannot find symbol" error.
Comment 2 Tomas Hurka 2005-10-04 12:54:34 UTC
Please attach your project so we can find out what is wrong. Thanks.
Comment 3 oneway 2005-10-09 03:50:29 UTC
$ cd nbproject

-------------------------------------------------------------------
$ cat project.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
    <type>org.netbeans.modules.ant.freeform</type>
    <configuration>
        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
            <!--Do not use Project Properties customizer when editing this file
manually.-->
            <name>Vcp</name>
            <properties>
                <property name="ant.script">src/ant/build.xml</property>
            </properties>
            <folders>
                <source-folder>
                    <label>src/main</label>
                    <type>java</type>
                    <location>src/main</location>
                </source-folder>
                <source-folder>
                    <label>src/test</label>
                    <type>java</type>
                    <location>src/test</location>
                </source-folder>
            </folders>
            <ide-actions>
                <action name="build">
                    <script>${ant.script}</script>
                    <target>build</target>
                </action>
                <action name="clean">
                    <script>${ant.script}</script>
                    <target>clean</target>
                </action>
                <action name="run">
                    <script>${ant.script}</script>
                    <target>run</target>
                </action>
                <action name="rebuild">
                    <script>${ant.script}</script>
                    <target>clean</target>
                    <target>build</target>
                </action>
                <action name="debug">
                    <script>nbproject/ide-targets.xml</script>
                    <target>debug-nb</target>
                </action>
            </ide-actions>
            <export>
                <type>folder</type>
                <location>build/main</location>
                <script>${ant.script}</script>
                <build-target>build</build-target>
            </export>
            <export>
                <type>folder</type>
                <location>build/test</location>
                <script>${ant.script}</script>
                <build-target>build</build-target>
            </export>
            <view>
                <items>
                    <source-folder style="packages">
                        <label>src/main</label>
                        <location>src/main</location>
                    </source-folder>
                    <source-folder style="packages">
                        <label>src/test</label>
                        <location>src/test</location>
                    </source-folder>
                    <source-file>
                        <location>${ant.script}</location>
                    </source-file>
                </items>
                <context-menu>
                    <ide-action name="build"/>
                    <ide-action name="clean"/>
                    <ide-action name="run"/>
                    <ide-action name="rebuild"/>
                    <ide-action name="debug"/>
                </context-menu>
            </view>
            <subprojects/>
        </general-data>
        <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
            <compilation-unit>
                <package-root>src/main</package-root>
                <classpath mode="compile">src/main</classpath>
                <built-to>build/main</built-to>
                <source-level>1.5</source-level>
            </compilation-unit>
            <compilation-unit>
                <package-root>src/test</package-root>
                <unit-tests/>
                <classpath mode="compile">src/test</classpath>
                <built-to>build/test</built-to>
                <source-level>1.5</source-level>
            </compilation-unit>
        </java-data>
    </configuration>
</project>


-------------------------------------------------------------------
# cat ide-targets.xml

<?xml version="1.0" encoding="UTF-8"?>
<project basedir="../src/ant" name="Rc-IDE">
    <import file="../src/ant/build.xml"/>
    <!-- TODO: edit the following target according to your needs -->
    <!-- (more info:
http://www.netbeans.org/kb/41/freeform-config.html#debugj2se) -->
    <target depends="compile,set.run.props" description="Debugs project"
name="debug-nb">
        <nbjpdastart addressproperty="jpda.address" name="Rc" transport="dt_socket">
            <classpath refid="project.compile.classpath"/>
        </nbjpdastart>
        
        <java classname="test.Test" failonerror="true" fork="true">
            <jvmarg line="${run.args.jvm}"/>
            <classpath refid="project.compile.classpath"/>
            <arg line="${run.args.application}"/>
            
            <jvmarg value="-Xdebug"/>
            <jvmarg value="-Xnoagent"/>
            <jvmarg value="-Djava.compiler=none"/>
            <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
        </java>
        
    </target>
</project>
Comment 4 Tomas Hurka 2005-10-10 08:41:51 UTC
I am sorry, but I need your zipped project folder to reproduce it. The files you
pasted to the comments window do not help me to track the problem.
Comment 5 oneway 2005-10-11 00:51:51 UTC
The problem is that the project folder contains code that I cannot distribute.
I'll see if I can build some test project but that may take time. If you have
other ideas, feel free...
Comment 6 oneway 2005-10-13 08:09:48 UTC
I think I know what the problem is.

I have an ant build.xml file that defines how the project is built, compilation
targets, run targets, etc., all with proper classpathes.

Currently, it is necessary to redefine those classpathes AGAIN, at least 2+
times (in my case 4 times since java code is located in 2 directories), when
creating Ant based project. This is really, really bad since it create a great
opportunity for errors.

At the very least, why can't I specify the classpath defined in the Ant file
instead of specifying all directories and JARs one-by-one?

Ideally, NB should get all necessary information from the Ant file itself.
Comment 7 oneway 2005-10-13 08:15:57 UTC
> Currently, it is necessary to redefine those classpathes AGAIN, at least 2+
> times (in my case 4 times since java code is located in 2 directories)

2 directories for "Java Sources Classpath" tab + 2 directories for "Output" tab
= 4 times classpathes have to be defined.

There has got to be a better way than this.
Comment 8 Tomas Hurka 2005-10-13 11:43:20 UTC
Thanks for the info. 

Reassignign to freeform project for evaluation. 
Comment 9 oneway 2005-10-18 14:41:17 UTC
> 4 times classpathes have to be defined

Actually, I was wrong, classpathes have to be (re!)defined 5 times, I forgot
nbproject/ide-targets.xml. There, at least, it allows to specify the classpath
from build.xml.

In my opinion, this is really, really, really bad. Is this really necessary? All
information is available in the build file:

1) Java Source: defined compile target
2) Java Source classpath: defined compile target (BTW, what is the point of
defining separate classpathes for "source" and "test" packages. Their both
require practically the same classpath
3) Output: classpath defined in the run target

Am curious if I can do "<import file="../build.xml"/>" in the
nbproject/project.xml and reuse classpathes defined there and thus avoid using
this "wizard" completely.
Comment 11 Jan Lahoda 2005-10-25 17:22:40 UTC
Hello,
    I am sorry but this is how it currently works. I do not think this is a
defect, and we will not be able to do anything about this for 5.0.

You are right that all the information is (somehow) in the build script, but it
is not simple to gather it from the build.xml (in general, it is algorithmically
insolvable). Consider simple (and not so unusual) example: the classpath for
javac is constructed in a target called "init", the classpath "cp.path" is
defined as "${lib1}/dist/lib1.jar:${lib2}/dist/lib2.jar". The properties lib1
and lib2 are defined in a properties file, that is load using <properties>
command in a "basic-init" target. Simply looking at the javac task invocation
(in target called "compile"):
<javac>
    <classpath>
        <path path="${cp.path}"/>
    </classpath>
</javac>
does not help much (you would have to parse dependencies for target "compile",
parse&analyze what is happening in the "init" and "basic-init" targets, etc.)

I agree that it would be nice if there would be some heuristics that would try
to guess correct classpaths from the build script but it would certainly support
only a subset of build scripts. Unfortunatelly, I do not have enough resources
to write and maintain this heuristics.

You can however import your <something>.properties in the project.xml (so you
set the classpath only once in the <something>.properties) using the properties
element like:
<properties>
  <property-file>my-properties-file.properties</property-file>
</properties>

Unfortunatelly, this has to be done manually and you cannot use project
customizer once you modified the project.xml by hand. See
http://www.netbeans.org/kb/articles/freeform-config-40.html
for more information.
Comment 12 oneway 2005-10-25 18:12:24 UTC
> You are right that all the information is (somehow) in the build script, but it
> is not simple to gather it from the build.xml (in general, it is algorithmically
> insolvable).

True, it may not be easy to guess what classpath should be used. In this case,
let the DEVELOPER specify what classpath, FROM THE ANT BUILD FILE, he wants to
use instead of forcing him to map it AGAIN, MANUALLY, USING GUI. For Pete's
sake, this is an ANT BASED project!

> You can however import your <something>.properties in the project.xml (so you
> set the classpath only once in the <something>.properties) using the properties
> element like

Why can't I import classpath from the build file? (I tried and I couldn't get it
to work) It's there, ready to be used. The whole point of this discussion is
that I'm trying to have ONLY ONE place where classpath is defined. Why?

You may not realize this but people work on many projects with fairly complex
classpathes that have many (2+) source directories. It's a f**ing torture having
to redefine the classpath and map it again and again and again. The classpathes
get out synch, it leads to subtle and difficult to find errors.

It's a critical non-usability issue that, in my opinion, must be fixed before
NB5 comes out.

Also, think about this. Do you really need separate classpathes for sources,
output/run and debug? Do you really need separate classpathes for main and test
sources? I really doubt it. They may be different somewhat but having a couple
of unused JARs on the classpath in not going to make any difference. NB3.6 had
only one classpath and it was hell of a lot easier to work with than NB5.

AGAIN, PLEASE FIX THE ANT PROJECT CLASSPATH ISSUES IN NB5.
 
At the very least, let import classpathes from build.xml (by manually editing
the project.xml or whatever). The same applies to ide-file-targets.xml. If
classpath relies on properties file used in build.xml, then that classpath
cannot be used (does not work) in ide-file-targets.xml (I think it used to work
but not any more - in build 200510201800).
Comment 13 Jan Lahoda 2005-10-25 18:46:24 UTC
>Why can't I import classpath from the build file? (I tried and I couldn't get it
>to work) It's there, ready to be used. The whole point of this discussion is
>that I'm trying to have ONLY ONE place where classpath is defined. Why?

The same reason: it would be necessary to parse&understand the build.xml. It is
(relativelly) simple to load&resolve properties, but it is quite hard to
parse&analyze the build script (without actually running it). Imagine task
"prepareclasspath" which computes the classpath based on some external
information: how the IDE could understand what does this task do (without
actually running it)? AFAIK, you can have the classpath defined on one place,
but it has to be a properties file.

>You may not realize this but people work on many projects with fairly complex
>classpathes that have many (2+) source directories. It's a f**ing torture having
>to redefine the classpath and map it again and again and again. The classpathes
>get out synch, it leads to subtle and difficult to find errors.

It should be possible to specify only one classpath for all (two or more) source
roots, see issues #65708 and #60558.

I do not quite understand what you say about the output. In the output, you
should not set any classpath, simply a directory(ies) and jar file(s) into which
the class files are stored (products of compilation).
Comment 14 oneway 2005-10-25 19:56:08 UTC
> but it is quite hard to parse&analyze the build script (without actually
running it).

I actually hoped that you COULD run it. Maybe you could require that there must
be a special build task that prepares the classpath. That sounds like a
resonable and easy requirement to me. In this case, you could run build file up
to a point, could you not?

> AFAIK, you can have the classpath defined on one place,
> but it has to be a properties file.

Yes, I may have to do that. The problem is that, currently, my classpath is
prepared using something like this

    <target name="set.classpath"
            description="Sets compile classpath">
        <path id="project.classpath">
        <fileset dir="${lib.dir}">
            <include name="*.jar"/>
        </fileset>
    </target>
    
That's very convinient, you just drop/replace a jar and that's all you have to
do, no editing. Obviously, I will not be able to do that in the properties file,
I will have to REMEMBER to edit a separate (from build.xml) properties file
EVERY TIME I make a change to project's jars.

Another problem, as you pointed out, is that I'll have to learn the project.xml
format since I'll have to edit it by hand from that point on.
Comment 15 Jan Lahoda 2005-10-26 21:08:34 UTC
>I actually hoped that you COULD run it. Maybe you could require that there must
>be a special build task that prepares the classpath. That sounds like a
>resonable and easy requirement to me. In this case, you could run build file up
>to a point, could you not?

Although this could theoretically work, there are many practical problems (when
the build script should be run? how to get the output from it? the user would
have to specify the target to run (cannot automagically start "random" target in
the script because the targets could have fatal side-effect) and confirm, even
in case of "simple" setting classpath the build may run for a long time,
probably many more).

>That's very convinient, you just drop/replace a jar and that's all you have to
>do, no editing. Obviously, I will not be able to do that in the properties file,
>I will have to REMEMBER to edit a separate (from build.xml) properties file
>EVERY TIME I make a change to project's jars.

Why can't you extend the "set.classpath" target to generate a properties file
that would contain the classpath? The properties file would be always up-to-date
after you do the build, generated automatically, etc.
Comment 16 oneway 2005-11-12 18:53:55 UTC
I got it workig by extending "set.classpath", as it was suggested.

I think this needs to be written up as a FAQ item or something, it'll save
people a lot of time.
Comment 17 Antonin Nebuzelsky 2010-01-11 04:28:45 UTC
Changing the default component owner to tzezula.