Is it possible to save project dependencies using Maven to prevent redownloading? - java

Problem
I am building a Maven project inside a Docker container. I want the initial build to be quick. However, since during the first build, the ~/.m2 folder is empty, Maven downloads all the specified dependencies, and this process takes a while.
Question
Is there a way to somehow bundle all the dependencies in one jar file ( or something similar), and simply use that while building the project?
Notes
Note 1. The dependencies of this project will probably not change frequently.
Note 2. The reason the build happens inside the container is that depending on some user actions, the resource files are dynamically changed, thus each build generates a JAR file with a different set of resource files. This is the reason why I cannot just build the JAR beforehand, and simply use it inside the container.
Note 3. This container will be run by people other than me, so I cannot simply try mounting the local ./m2 directory to the container to speed up the process.
Thanks, and let me know if there are any questions.

Related

How can I exclude files from indexing but include them in .war file?

We build with IDEA a Maven-managed web application for which we generate bundles with Webpack fairly often in main/webapp/resources. Ideally these files shouldn’t be indexed, but if I exclude them in Project Structure or in the Project tree, they aren’t included in the .war file when we run Tomcat (within IDEA). Is there a way to exclude files from indexing and still include them in the web app?
Thanks.
The crux of the matter is that the (exploded) .war file that IDEA generates when running Tomcat within the IDE follows different rules than the one you get executing mvn package. Whatever you exclude in IDEA is also removed from the webapp.
There are two ways to solve the issue.
1. Build using Maven
The first one is to have Maven build your module instead of IDEA. To do that you need to change the Before launch command: remove the default, click on +, choose Run Maven Goal and type in Command line something like -DskipTests -pl {module_name} package (see image below).
The profile will be picked up from whatever you have selected in IDEA (that was unexpectedly clever from the guys at IntelliJ, so kudos to them) but it has the drawback that it makes a full build each time you start Tomcat. In our case that’s roughly 25 seconds, which is quite a lot.
2. Edit the artifact
The second way, which is faster because it takes advantage of the automatic compilation of classes that IDEA makes in the background, is to edit the war artifact. To do so go to Build → Build Artifacts... → :war exploded → Edit..., select the tab Output Layout and create a directory of the same name (resources in my case) and add a Directory Content entry. Check the following image for details.
You will also need to change the Before launch similarly to the first solution, but just select the affected artifact.
UPDATE
Because the default war and exploded wars are imported from Maven, any change to e.g. the selected profile accompanied by a clean command reverts the artifact to the default layout, so if you use this solution you’d better create a duplicate war artifact.

Export Java project as JAR with ressources out of it

I currently have a basic Java project, that I want to deliver as an executable JAR. The program within it is based on several resource files, which must be editable by the user, or by a third-party program, which means that those files must not be embedded into the JAR archive.
I am using Eclipse to develop my project. The question is :
How to make the exportation of those files automatic, to end up with the JAR, and right next to it, a folder containing the resources for exemple (if that is possible of course) ?
Every thing I've tried or found on the net concerns resources delivered within the JAR, which avoids any modification of those resources. The ideal solution would copy the files right next to the JAR when it is exported.
Eclipse's "export executable JAR" functionality can't do this directly, it's limited to the contents of the JAR. I recommend you investigate doing this with a build tool like Gradle, Maven, or Ant, and then invoking that from Eclipse or via command-line.

Sharing a Spring MVC project

I need to do a Java web project. I'm going to be using Eclipse.
I thought of using Spring MVC. As far as I can tell - it's gonna require me to add some "extra" stuff to a "clean" Java web project. I don't mind that - the thing is - one of the project requirements is - that I'll be able to send the project to someone else - that doesn't have any extra installation and/or configuration - and he will be able to compile the project.
Is that possible with Spring MVC? Does the Spring MVC framework is just a "JAR" like addition to the project - therefore - the project can be shared without a problem?
Thanks.
Short answer: yes, you are right.
To use Spring in your Java web project, you generally need to add two things:
the appropriate Spring configuration file(s) (XML)
the appropriate Spring JAR files (traditionally placed in /WEB-INF/lib, the same as other JARs). By the way, it is NOT a single JAR file, but several JAR files.
That is all there is to it.
Spring has nothing to do with "sharing the project".
To "share" the project with someone else, you put it on the SCM of your choice and your collaborators will be able to get the code and work on it.
Building the project is a different aspect. To correctly compile the project you have to make sure that all the classes and/or jars are visible in the classpath (and runtime if you want to execute the code). Spring is made of a bunch of jars that, depending on which classes of the framework you use, must be in the classpath (eg. putting them in the /WEB-INF/lib directory). You may version them as well, or just version the configuration (I'm thinking about Maven for example, that will take care of resolving the dependencies).
Another piece of the puzzle is making all of this work in your IDE. This is a matter of taste. I prefer not to version ide-specific files (in the case of Eclipse, .settings and .project files/folders). You can do that, making sure you do not use absolute path anywhere, and technically you will be able to import the project without problems from another machine.
Yes.
If the other person has nothing extra installed and configured, namely no build tool, you need to put every needed Spring and other Jar into a folder, typically called "lib" and tell him to add them into his compile process. If he just uses the JDK he will get an enormous command line. It is much better to use a build tool like Maven or Ant+Ivy for building and dependency resolution. But that would be an "extra installation" per your question.
If he has Eclipse installed like you have and you use Eclipse internal for building:
Put the JARs in a lib folder
Configure the build path
Make a local test build
Export the project as zip (File menu > Export)
" The other person needs to import the project into his workspace
The exported project should not have any absolute paths as long as you didn't set some deliberately in the build path.
This works but is not exactly best practice. Installing a build tool like Maven is absolutely worth the time and should be preferred under any circumstances. It will save you a lot of time and nerves.

How to share common resources between many webapplications?

I have 4 web applications. But images, css, javascripts are the same.
When I do changes in one project after I need propagate changes to all projects.
What the best way - create common jar only with resoures or use something similar to links in SVN or else?
Thanks.
I had the same requirement and got exactly what I needed using Bower and a small Perl script.
The problem with doing a simple copy of files across your shared projects is if for any reason in the future you need one of your projects to temporarily have a slightly modified version, you will essentially either break your project or your deploy routine. It's a much cleaner way to manage shared resources across projects by placing them in their own version controlled repository so each project can refer to a particular version either "latest" or "1.0.0" etc... now the solution:
Bower is a package manager which can, among other things, help manage retrieval/dependencies of git repositories. You can fetch git repositories from urls or even local paths on a drive. So all the files that need to be shared across projects I place them in their own individual git repository. Bower can then fetch a particular version of the shared content. The only problem is that bower copies them all in one particular sub-directory which is not always ideal.
Script(bower-redeployer) so then I use this perl script to deploy the fetched shared resources to the right location in my project.
With the maven resources plugin, you can specify a copy-resources goal that will copy the common resources into the specified projects prior to building the war files.
I've also seen the use of a common directory that is links (ln -s) during the build. This avoids the space and time load of creating physical copies of the resources.
Couple of suggestions...
Put them in a common jar file
Put them on shared URL(s)
(Promoting user710818's comment to an answer)
Consider using the Maven WAR plugin's overlay feature as described in the following links. From the first link,
Overlays are used to share common resources across multiple web applications. The dependencies of a WAR project are collected in WEB-INF/lib, except for WAR artifacts which are overlayed on the WAR project itself.
http://maven.apache.org/plugins/maven-war-plugin/overlays.html
http://java.dzone.com/articles/mavens-war-overlay-what-are
http://www.manydesigns.com/en/portofino/portofino3/tutorials/using-maven-overlays

Setting up a maven project for already made jars

I have some jar files that I need to include in my build - I'd rather not specify them as system dependencies - that creates a nightmare for setup. I have been uploading them to artifactory and then they can be pulled down directly, but I won't always have access to artifactory while building.
What I was thinking of doing is creating a project that has these jar files in them. It could be one per or all of them (open to suggestion). I was wondering if there is a graceful way to handle this?
What I have done (which is clearly a hack) have a project that takes the jar and during the compile phase it unpacks the jar into the target/classes directory. It then packs those class files back during the package phase. it essentially creates the same jar file again...massively hackey. Could I add the jar into the resource area or is there a different project type I could use? I am open to any ideas.
You may try to use install:install-file. I would go about it in the following way.
Create project that contains all your jars in some location
Configure install:install-file in pom of this project to install jars in repository in some early phase.
Make sure that this pom is executed before anything else that depend on it. List it as first module.

Categories

Resources