I'm using Google App Engine to create a project consisting of multiple Google Modules. How do I set up my project (using Maven) so that I can share source code such as Objectify object model definitions, shared utility code, and unit test code across the modules?
I'm hoping the answer is simple and that I can just use Maven as suggested in answers such as these:
How do you use Maven to share source code for two projects?
How to create shared source folder across multiple projects in Eclipse?
For test code: Sharing src/test classes between modules in a multi-module maven project
For test code: Share test resources between maven projects
Eclipse Linked Resources: https://stackoverflow.com/a/7585095/2848676. Is this compatible with Maven though?
However, I'm concerned there might be something special about Google App Engine modules that makes them different from Maven modules. And then maybe the approaches above won't work.
As an example of why I'm concerned, notice that Google says "Although Java EE supports WAR files, module configuration uses unpacked WAR directories only." yet some of the solutions given above suggest packaging the shared code into JAR files. I realize WAR and JAR are different but I'm worried I'll waste my time trying to make something work that can't.
Any advice on how to share code among Google App Engine modules?
I have a share directory that contains code I want to share between modules.
Then I can make symlinks from my modules directories to the share directory.
The symlinks can be of a file, sub-directory, or the whole share directory itself.
Related
I am reading Maven documentation and came across the name uber-jar.
What does an uber-jar mean and what are its features/advantages?
Über is the German word for above or over (it's actually cognate with the English over).
Hence, in this context, an uber-jar is an "over-jar", one level up from a simple JAR (a), defined as one that contains both your package and all its dependencies in one single JAR file. The name can be thought to come from the same stable as ultrageek, superman, hyperspace, and metadata, which all have similar meanings of "beyond the normal".
The advantage is that you can distribute your uber-jar and not care at all whether or not dependencies are installed at the destination, as your uber-jar actually has no dependencies.
All the dependencies of your own stuff within the uber-jar are also within that uber-jar. As are all dependencies of those dependencies. And so on.
(a) I probably shouldn't have to explain what a JAR is to a Java developer but I'll include it for completeness. It's a Java archive, basically a single file that typically contains a number of Java class files along with associated metadata and resources.
ubar jar is also known as fat jar i.e. jar with dependencies.
There are three common methods for constructing an uber jar:
Unshaded: Unpack all JAR files, then repack them into a single JAR.
Works with Java's default class loader. Tools maven-assembly-plugin
Shaded: Same as unshaded, but rename (i.e., "shade") all packages of all dependencies. Works with Java's default class loader. Avoids some (not all) dependency version clashes. Tools maven-shade-plugin
JAR of JARs: The final JAR file contains the other JAR files embedded within. Avoids dependency version clashes. All resource files are preserved. Tools: Eclipse JAR File Exporter
for more
Paxdiablo's definition is really good.
In addition, please consider delivering an uber-jar is sometimes quite useful, if you really want to distribute a software and don't want customer to download dependencies by themselves. As a draw back, if their own policy don't allow usage of some library, or if they have to bind some extra-components (slf4j, system compliant libs, arch specialiez libs, ...) this will probably increase difficulties for them.
You can perform that :
basically with maven-assembly-plugin
a bit more further with maven-shade-plugin
A cleaner solution is to provide their library separately; maven-shade-plugin has preconfigured descriptor for that. This is not more complicated to do (with maven and its plugin).
Finally, a really good solution is to use an OSGI Bundle. There is plenty of good tutorials on that :)
For further configuration, please read those topics :
Should you provide dependent libraries in client jar?
Best practices in building and deploying Clojure applications: good tutorials?
The different names are just ways of packaging java apps.
Skinny – Contains ONLY the bits you literally type into your code editor, and NOTHING else.
Thin – Contains all of the above PLUS the app’s direct dependencies of your app (db drivers, utility libraries, etc).
Hollow – The inverse of Thin – Contains only the bits needed to run your app but does NOT contain the app itself. Basically a pre-packaged “app server” to which you can later deploy your app, in the same style as traditional Java EE app servers, but with important differences.
Fat/Uber – Contains the bit you literally write yourself PLUS the direct dependencies of your app PLUS the bits needed to run your app “on its own”.
Source: Article from Dzone
Reposted from: https://stackoverflow.com/a/57592130/9470346
A self-contained, executable Java archive. In the case of WildFly Swarm uberjars, it is a single .jar file containing your application, the portions of WildFly required to support it, an internal Maven repository of dependencies, plus a shim to bootstrap it all. see this
According to uber-JAR Documentation Approaches:
There are three common methods for constructing an uber-JAR:
Unshaded Unpack all JAR files, then repack them into a single JAR.
Tools: Maven Assembly Plugin, Classworlds Uberjar
Shaded Same as unshaded, but rename (i.e., "shade") all packages of all dependencies.
Tools: Maven Shade Plugin
JAR of JARs The final JAR file contains the other JAR files embedded within.
Tools: Eclipse JAR File Exporter, One-JAR.
For Java Developers who use SpringBoot, ÜBER/FAT JAR is normally the final result of the package phase of maven (or build task if you use gradle).
Inside the Fat JAR one can find a META-INF directory inside which the MANIFEST.MF file lives with all the info regarding the Main class. More importantly, at the same level of META-INF directory you find the BOOT-INF directory inside which the directory lib lives and contains all the .jar files that are the dependencies of your application.
I followed dropwizard tutorial and build a simple API project( or maybe I should call it a module). Can I make it a module? Since there is a main method in it, is it allowed to have main method, pom.xml and yml file in a module? If so, when import several modules to a project, how to use the service it provides?
What is the folder structure difference between a project and a module? I notice in the Project Settings of Intellij, I can either add my application to the module, or artifacts.
Should I package my restful API project as a jar to use it?
1.
A project can contain one or more related modules.Each module is a separate library, application and can be a jar, ear or war.Also modules aren't just Java either. You can have modules for ruby, scala, or something else as well.A project is a convenient way to develop related, interdependent applications, libraries in concert.2. Module folders are subfolders of the project folder. An artifact is an assembly of your project assets that you put together to test, deploy or distribute your software solution or its part.see https://www.jetbrains.com/help/idea/working-with-artifacts.html
3. Your REST API most likely will be a web app. So it should be a war/ear.for a sample see https://www.jetbrains.com/help/idea/creating-and-running-your-first-restful-web-service.html
I have a web application with different features such as map view, dashboard, report etc. But now, we are planning to split the application in different modules such as map module, dashboard module, etc. to make plug-gable as per the requirement. As all the modules will have their respective htmls, js, controllers, dao layers, how can be these divided as independent modules? Will it be a war or a jar files?
Need a suggestion or example which can help me move forward.
Thanks.
If you have different modules, with independent features. Its possible.
I recommend you, to first, find what features are common to all web-modules, so this common-module, should be installed (as a jar for example) in the library folder of your server.
Then, all the modules could be installed in the webapps of your server (in tomcat is called as webapps).
Important:
You must be careful not to duplicate libraries in each web-module, beacause this would generate conflicts. All your common jars (libraries or your own modules should be installed in the libs folder).
If you are using maven I recommend you to have a parent maven project with all your dependencies included, and then all the modules which needs these dependencies can import it as provided.
Microservices might be your best approach given the requirement you are sharing here. Each module i.e reporting, dashboard etc will be a separate microservice. If you use spring boot, you will end up creating multiple jar files and each jar file can be booted on the VM as a separate process and each one comes with its own container (tomcat). Makes things simple.
If all sub modules of your project are tightly coupled it is very difficult to split it. I suggest you to develop new different projects using reference of your old project. There is no technique to split existing project to different war files.
if you use Maven, you can create a parent with all common dependencies, and in its pom.xml you should define all your modules in <modules> </modules> tag. Be careful about the version of the artifacts, it should be the same version when you reference it in child pom.xml, in the parent tag.
About microservices, they are independent services and on every server is just running a single service. So, if you have multiple modules or if you more than one service on each server, it will be in conflict with MS concept.
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
I am writing an application that integrates Geoserver with a custom component, intended to be hosted on a single servlet engine. Both are Maven based projects, and I would like to stay in Maven land to package it all into a nice distributable. The general idea I have is to add another module to my application that packages the application itself, Geoserver and all dependencies into one nice archive.
I am aware of the maven-assembly-plugin and its capability of storing all dependencies in a target folder, but I am not sure what would be the best way to create a package that it easy to deploy. Googling for any examples has not been successful.
Extra bonus points if the module can be started via mvn jetty:run.
Have you considered packaging them into an EAR project. It will bundle a set of WARs (and jars), and allows you to specify or generate a deployment descriptor.