The scenario is that I have a bunch of java projects with source files and lib jar files (for example apache-commons). I have multiple projects like that in different locations (shared drives, web servers, etc). Some of these projects depend on others. For example the output (.jar) from one project is used to compile and produce output for an other.
What I want to do is, programmatically (headless), using java, collect the source files and libs for all projects, compile them in order, and at the end produce jar files for the end projects. So, for project #1, brings all source files to a directory, bring all dependent libs in the same directory, compile, and create a .jar. Then do the same for project #2 but also include in the libs (or class path) the output of project #1, etc.
The projects dependency is known. The order on which the projects need to compile is known.
Bringing the source files and lib files together is not a problem. What I am looking for is suggestions on how to go about compiling programmatically. One option that I am considering is maybe Eclipse JDT. But before I go that path, I would like to see what other similar options exist out there
(I do understand that there are better procedures and processes that can be followed in order to make it easier to get the end result but I have no control over those. The build needs to be done dynamically/programmatically as described above)
Related
What is the equivalent project file for a Java project? For example, a C# project file is denoted by the delimiter of .csproj. So what would it be for a Java project? Is it dependent on what IDE I am using for Java?
I did some search online about this and it seems to me that the answer to this question is dependent on the IDE. From memory, it seems to me, that all I have to do is drop the Java files into an IDE and then, somehow, a project file is automatically generated. I do not want to be steered in the wrong direction on this and so I want to first ask around for guidance.
You're probably looking for the build file, not the IDE project definition.
Is it dependent on what IDE I am using for Java?
Yes. IntelliJ has .iml files, and Eclipse has .project (that's not a file ending - that's the file), as well as .classpath, .factorypath, and more. But, many of these are effectively generated or just refer to the build file. In C that tends to be called Makefile, in the Java ecosystem, Gradle and Maven are the 2 most popular build tools; they have build.gradle and pom.xml respectively. These would be more useful as basis for knowing how a project is 'put together', so to speak.
From memory, it seems to me, that all I have to do is drop the Java files into an IDE and then, somehow, a project file is automatically generated.
That's very basic and should rarely work except for the simplest projects. For example, most Java projects have source files, test files (also source files but they are not part of the distribution), and resource files (non-Java files that are also needed for the app; think about the images for the icon on a button), as well as a ton of dependencies (third party libraries used by the Java app).
Given that folks like many IDEs, the IDE 'config file' is not what you are looking for, and many projects don't even check these into source control (and probably shouldn't). Together with the source, you have a build file. This build file knows how to download dependencies, compile every artifact (there doesn't have to be one; maybe there's the test code to the built, the main app, a plugin for some other tool, and an installer. Build tools can handle all that), run the tests and report on them, possibly even tell you about code coverage, and they usually can run the app, but more generally, you just want to tell the build tool to build a distributable for each relevant artifact.
Those build files are what you're looking for. With those you can build your project, or point an IDE at them and then you can edit the project with all the dependencies and classpath linkages all worked out for you.
I have read numerous posts regarding this, and I was still not able to find a clear-cut answer.
We have the need to use a proprietary SDK in our maven project and this SDK contains ~315 jar files that are needed for around 30 lines of code (SAP product). Every answer I read dealt with adding individual jars to your local maven repo. That is fine and I understand that, but is it possible to add an entire directory of libraries. These libraries are only needed for compiling the project since they are already on the classpath of the target server (They would all be scoped as provided in a pom).
I've tagged Netbeans 8 since that is the IDE I am using, so if anyone knows a hack to get a maven project in netbeans compiled using libraries on Netbeans classpath that would be a good solution as well...
JAR's are just java .class organized in folders and Zipped. Extract all those 315 JARs to somewhere, thus merging all of their content, and then Zip it again to one single fat JAR file. Add this fat JAR to your local repository as you have read elsewhere.
This other question can help you with the JAR merging thing: How to combine two Jar files
Although there are many messy workarounds for this, the ideal would be to let the compilation fail and search for the missing compile jars using a search utility like agent ransack you can search within the jars in that directory for the missing classes referenced in the compiler errors. As you find the jars you need, add them as dependencies with the scope of provided.
A less clean option would be to zip all of the jars, use the dependency plugin to unpack them to a folder and add that folder to the classpath of the build, then remove them or exclude them from the final package.
I am writing a Bukkit plugin in Eclipse in which I separate different functions into different packages and export each package as its own jar file.
However, I would still like to keep these packages in the same project, rather than separating them into different Eclipse projects. These plugins each have files which must be in the root of the jar file, such as plugin.yml. I have moved each jar's files into their respective packages, but these files are put into plugin.jar\com\Preston159\plugin rather than in the root of the jar file (plugin.jar\), causing the plugin not to work.
Does Eclipse have any function to make these files automatically compress into the root of the jar file even though they are contained within the package in the source, or, is this something that I could solve by using Maven? My current solution to this problem is to move the files manually after exporting the jar, but this is becoming increasingly annoying.
EDIT:
The project builder XML I ended up using to complete this task can be found here
You would need to use a Build Tool. There are several supported by Eclipse. Ant and Maven are now built-in, but there are several build tools that run directly within Eclipse, but Eclipse can also be configured to run an external build tool as well.
Do a quick search on build.xml for examples of ANT build jobs.
Unless you're specifically required to use MAVEN for continuous integration, etc. then what you want to accomplish would be easily done with ANT.
I keep server and client code in the same project of Eclipse. Libraries for both of them are included. Images for the client are also added to the build path.
Now I want to generate jars for server and client, that they include only required libraries, and server jar does not have images included.
Is there a way to do this without maven, etc?
Right-click on the project and go to Export. Select jar from the selection tree and in the next tab, remove the code/resources that you don't want included in the jar. Better still if you keep them in separate projects (even if there is no client java code, you can create a resource project).
However, what you're describing sounds a lot like a WAR file. Contrary to a jar, a WAR file is a deployable jar meant to be added to a web hosting application like Tomcat. I don't know if that's suitable for your needs, but more often than not, you want to have both server and client code together. If your project is dependent upon another project, that project will automatically create a jar that will be included in the WAR.
You can divide your sources into three source (and output) folders within the same project:
src-shared
src-server
src-client
Then create a build.xml (Ant buildfile) which creates a jar from bin-shared + bin-server and a jar from bin-shared + bin-client.
Note: One danger of keeping it in the same project is that you can accidentally use client classes from server classes, or vice versa, which will fail at runtime. To fix this, make three projects instead of three source folders.
So I'm fairly new to Java and especially Eclipse, so please excuse my ignorance. I took a project from a server and copied it locally to my machine. When I opened the workspace, I had many errors due to it not being able to find the jars. This makes sense because I don't have the same dir structure as the server I copied from. So if I copy the same external jar's to my machine and get it to compile into a jar and copy it back to the server, will it work? Or will it fail because now the external jar's are in a different place than it is expecting?
Also, down the road should I put the external jars into regular jars to avoid this problem?
You should be OK. Java is using what is called classpath to locate dependencies. The classpath may be different on the development machines, but as long as all the dependencies are on the classpath in the production everything should work.
To avoid issues with the synchronisation of directory structures the most common way is to use Maven - it will manage all the dependencies for you (but you have to manage the pom.xml - the Maven's project descriptor). A little clumsier way is to have the dependencies in the project, however you may end up with many projects having to include same jars, and then there will be version conflicts and so on.
For small projects you can manage dependencies yourself, however larger projects will need a more thought through strategy (like Maven).
In regard to the executable jars, make sure the Class-Path entry in <jarfile>:\META-INF\MANIFEST.MF is correct, e.g. where it references other jars, those jars are going to be there in the production. For example, assume we have ourjar.jar and assume this is a snippet from its MANIFEST.MF:
Class-Path: lib/myteamjar.jar
It will then be expected that a following directory structure is in place:
lib/myteamjar.jar
ourjar.jar
No, the location of the external jars does not mater. What you want to do is put the external jars on your classpath. How you do it depends on how you are running your java code. If you are running it from the CLI using the java command, it takes the classpath as an argument. If you want your code to build/run in Eclipse, you need to right click on your project, select "Build Path" > "Configure Build Path..." Use the "Add JARs..." button to add jars that are part of a project you have open and "Add External JARs..." to add jars that reside outside of the project. See specific documentation for your tool for more details about classpaths.
I would not recommend Maven to somebody who is fairly new to Java and Eclipse. I would forget about Eclipse, too.
You have a packaging and CLASSPATH issue. Focus on that.
What kind of project are you talking about? The answer you get will depend on what type of app you're creating. Is it an executable JAR? Then the right way to do it is to package everything into a ZIP file that's laid out exactly as the CLASSPATH in the JAR manifest expects.
If it's a web app, the right thing is a WAR file, with all the JARs your app needs in the WEB-INF/lib directory.
If you package things properly, you should end up with a single package that has everything laid out the right way. You should be able to deploy it to the server and make it all work.