I have 2 projects, which are developed using PlayFramework 2.4. Although they are completely separate in concept, they share some common features, like evolution management (Liquibase), CRUD administrative mechanism, notification (email, sms) mechanism, etc. So, it was decided to split every project in 2 modules: common "core" module, which holds all described logic, and "project" module, which hold project-specific services, templates, views.
Recomended approach for achieving this in Play Framework is "subproject" concept. But it's clearly not an option, due to at least two reasons:
Projects are developed by different teams, that's why they they can't be located in one directory structure
These 3 modules ("core" and 2 "project" modules) MUST be versioned in separate VCS repos (Mercurial)
My current solution is to create core module, and provide it as a dependency in "project" Play application. An though this approach partially works, there are major downsides:
If you add routes file in module, they will override project routes file
You cant place views in core module, because due to fig.1 you cant access public assets
Due to downside n.1 and 2, you cant place Controllers in core module, because you cant specify a view to render
static assets (public directory) is not included in module distribution
I'm forced to copy common templates into both projects, I practically can't write common controllers which is annoying SO much
Appreciate any help. Maybe this can be achieved in some sort of highly-custom build and publish process for the core module?
I think you should not add the role core project as a dependency for the other 2 projects.
You could break the core project into core classes and core resources.
The templates and views in play framework are compiled classes, so you can pack then in a jar perfectly. The templates you create would be packaged alongside the core classes (or you can break them too). You can publish this jars into a dependency application like artifactory or nexus and import in the other projects. For the resources, you can package them like webjars do. So you can access them from any other view of your other projects.
Related
I have created a Selenium Java Framework with a proper folder structure. Basically my framework consists of few common utilities(page objects, reporting configurations and, driver initialization settings, etc.). This framework was developed to automate and validate web applications. We have a bunch of web applications in our organization that are common in nature and behavior. The Java framework that I have developed has some generic methods and page objects that can be utilized in all the web applications.
Now, I have pushed my framework to the Github. And, I want other teams in my organization also to use my framework. So, in my organization for each project, we create a new repo. Therefore, I wanted to know if by any chance my framework can be accessed by other teams of my organization in their projects.
I don't want anyone to clone my framework repo, add their tests, and push it back. As each project in my organization will have their own repo. Therefore, I simply want them to add my framework as a dependency in their project repo. And, when they clone their repo and do a maven build, they should be able to access the utilities of my framework. Please let me know if this is possible by any chance. Thanks! in advance.
You have multiple options.
Option 1:
Give read-only access to the outside your project users, so that they can extract and re-use the items from the framework without impact your code. Other teams can tailor the framework according to their needs (you can consider it as adv/ disadv)
Option 2:
Convert your framework into a jar and then share it with other teams. Ask them to use the jar. No Edits in framework possible.
We are exactly doing the same thing (we are using option-2 as below). Other teams need to use it as a dependency in their pom.xml. Two ways to use the dependency in maven:
If your company has maven artifactory management system, you can publish your framework jar into that and ask the other teams to use it as a dependency in their pom.xml directly
Else,
2. You need to prepare a jar file, and the other teams need to use it as a dependency using system scope level as below:
<!-- Framework -->
<dependency>
<groupId>com.test.group></groupId>
<artifactId>automation-framework</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${jar.location}</systemPath>
</dependency>
groupId, artifactId, and version are the details of your framework project.
Other teams can create a folder called "libs" in in their project, and store your framework's jar in there. That location will go here: ${jar.location}
Every time you make changes to your framework and build new jar, they need to update the jar file under "libs" folder.
In this way, they can use all your utilities, but can't modify or publish any tests into your project.
You need to keep utils package and create all utils classes into that package and use it
In every projects you need to keep package for separate keeping utils classes
I have an Android project which is architectured in a Modularized way. I have modularized the projects by dividing their source code between multiple Gradle modules, following the clean Architecture.
Here is the structure of the App.
The top module in this hierarchy, App is the one that no other module depends upon, is the main module of your application. The lower level modules domain and data do not depend on the App module, where the App module includes the data and domain modules. I have added the below code in the build.gradle of the app module
implementation project(':domain')
api project(':data')
Now, I'm having some issues with maintaining dependencies across each module. Since each of them is an individual android module, each of them having its own build.gradle. The App module can use classes in the data and domain modules. But, I have some general purpose classes, (Such as some annotations, Utilities, Broadcast classes, Dagger scopes etc) which I want to make use in all the modules. But these are the issues I'm facing
Since these classes are contained in the main module app, I cannot
access these in my data and domain, because those modules do not
depend on the higher layer app
Any libraries I'm using in all the layers (eg: RxJava) needs to be
included in the build.gradle of each module
As a solution for this I thought of adding one more android module, say common which will be containing all my general purpose classes as well as the libraries which I use in all the modules.
All my other modules app, domain and data will be having this module as a dependency.
implementation project(':common')
So, any global libraries and classes will be added to this module and each of the individual modules will have only module-specific classes.
Is that a good approach? Or is there any way to solve this issue efficiently?
We recently encountered this problem, as we transitioned to a multi-module project for reuse, build time optimisation (unchanged modules aren't recompiled), etc. Your core goal is to make your app module as small as possible, as it will be recompiled every time.
We used a few general principles, which may help you:
A common base-ui module contains the primary strings.xml, styles.xml etc.
Other front-end modules (profile, dashboard, etc) implement this base-ui module.
Libraries that will be used in all user-facing modules are included in base-ui, as an api instead of implementation.
Libraries that are only used in some modules are added as dependencies only in those modules.
The project makes extensive use of data syncing etc too, so there are also base-data, dashboard-data etc modules, following the same logic.
The dashboard feature module depends on dashboard-data.
The app module depends only on feature modules, dashboard, profile, etc.
I strongly suggest sketching out your module dependency flow beforehand, we ended up with ~15 or so modules, all strictly organised. In your case, you mentioned it's already quite a large app, so I imagine app needs feature modules pulled out of it, as does domain. Remember, small modules = less code to be recompiled!
We encountered some issues with making sure the same version (buildType, flavors) of the app was used across all submodules. Essentially, all submodules have to have the same flavors and buildTypes defined as the app module.
On the other side of the coin, multi module development does really make you think about dependencies, and enforces strict separation between features. You're likely to run into a few unexpected problems that you've never considered before. For example, something as simple as displaying the app's version suddenly complicates (disclaimer: my article).
This article also helped us decide on our approach. The article you linked also seems to be an excellent resource, I wish it had existed when we'd transitioned!
After comment discussion, here's an example diagram (with unfortunate untidiness, but enough to illustrate the concept. Note that distinguishing between api and implementation would be a good next step):
I am working on a project using the Java Spring framework, but I am (even after googling or looking through tutorials) unable to understand how it should be used.
Situation:
The project is(or, will be) made up of 3 separate web applications(for three different uses/target audiences) that uses the same database and to some extent functions and/or classes.
Database/cryptography-related classes and such are in a common folder under the project root, which seems appropriate.
Then there is a folder for gradle, used for starting the program("./gradlew app-one:bootRun"), which I suppose makes sense.
Then, there is a folder for one of the web applications("app-one") with related source code(Controllers, Services, etc.) and whatnot.
Problem:
I am tasked with adding the second application. Is it suppose to be a separate folder in the root directory?(Logically/By framework standards)
If it is not, how do I know what belongs to which application?
Do I need to use separate gradle commands to start each of the three applications? Is that even possible, and is it recommended/efficient/the best way to structure everything?
If you want to use maven,you can create a multi-module maven project with parent pom having all dependency management.A core project(jar) having all core functionality and three web projects(war) for your web modules which depend on this core project.You can start build and run these projects with a bat script from one place only.
I'd like to have 2 different projects: one connecting to a webservice, and another project handling imports.
Both projects will be running for the same final application, but should run on a different server each. Also each project should be able to be released independently (eg if I fix a bug on the importer, I have to release it without reference to the webservice project).
The projects should share some code, eg domain classes. Which maven structure should I use for this purpose?
3 independent projects whereas the commons is installed to the local maven repo and used as dependency by the others?
Or is it somehow possible to directly resolve the commons project from eclipse workspace without having to install it?
svn/Webservice/pom.xml
svn/Cache-Importer/pom.xml
svn/Commons/pom.xml //used by both projects and contains eg shared domain code
I would recommend, as you guessed, the three independent projects model. The Webservice and Cache-Importer projects will depend on the Commons. Having them as separate projects allows you to have different lifecycles for these projects and you can release one, but not the other.
If you want to put them in the same aggregator, this would tie you to having them all released under the same version and some of the modules might not need a version bump at the time. Therefore, in my opinion, this would be a better approach.
If you would like to build them together, but would also like to have them as independent modules, you could create a fourth project which has them defined as <modules/> in the pom.xml. You will need to setup svn:externals (as explained here) and basically link the paths of the modules to this project. This way you'll be able to check them out altogether and build them, while you'll also be able to release them independently as well.
I have two java projects that are fairly independent beside the fact that they share a common mysql database.
I wanted to refactor these project and extract everything regarding the common data layer. I am using jOOQ, so most of this layer gets autogenerated in my build. Beside that i then have a few common entity classes that are used in both projects.
what would be the best practice to separate this, so that any change can be done one place and still propagate to both projects? create a third java simple project with the common code? what would you do
I work on a distributed system, and multiple daemons need access to the same Postgres database via jOOQ. Since each daemon is its own Java project, I am in the same boat as you basically.
The solution I've been using is to create a third Java project as a Java Library. If you're using Netbeans you can just include it as a subproject dependency and any changes to the library project can be recompiled into the individual application projects.
One thing of note, you'll need to specify the jOOQ library jars in all 3 projects. In Netbeans its easy to specify a project's library directory, and have multiple projects share these dependencies. Netbeans will copy the dependencies at deployment time.
Edit:
The steps are basically:
create a master layout for system, IE:
/master-project/
/master-project/library
/master-project/software
/master-project/software/daemon1
/master-project/software/daemon2
/master-project/common
/master-project/common/utility1
/master-project/common/utility2
create third-party "library" bundles of {jar,src,docs} under /master-project/library.
create "application" projects under /master-project/software, making sure to tell Netbeans to only use third-party libraries under /master-project/library.
create "library" projects under /master-project/common, making sure to tell NB only to use third-party libraries under /master-project/library.
create a "library" for jOOQ code to be shared, as in step 4.
Each project is responsible for its own compile script (including generating jOOQ code, if desirable), and correctly specifying its dependencies out of /master-project/library, and /master-project/common.