Eclipse classpath entries only used for tests - java

In Maven, you can have compile-time dependencies and test dependencies. This is a feature I love, and the M2Eclipse plugin makes this available in Eclipse, too, which is great. So if I add jmock.jar to my project as a test dependency, it will show up on the classpath for JUnit tests, but won't be present when I'm debugging the application itself.
This is exactly what I'd like to achieve now, but without M2Eclipse or Maven. Is there a way to do this in plain Eclipse? (Possibly without installing any plugins.)

You could separate all your tests into another project and add the main project as a dependency (Project->Properties->Java Build Path->Projects->Add...)
Update: To avoid changing the original project structure, your test projects can use linked locations.
Create the test project as normal, you now need to create a linked resource to bring in the src/test/java folder. It is best to create it using a variable so that your projects can retain some platform independence.
To create a new linked folder select New->Folder, input src in the folder name: field then click Advanced>>
Click Link to folder in the file system
Click on Variables... to bring up the Select Path Variable dialogue.
If this is your first time, or you are linking to a new location select New... and give the variable a sensible name and path. If all your projects are located in c:\workspaces\foo** it makes sense to call the variable **WORKSPACE_ROOT and give it that path. If you have some other convention that is fine, but it makes sense to put a comment in the .project file so someone has a chance of figuring out what the correct value should be.
Assuming the values above you can now set a value of WORKSPACE_ROOT/[subject project name]/src on the input field
Once you confirm that you should see the src folder with a little arrow, and if you look in the .project file see something like this:
<linkedResources>
<link>
<name>src</name>
<type>2</type>
<locationURI>WORKSPACE_ROOT/esf-ns-core-rp/src</locationURI>
</link><!--NOTE the WORKSPACE_ROOT variable points to the folder containing the subject project's sandbox-->
</linkedResources>
You can now add the src/test/java folder as a source location as normal.
Note you can also share just the src/test/java folder by changing the config to something like this:
<linkedResources>
<link>
<name>src/test/java</name>
<type>2</type>
<locationURI>WORKSPACE_ROOT/my-project/src/test/java</locationURI>
</link>
</linkedResources>
This gives more control over the config, but you would have to repeat for src/test/resources, src/it/java etc.
You then set all the test dependencies only in the test project.
Very not pretty, but it does work (I've also used this where my test compliance level is different to the main compliance level, e.g. 1.5 for tests, but 1.4 for the target environment).

I'm afraid the answer is that you can't. There are 2 open issues which were postponed from 3.5 related to your problem:
Ability to mark source folder as test sources
[buildpath] Should be able to ignore warnings from certain source folders

Since you use both Eclipse and Maven you can workaround it.
Create a new "Maven Build" run configuration with goal "exec:java" and parameters "exec.mainClass=com.example.Starter". This way the classpath will be calculated by Maven.

Actually if you look in eclipse as to how Maven integrates dependencies it will not make the difference in test or runtime dependencies your test libraries are always accessible.
Maven will keep the difference when packaging the application and when it generates the runtime classpath if maven has control over the execution of that part. When eclipse is concerned Maven simply adds them all without question to the eclipse build path.
Why is it you need to have this separated like so ? What will this help you acheive ?

Eclipse Photon finally added this feature, with m2e support for it.

Related

How can I tell from a JUnit test whether an Eclipse project is open?

I need to run Maven from the command line while Eclipse is open. Since this can confuse Eclipse, I configured the two to use different output folders (Maven writes to target, Eclipse m2e uses target-eclipse). This works very well.
But in one of my unit tests, I need to load classes which are part of a project but not on the classpath. Basically, I build my own URL classloader. Now, I have a problem: Which class folder to add?
If the project is open, target-eclipse/classes is the correct choice, otherwise I should use target/classes.
Assume that I know the Eclipse folder and the workspace folder. How can I tell from Java code running in a child process of Eclipse (not an Eclipse plugin) which projects are open and which aren't?
The existence of the folder is not a good criteria since the folder isn't deleted when I close a project.
[EDIT] Basically my question is: Eclipse must store that information somewhere in $workspace/.metadata or in $ECLIPSE_HOME/configuration. In which file do I need to look?
A file [Workspace_Home]/.metadata/.lock tells You the workspace is open.
The list and settings of projects in the workspace are in [Workspace_Home]/.metadata/.plugins/org.eclipse.core.resources/.projects.
It seems like open Java projects have a folder [Workspace_Home]/.metadata/.plugins/org.eclipse.core.resources/.projects/[Project_name]/.indexes, and closed don't have it. - I double checked it, and it seems I was wrong here.
But I just checked that closed Java projects have a file: [Workspace_Home]/.metadata/.plugins/org.eclipse.core.resources/.projects/[Project_name]/org.eclipse.jdt.core/state.dat, and open projects don't have it.
I would just use some configuration parameter (a system property for example), telling where the folder is. See http://maven.apache.org/plugins/maven-surefire-plugin/examples/system-properties.html for how to pass system properties when running tests with Maven. The first example in this page shows how to pass the build directory as a system property.

Definining user libraries in Eclipse as part of a project and not a workspace

I saw that in Eclipse I can define User Libraries - to make setting the classpath easier (and probably for other reasons as well).
The problem is, that these libraries are only available in the workspace, and if I want other people using the same project to use them - I need to export my user library and they need to import it.
Is there any functionality like this on the project level? I basically need to have a 'classpath group' - can it be done?
If not, is there an automatic way to auto import the user library to the workspace when importing the project?
I'm using Eclipse 3.6.
JDT has the 2 concepts, user libraries and classpath variables. In the classpath variable, you can add jars to your project. Other team members have to fill in the variables in their workspace so their classpath is complete. This is useful when external jars might be in different locations on each team members local file system.
The USER_LIBRARY is a container for adding a logical group of local jars all at once. For example, the JRE_LIB container represents a number of local jars. But as you've seen, it points to a local set of jars meant to be used in multiple projects (as the JRE is added to multiple projects).
Aside from export/import (which you're already doing), I don't believe you can check CLASS_LIBRARIES into a project's SCM. If there was, the preference page would have a "Configure Project specific settings" link at the top.
Your best bet is to simply add the jars to the project, so they'll be included in the SCM. If they can be in different locations depending on the rest of your team, then use a classpath variable so it can be set in each workspace. That's the least amount of hassle as far as team members checking out the project and being ready to go.
The best way IMO is to use m2eclipse - Maven plugin for eclipse. In Maven all the dependencies are defined in pom.xml and downloaded automatically as needed. This means that the only thing you share with your team is pom.xml - your project definition.
There is a lot more advantages when using m2eclipse vs standard eclipse approch. More information is at http://www.sonatype.com/books/m2eclipse-book/reference/
The way I have used user libraries is for something like Ant. Define a user library "ant" for all the jars in ANT_HOME/lib. If including this in your Eclipse .classpath and then sharing with other users, they will get a build problem report until they create that "ant" user library themselves. It's useful, but you need to share knowledge on how to create the library. If you're using it for simple cases like above, then instructions for adding the right jars to the library are straightforward.
Another approach I've used is to build classpaths pointing into a folder (or folders) defined as a variable in Eclipse. See File -> New Folder -> Advanced -> Link to folder in the file system -> Variables. This lets you setup (again at workspace level) variable references to one or more folders. You can then build your Eclipse classpath/s with reference to the folder/s.
So say in your development environment, everyone needs to have a directory called "thirdparty" containing all the external jars dependencies (probably in hierarchy within that dir: thirdparty/apache; thirdparty/sun; ...). You define "thirdparty" as a variable pointing to wherever that dir is on your current system, you create a folder in your project/s using the variable. You can then setup (and share) classpath using paths into that folder.
It's similar to User Library and with similar limitations. The limitation is that the other users you share your project with must create variable folder/s as you have. But it's more flexible in that they don't have to add the jars explicitly as they do with a library; rather, your classpath/s in Eclipse point into the folder, as required for each project.
Note that although the folder variable is defined at workspace level, it can be reused in multiple projects, each of which builds their classpaths (.classpath files) with different references into the folder).
This is maybe something easier to show than to describe with words, but I hope it makes sense.

Add a properties file to IntelliJ's classpath

I'm running a simple Java program from the IntelliJ IDE using the Run->Run menu. It works fine. Now I want to add log4j logging.
I added a resources folder under my project root.
I added a log4j.properties file in that folder.
I changed the code to log something.
What is the right way to tell IntelliJ to include the resources folder in the classpath so the properties file is seen?
With IntelliJ 8 I could guess like a drunk monkey and eventually get it to work. I have 9 now and I am wholly unsuccessful. I've been trying for an hour. How about an "Add to classpath" option somewhere? /fume /vent /rant
Try this:
Go to Project Structure.
Select your module.
Find the folder in the tree on the right and select it.
Click the Sources button above that tree (with the blue folder) to make that folder a sources folder.
Actually, you have at least 2 ways to do it, the first way is described by ColinD, you just configure the "resources" folder as Sources folder in IDEA. If the Resource Patterns contains the extension of your resource, then it will be copied to the output directory when you Make the project and output directory is automatically a classpath of your application.
Another common way is to add the "resources" folder to the classpath directly. Go to Project Structure | Modules | Your Module | Dependencies, click Add, Single-Entry Module Library, specify the path to the "resources" folder.
Yet another solution would be to put the log4j.properties file directly under the Source root of your project (in the default package directory). It's the same as the first way except you don't need to add another Source root in the Module Paths settings, the file will be copied to the output directory on Make.
If you want to test with different log4j configurations, it may be easier to specify a custom configuration file directly in the Run/Debug configuration, VM parameters filed like:
-Dlog4j.configuration=file:/c:/log4j.properties.
I have the same problem and it annoys me tremendously!!
I have always thought I was surposed to do as answer 2. That used to work in Intellij 9 (now using 10).
However I figured out that by adding these line to my maven pom file helps:
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
...
</build>
I spent quite a lot of time figuring out how to do this in Intellij 13x. I apparently never added the properties files to the artifacts that required them, which is a separate step in Intellij. The setup below also works when you have a properties file that is shared by multiple modules.
Go to your project setup (CTRL + ALT + SHIFT + S)
In the list, select the module that you want to add one or more properties files to.
On the right, select the Dependencies tab.
Click the green plus and select "Jars or directories".
Now select the folder that contains the property file(s). (I haven't tried including an individual file)
Intellij will now ask you what the "category" of the selected file is. Choose "classes" (even though they are not).
Now you must add the properties files to the artifact. Intellij will give you the shortcut shown below. It will show errors in the red part at the bottom and a 'red lightbulb' that when clicked shows you an option to add the files to the artifact. You can also go to the 'artifacts' section and add the files to the artifacts manually.
Faced a similar challenge adding files with .ini extensions to the classpath. Found this answer, which is to add it to Preferences -> Compiler -> Resource Patterns -> [...] ;*.ini
If you ever end up with the same problem with Scala and SBT:
Go to Project Structure. The shortcut is (CTRL + ALT + SHIFT + S)
On the far left list, choose Project Settings > Modules
On the module list right of that, select the module of your project name (without the build) and choose the sources tab
In middle, expand the folder that the root of your project for me that's /home/<username>/IdeaProjects/<projectName>
Look at the Content Root section on the right side, the red paths are directories that you haven't made. You'll want to put the properties file in a Resources directory. So I created src/main/resources and put log4j.properties in it. I believe you can also modify the Content Root to put it wherever you want (I didn't do this).
I ran my code with a SBT configuration and it found my log4j.properties file.
For those of you who migrate from Eclipse to IntelliJ or the other way around here is a tip when working with property files or other resource files.
Its maddening (cost my a whole evening to find out) but both IDE's work quite different when it comes to looking for resource/propertty files when you want to run locally from your IDE or during debugging. (Packaging to a .jar is also quite different, but thats documented better.)
Suppose you have a relative path referral like this in your code:
new FileInputStream("xxxx.properties");
(which is convenient if you work with env specific .properties files which you don't want to package along with your JAR)
INTELLIJ
(I use 13.1 , but could be valid for more versions)
The file xxxx.properties needs to be at the PARENT dir of the project ROOT in order to be picked up at runtime like this in IntelliJ. (The project ROOT is where the /src folder resides in)
ECLIPSE
Eclipse is just happy when the xxxx.properties file is at the project ROOT itself.
So IntelliJ expects .properties file to be 1 level higher then Eclipse when it is referenced like this !!
This also affects the way you have to execute your code when you have this same line of code ( new FileInputStream("xxxx.properties"); ) in your exported .jar.
When you want to be agile and don't want to package the .properties file with your jar you'll have to execute the jar like below in order to reference the .properties file correctly from the command line:
INTELLIJ EXPORTED JAR
java -cp "/path/to_properties_file/:/path/to_jar/some.jar" com.bla.blabla.ClassContainingMainMethod
ECLIPSE EXPORTED JAR
java -jar some.jar
where the Eclipse exported executable jar will just expect the referenced .properties file to be on the same location as where the .jar file is
Right-click on your directory and from Mark directory as select Resources root as below:
Perhaps this is a bit off-topic, seeing as the question has already been answered, but I have experienced a similar problem. In my case only some of the unit test resources were copied to the output folder upon compilation. My persistence.xml in the META-INF folder got copied but nothing else.
In the end I "solved" the problem by renaming the problematic files, rebuiling the project and then changing the file names back to the original ones. Do not ask me why this worked but it did. My best guess is that, somehow, my IntelliJ project had gotten a bit out of sync with the file system and the renaming operation triggered some kind of internal "resource rescan".
This is one of the dumb mistakes I've done. I spent a lot of time trying to debug this problem and tried all the responses posted above, but in the end, it was one of my many dumb mistakes.
I was using org.apache.logging.log4j.Logger (:fml:) whereas I should have used org.apache.log4j.Logger. Using this correct logger saved my evening.
I had a similar problem with a log4j.xml file for a unit test, did all of the above. But figured out it was because I was only re-running a failed test....if I re-run the entire test class the correct file is picked up. This is under Intelli-j 9.0.4

In Eclipse, how to have launch configurations relative to the project?

I usually have multiple copies of a project, for example: a copy of the trunk and another of the last release branch. To cleanly separate my project files from Eclipse, they are checked out from Subversion in a directory outside the Eclipse workspace.
I want to make the project easily importable to Eclipse and followed instructions from multiple answers.
The problem is that my .launch files have the project name hardcoded. When a new project is imported, the launch files will display in the Run Configurations menu just if the project has exactly the same name of the exported one. This forbids me to have two versions of the same project.
It looks like the only way to do it is to have the .launch and .project files generated from an Ant task, but I don't see anyone using this solution. Maybe I should have multiple workspaces and the project always with the same name.
What's the best way to do it?
Edit: I'm marking VonC as the answer, but don't miss the comments.
Remember that the .launch configuration files don't have to be in your workspace.
They can be in your <project>/.settings as I mentioned in the answer you refer to.
That means you cannot import in your eclipse workspace two versions of the same project.
You need separate workspaces (not versioned themselves), each one referring to a project in a different path.
Each path represents different working trees (like different working directories for Subversion).
The OP adds:
The project must have the same name, but the project checkout dir can have any name.
To make the launch file work, you have to reference any file using the variable ${workspace_loc:ProjectName}.
Java files can be referenced using a path like: '/ProjectName/src/package/MyFile.java'
This way, it is easier to use any tool to interact with the subversion repository.
I want to make life easier for who uses Eclipse, but I don't want to force anyone to use it.
My recommendation is to tie the workspace to the checkout location, and then you can use the launch configurations for the relevant projects in Subversion.
My directory structure looks like this:
{checkout root}
|
+code
|
-workspace
In your case, that would mean a workspace for the trunk, and any other branch/tag you check out. I also keep all my projects outside the workspace. The workspace directory in Subversion is empty; I just recursively add the project reference(s) to the workspace from the sibling tree. It also helps if you export your Eclipse settings, as you can then re-import them into each new workspace.
I derived this approach from a pair of IBM and Rational white papers for using Eclipse with Rational ClearCase. This should work unless you need to have multiple versions of the same project open in the same workspace.

Eclipse rename not working completely

Ok I'm completely googled-out.
I have a few java projects in my eclipse workspace (about 25). Most projects use linked source folders.
When I rename a class in Project1, the references to that class in the other projects are not updated. The references within the project are updated just fine. The net result is compilation errors on the next automatic recompile.
I'm using Eclipse 3.5.1, but the same behavior was shown by 3.4.0 and 3.4.2
Any ideas about how to fix this?
My current plan - after googling for 20 minutes - is to write a script to convert the linked source folders to be OS links (I'm on linux) in the project folders themselves. So then I'm no longer using linked source folders.
Like Philippe Faes said, it works fine if your projects are set as a dependency on each other. Make sure that your project's build path are set up that way.
IMHO linked folders are for external files, not for another projects.
Another problem is that if you are just referencing a jar as a dependency (ie, on the project's class path), eclipse will not be able to know that the jar was build based on another project's source thus will not refactor properly.
Try to ask your colleagues for the eclipse project files (.project and .classpath) and edit the files if you need, then check if your refactor still doesn't work. I am guessing that your project is set up differently than your colleagues.
Cross-project renames work just fine if your projects depend on each other.
What exactly do you mean with linked source folders: do you link to the same source folder more than once?
This is a shot in the dark, but make sure that your project is a Java project. I am not sure if other project types (like the generic Project) might not refactor properly. I have never seen this problem before and it has always worked as expected for me...

Categories

Resources