Eclipse: Get the project name as a VM argument? - java

Consider a configuration class which needs to parse a different config file for each Eclipse project.
For instance, If Configuration class is called from Project1, it should parse special/path/fileX, and if it is being called from Project2, it should parse special/path/fileY.
I've tried using Eclipse's {project_name}, but surprisingly it is being parsed to the project being highlighted by the cursor, not the parent project of the current class.
Any ideas how can I distinguish one project from another in Eclipse Runtime, preferably using JVM arguments?

This is a workaround to your described problem, but I guess it's a better solution as it's independent from Eclipse and will easily work in production too.
Simply load the same file from the classpath, regardless which Project you're starting this from:
/my/file/from/classpath.txt
But put this file only in Project1 / Project2, such that the various files mutually exclude themselves according to your set-up:
/Project1/src/my/file/from/classpath.txt
/Project2/src/my/file/from/classpath.txt
Where src are Java source folders. Now you can still use your JVM parameter to override this, or to provide a default if the above is missing.

I think the easiest way would be using eclipse's run configurations. Simply create as many configurations as you want, supply all the JVM args you want, and use them to launch. This will also be very close to what you're going to do in production mode

or you can go to your Eclipse' Installed JRE's and have the configuration set as JVMArgs just the way you would have in prod.
If required, you can have diff copy of JREs per env.
Also if running from the IDE, you can get the
System.getProperty("user.dir")
which should be the root of the project.
that system property can be used to track the callee. Better still, set the Installed JRE's JVM Args to be something like this
-Dtheflaginprod=${project_loc}
project_loc = absolute path of the the project (/usr/projects/project1)
project_path = project name relative to the workspace (/project1)

Related

Can I create a Run Configuration in Eclipse without specifying main class?

I have multiple Java projects in Eclipse, which I would like to sometimes run with some arguments (same args for every project). Therefore I would like to create a Run Configuration which I would run on chosen project. Creating a RC for every project is a little too much hassle for me. Ideal solution for me is that I could click on a project or main class, select my run configuration and I'd run this project with specified arguments. Or maybe somebody could come up with some clever and usable alternative?
There are a few quirks, but it is doable.
Main
Project must be specified explicitly, but it is not that relevant for your use case.
Use ${java_type_name} as Main class name.
JRE
Select an appropriate JRE
Classpath
Make sure the JRE is selected in Bootstrap Entries
User entries must contain a variable string ${project_classpath}

Eclipse Checkstyle plugin (eclipse-cs) Error Property has not been set

I try to use eclipse-cs (eclipse checkstyle plugin) in our Eclipse 4 teamproject.
The idea is that we define one checkstyle.xml for our team and have this checkstyle.xml under sourcecontrol.
The Project structure looks like this
Root
Checkstyle.xml
PluginProjectFolder1
PluginProjectFolder2
According to the documentation it should be possible defining relative paths with the ${property} style pattern(s)...
When I try to define the location for the checkstyle.xml I get an error "Property xy has not been set".
What I'm doing wrong ?
The documentation you reference says:
To do this use ${property} style pattern(s) in the location string,
these patterns will be resolved from equally named Classpath Variables
or Environment properties (passed into Eclipse via -D parameter)
${project_loc} is not a Classpath variable or an environment property. It is an Eclipse String Variable which is different and the dialog needs to have specifically added code to support it. It looks like this dialog has not done that.
You can define Classpath variables in the Preferences in 'Java > Build Path > Classpath Variables'
I would assume that PluginProjectFolder1, PluginProjectFolder2, and Checkstyle.xml are all inside your Eclipse workspace. If they are not, then that is what you should try to do, e.g. by including an Eclipse project called WorkspaceConfig or some such which includes the checkstyle.xml.
Then, in order to achieve what you describe, you can select "project relative configuration" from the dropdown box. This actually refers to the Eclipse workspace. Select WorkspaceConfig/checkstyle.xml, and there you have it: The checkstyle.xml is under version control, and it will not matter where the developer's workspace is located on his PC.
An added advantage is that such a configuration will work out of the box, without required extra configuration steps such as defining classpath variables.

java.lang.NoSuchMethodError in Genexus

I am using GeneXus Evolution 2 for my project. While I was developing, I got the following error:
HTTPステータス 500 -java.lang.NoSuchMethodError:com.genexus.ModelContext.server2webcli(Ljava/util/Date;)Ljava/util/Date;
I don't know what it is and how to solve this. Any ideas?
A NoSuchMethodError usually indicates that a method (declaration) was there when you compiled the code, but the implementation is missing when you're running it. In most cases, the reason for this is that you had one version of the respective library's JAR file on your class path when compiling, and another, incompatible one when running.
A more detailed answer would require a more detailed question...;-)
Supposing you're using Tomcat as servlet container, look at {Tomcat_Home}/webapps/MyApp/WEB-INF/lib, where MyApp is your app name. There will be a gxclassR.jar file that should match with the version of your Genexus installation. To test if you have the right one:
Assure that there is not other similar lib, like gxclassD.jar, in the same folder. If there is, delete it.
Go to the environment target folder where you're working (from the Genexus DE Menu "Tools -> Explore Target Environment Directory") and look for the gxclassR.zip file. Copy to the WEB-INF/lib folder, rename it to gxclassR.jar replacing actual gxclassR.zip file.
Restart tomcat application to assure that the new gxclassR.jar is being used.
If your object keep failing, then the problem may be the .class associated to your genexus object. Maybe isn't correctly generated/compiled. So, to fix this:
Force the building of the genexus object. For this, try the Build with this only option associated to the object. Activate the Force option for this action, accessing to "Tools -> Options -> Build -> Build with this Only"
Once forced the build, go once again to the environment target folder and look for the .class file/s associated to the object. Usually the name of the file/s matches the name of the object. Look the modification date and confirm that is recently.
Copy this .class files to WEB-INF\classes folder inside your webapp folder.
I think this is good enough info to fix your problem. If not, detail your error a little bit more.
It may also be that the method you are calling does not exist, or exists with different parameters, either by quantity or by type.
Check the date and size of the file gxclassR.zip that is on your web folder inside your KB (Tools -> Explore Target Environment Directory), and compare it with the one used by your web application (folder WEB-INF/lib). If they don't match, replace the one in your web application with the one in your KB.
If you are unsure about it, and would rather GX handle it, delete all the .ver files in your web folder and force a build. That should synchronize all the files to the proper version.

Easiest way to manage my CLASSPATH?

I'm beginning to play with Clojure a bit and my Java experience is pretty limited. I'm coming from the dynamic world of Ruby and OO, so the functional side of things is very interesting!
Anyway, as I discover libraries and various tools for use (and the tutorial files for the Pragmatic Clojure Book), everything typically calls for placing files in the CLASSPATH in order for Clojure to see the library for use.
Is there such thing as good CLASSPATH practice? Would I ever want to only have a CLASSPATH with just the external libraries of files I need or can I go ahead toss any library or file I would ever need in a directory and simply define it as my CLASSPATH and only require what's needed?
If it helps, I'm an OSX and Emacs user (Using slime and swank-clojure).
I recommend using leiningen and lein-swank to manage this. You can start a REPL in the directory and connect to it from Emacs.
Personally, I'm using a variant of a clojure-project elisp function by Phil Hagelberg, see source in this post to the Clojure group. It sets up the classpath appropriately for the project you'll be working on, then launches SLIME. (EDIT: You'll need to change the value which gets assigned to swank-clojure-jar-path to point to clojure.jar. I'm using (expand-file-name "~/.clojure/clojure.jar") as the default.)
To answer the question about having everything on the classpath all the time vs only throwing in what's needed: to the best of my knowledge, nothing will actually break if you take the first approach (I know I do that for experimental purposes), but apparently things might break with the first approach (see cjstehno's comment below) and in a proper project I find the second to be cleaner. At some point it'll be necessary to determine what libs are being used (and which versions of them), if only to tell leiningen (or maven) about it -- why not keep tabs on it as you go.
We are using Clojure and use a number of infrastructure tools, especially Eclipse (IDE) (http://en.wikipedia.org/wiki/Eclipse_%28software%29) and maven (http://en.wikipedia.org/wiki/Apache_Maven). maven manages libraries and jar dependencies so if you have a number of these and they are likely to grow start using maven.
In answer to your original question you can just put your jars in one directory and you can access them by name every time you run. But you will benefit from the tools...
If you are just exploring then Eclipse will probably manage your jar files fairly painlessly. You can add these to the project as required through the Build Path -> Configure Build Path option.
As your work progresses you will possibly wish to split it into Projects which Eclipse supports so you can add your (or other projects) to your Build Path.
If you use external Clojure libraries look to see if they have been packaged as maven projects (they will have a pom.xml file). The POM will give a list of dependencies.
#
The usual CLASSPATH practice for Java is to put only the jar files needed for a project into this projects class path, which means to have potentially different class paths for diffent projects. This is usually managed by the IDE as part of it's project properties.
Since you are using Emacs and thus probably don't have or use something like projects it might be more convinient for you to set up and use a single global class path for all your clojure related stuff or maybe even simply put all the needed jar files into the java2se/jre/lib/ext directory of your java installation.
The two main problems that could arise from having unneded jar files in your class path are: 1. it has a minor negative impact on the start up time of the JVM and 2. it becomes more difficult to make sure that you are not having classes with different versions in the same class path (i.e. different classes with the same package and name in different jar files).
Since Java SE 1.6 (or JDK 1.6) you can include class path entries by wildcard. If your class files live in .\bin, and your library jar files live in .\lib, then on Windows you could define your class path like this:
set CLASSPATH=bin;lib\*;
This will let you add jar files into the .\lib directory and they will automatically be added to the class path for new instances of the JRE.
See this link for details: Setting the class path
Prior to JDK 1.6 you had to add each jar file onto the ClassPath individually.
I just discovered this bit which I need to give a shot:
(setq swank-clojure-extra-classpaths (list "/class/path/1" "/class/path/2" "/class/path/3" "etc"))
clojure-contrib/launchers/bash/clj-env-dir has an interesting property that you can point it at a directory and it will basically include anything in there. In the past I've had a ~/classpath directory which I would dump any jars into and link any commonly used directories and it worked great. Very simple way to dump and use. Now I tend to use Maven clojure-maven-plugin and that works well also though can be a bit tedious when you just want to muck around with some ideas.

Eclipse classpath entries only used for tests

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.

Categories

Resources