I'm using Gradle on IntelliJ and I have a peculiar issue with my dependencies: two of them contain a few of the same classes (apart from other files from each library), but one comes with the sources and the other one doesn't. The result is IntelliJ gives preference over to the one that doesn't contain the sources and I have to attach them manually (which is bad, because they'll be gone on every Gradle sync).
How can I choose the order of preference? And yes, I need both dependencies, even with their issues, but I also need the sources of the common files.
Related
Suppose that I have a common directory that contains general-purpose files like FileUtils.java and ImageUtils.java. Also I have two projects that should use these common files. What is the most Java-way to import them into these projects? Just add path manually to the -classpath option when using javac and java? Build them into one jar file? Or something else?
Just follow simple steps:
1.) Have module say, companyname-commons-util
2.) build to a jar file, companyname-commons-util.jar
3.) Add dependency of this jar into other projects, and just reuse the classes. (maybe maven, gradle or explicitly adding into classpath)
** The same can be reused in other projects as well. Good from maintenance point of view, and keeping project structure intact.
The recommendation would be to create a third project and then use that to generate a JAR file; you can then use that reference in your other projects. If you're using Maven to build them you'd end up with a different module with your common code in place.
Besides the things that have been said; a word of warning: try to slice your projects aka components to be as small as possible.
In other words: before just blindly going forward and pushing all content of your "common" folder into its own project it might be worthwhile to step back and carefully look at
a) the contents of common
b) how other projects make use of that source
And theoretically, you match that whole picture with the thing that is called "architecture" (which may or may not exist for your overall "product") to understand where "reality differs from as-it-should-be".
Then, finally, you define one or more projects that cover all (or parts of) your source code in "common"; and then you change your whole infrastructure so that other "dependent" projects do not rely on using your "common" source files but some kind of build artifact.
There is a business module - say kilo-business in one of the applications. Now there are some APIs in this module that is to be used by another application (locally within the organization - say kilo-client1). I have used Proguard (via its maven plugin) to only extract the classes relevant to the API and make a JAR out of it - the shrunk API JAR called kilo-business-apis. kilo-client1 uses this kilo-business-apis dependency and invokes the service. As a policy, we always include sources along with any artifact that we share between applications (for debugging ease and additional documentation).
In this case, is there a way that one can have Proguard also give out the (probable) source files (belonging to kilo-business module) from where it has sourced the classes for the kilo-business-apis using which a sources JAR can be conjured? Actually, we don't shrink the JAR to the extent of removing unused methods/variables from the class, so giving out the source java files would also suffice.
I understand that one can use jd-eclipse or some other decompiler in eclipse to aid debugging even if we don't publish it, but wanted to check if we can generate the sources first class whereby documentation needs are also addressed.
One thought is to break up kilo-business itself into a separate module for kilo-business-apis where only the API definitions reside and both kilo-business and kilo-client1 can use it, but unfortunately I can't do it for legacy reasons.
Thanks in advance!
ProGuard optionally writes out information about kept entry points (-printseeds), unused code (-printusage), and obfuscation mapping (-printmapping), but nothing related to source files. If you don't obfuscate the code, you can simply list the .class names in the processed output, and find the corresponding .java files.
I check out a java project from svn repository include .classpath and .project files. And I import these codes into eclipse. But the eclipse will modify the content of .classpath file. How can I stop eclipse to do this? just write off build automatically option?
You can't. But instead of putting a JAR on the Java build path you could
choose an execution environment which should stay stable when you change
the JRE and hence the .classpath file will not change either.
.Project and .classpath files should not be checked in under svn repos.Blindly copying such files from one machine to another may be risky. These are the files that eclipse automatically constructs for you as per your project structure. If you want to edit, you can do that.
Here is the nice explanation What's in an Eclipse .classpath/.project file?
Adding information to a 2-year old question just in case of any one else is stumbling across this.
Due to insufficient detail in the original question, I am guessing that the problem experienced is due to the project's classpath pointing to a different location on the questioner's machine as on the original project author's machine. When a project uses 3rd party libraries (JARs) and is shared between different team members (as hinted at by the use of a version control tool), this is a common occurrence.
A solution to this would be to have all team members set up the location of the directory containing all 3rd party JARs to have an identical structure on all individual machines. So instead of changing the classpath, change the directory structure to that required by the classpath.
Unfortunately this is not always the best solution:
Team members may have different operating systems (Windows vs Linux) and you will not be able to have a (absolute) class path that works on all platforms (e.g. C:\libraries\3rdparty.jar vs /opt/libs/3rdparty.jar)
Team members may differ in how they prefer to organize their directory structure. Especially, if a team member places libraries into his home directory (e.g. C:\User\abcd\libraries\3rdparty.jar or /usr/abcd/libs/3rdparty.jar), another team member will struggle to replicate that directory structure.
Eclipse provides various methods to set up a project so that it can easily be shared between team members. These however require team members to all agree on the convention, and will be slightly easier if set up by the original project author right from the start. Two methods most commonly used:
Add all third-party libraries to the project itself (the usual convention is to have a /lib directory inside the project for this - on the same level as /src and /bin etc.). The classpath can now be set up to be relative to the project's root and thus usable across different setups. A variation for large multi-project-file projects would be to have a separate eclipse project containing the libraries, then add it to other projects as a dependency ("Required projects on the build path" in the "Java Build Path" dialog).
This has the benefit of being able to version control your JARs too. However, it may use up a lot of extra storage/bandwith, so may not always be desirable. For instance, I would not do this with Java Enterprise Edition JARs contained in my preferred Application Server distribution, as I may want to migrate my project in future to a new version or another product, without such dependencies - I also do not want to have my project saddled with duplicate JARs that are in any case already available in the AS distribution. So you need to think through your requirements.
Eclipse also provides the concept of a classpath variable. This may be set up to point to the root of a team member's JAR-containing directory, and be extended with subdirectories and filenames inside the classpath. This needs to be done only once, and is also accessed via the "Java Build Path" dialog.
Whenever a new team member uses the project for the first time, he needs to configure eclipse (once) to point that variable to the relevant path on his own machine.
The above mechanisms are explained in more detail on various web pages, here is one reference: http://www.informit.com/articles/article.aspx?p=367962
I'm a new configuration manager at my company and I am starting a project to clean up much of our build process.
We have oodles of jars we have put away in one Subversion project. Some people copy these jars to their projects. Others put an SVN:External on their project to this directory. Others have a convoluted way of copying in these jars. These are the only jars that we're suppose to use.
I'm moving over to Ivy and maybe to Maven. I've setup a Maven repository, and have identified these jar's GroupId, ArtifactId, and Version and have documented how to access the ones you need via Ivy and Maven configurations.
I want to go through all the projects' source files, find all the import statements, and compare those imports against all the classes these jars contain.
I want to find all the jars that a given set of sources call directly. For example, if a jar contains:
import org.apache.commons.beanutils.*
I know it needs commons-beanutils.jar (version 1.6). I also know that it needs commons-logging.jar, but I'll let Maven and Ivy handle that issue. I just want to tell the developer when they create their pom.xml or ivy.xml, they'll need to include common-beanutils#common-beansutil#1.6 in their pom.xml or ivy.xml file.
I know this won't be a complete list. I know there will be jars needed for runtime, but not compile. I also know there are classes that can work with multiple jars. I also now developers could do this:
import org.apache.commons.*;
which would match with dozens of jars and tell me nothing. (Maybe there's a way to figure out what classes are actually used in the Java source files).
I could write a Python or Perl script that could probably do this, but I was hoping there was something already around that could save me several hours of work. I know about TattleTale by JBoss, but the documentation seem to say it only works with jars and shows dependencies between jars, etc. I'm not really interested in that. I just want to know what jars our sources are calling and let Ivy and Maven handle deeper dependencies.
Any such tools?
Addendum
Just to be more specific. This is an old project. In fact, there are 50 or so projects. We know that a particular project needs 20 jars to run, and tools like TattleTail can go through and show you the whole data analysis.
However, let's look at it from a developer's view point. I have a problem, and I find an open source project that will solve my problem. I read the docs, write my code and import the classes I need. I know the jar for that open source project that contains the classes, and that's pretty much all I know.
What I want to do is get back to the original developer's mindset: I used these classes in this project, and I need these 5 jars. That those 5 jars may need another 15 to run is something that Ivy/Maven will now handle. We know the 20 jars that program needs. I just want the 5 that the developers originally referred to in their code.
This is to help the developers write their pom.xml or ivy.xml. I don't want them putting all 20 jars in that pom.xml or that ivy.xml file -- just the five they need.
This is just a starting point. They might have imported com.foo.bar.bar.foo and that class is in foo-all.jar, foo-client.jar, and bar-talk.com. The developers will have to decide which one of these their project needs.
This is a massive paradigm shift in our programming, but we are losing track of jars and versions, and making sure all of these projects can talk to each other. Using Ivy/Maven will greatly simplify this mess.
Tattletale ended up giving me the first level of dependencies which is what I need to build my ivy.xml or pom.xml file. It misses one or two occasionally, but otherwise it works pretty good.
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.