Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using an embedded tomcat to start the application #8797

Merged
merged 29 commits into from Jan 26, 2024

Conversation

LucaGiamminonni
Copy link
Contributor

@LucaGiamminonni LucaGiamminonni commented Apr 20, 2023

The purpose of this PR is to allow dspace backend to be started using an embedded tomcat or via an executable jar. It still allows DSpace backend to also run in an external Tomcat (as currently).

Major benefits to this PR

  • Allows DSpace backend to be more easily run in IntelliJ (community edition) and similar IDEs
  • Can be beneficial to Docker deployments (note: our Docker scripts currently use an external Tomcat but could be refactored to use embedded tomcat).
  • Easier to test PRs or run demos using embedded Tomcat (no need to maintain Tomcat separately)

To allow that I made the following changes:

  • the dspace-server-webapp module went from being a war to being a jar; it then becomes a simple dependency like dspace-api or dspace-iif
  • I moved the html and js resources required for the HAL Browser from scr/main/webapp to src/main/resources/static, in order to be detected by spring boot
  • I renamed the Application class of dspace-server-webapp to WebApplication, removing the @SpringBootApplication annotation since the spring boot modules will be others (server and the new server-boot)
  • I update the application.properties to set the context path via server.servlet.context-path = /server
  • I modified the module server adding the class ServerApplication in order to deploy the generated war as we do currently
  • I introduced a new module server-boot in order to run DSpace using an embedded tomcat (see the class ServerBootApplication). To run this class with using the embedded tomcat is enough to run it’s main method with this program argument: --dspace.dir=
    image
    image

With these changes you can start the DSpace backend in 3 ways

Prior to running any of these, you FIRST must install the DSpace backend as normal using mvn clean package; ant fresh_install. Those steps are still required.

  1. (As in DSpace 7) You can deploy the WAR related to the server project in a Tomcat installation
  2. (NEW) You can run the main of ServerBootApplication method from the IDE (Eclipse or Intellij)
  3. (NEW) You can run the executable jar generated for the server-boot project (placed under the target folder). For example java -jar .\server-boot-8.0-SNAPSHOT.jar (this runs the backend using an embedded Tomcat)
    image

These modifications had the side effect of modifying the order in which the beans are discovered and injected into lists annotated with autowired: for example, in DSpacePermissionEvaluator plugins can be inserted in an unspecified order. This highlighted a few issues which I fixed.

Checklist

This checklist provides a reminder of what we are going to look for when reviewing your PR. You need not complete this checklist prior to creating your PR (draft PRs are always welcome). If you are unsure about an item in the checklist, don't hesitate to ask. We're here to help!

  • My PR is small in size (e.g. less than 1,000 lines of code, not including comments & integration tests). Exceptions may be made if previously agreed upon.
  • My PR passes Checkstyle validation based on the Code Style Guide.
  • My PR includes Javadoc for all new (or modified) public methods and classes. It also includes Javadoc for large or complex private methods.
  • My PR passes all tests and includes new/updated Unit or Integration Tests based on the Code Testing Guide.
  • If my PR includes new libraries/dependencies (in any pom.xml), I've made sure their licenses align with the DSpace BSD License based on the Licensing of Contributions documentation.
  • If my PR modifies REST API endpoints, I've opened a separate REST Contract PR related to this change.
  • If my PR includes new configurations, I've provided basic technical documentation in the PR itself.
  • If my PR fixes an issue ticket, I've linked them together.

@LucaGiamminonni LucaGiamminonni changed the title Start REST using an embedded tomcat Using an embedded tomcat to start the application Apr 20, 2023
@tdonohue tdonohue added the code task Code cleanup task label Apr 20, 2023
@tdonohue tdonohue added this to the 7.6 milestone Apr 20, 2023
@tdonohue tdonohue self-requested a review April 20, 2023 13:57
@hardyoyo hardyoyo self-requested a review April 20, 2023 14:16
@tdonohue tdonohue added the needs discussion Ticket or PR needs discussion before it can be moved forward. label Apr 20, 2023
@tdonohue
Copy link
Member

tdonohue commented Apr 20, 2023

@LucaGiamminonni : One immediate question. How does this impact the old (v6) REST API (in [src]/dspace-rest which generates a rest webapp)? We have made promises to provide "backwards combability" with older clients/scripts by allowing sites to optionally include that old REST API alongside the new one. How would one deploy the old (v6) REST API if we were to move this PR forward?

To be clear, I am a big fan of this PR & the movement towards an embedded Tomcat. However, it's unclear to me if we can make this embedded Tomcat change in DSpace 7, or if we'd need to wait for DSpace 8 when the old REST API is removed.

(Rereading your description... I realized that it sounds like we can still deploy the server webapp in an external Tomcat? That may be the approach that would be required if a site needs to continue to use the older rest webapp alongside the server webapp.)

@hardyoyo
Copy link
Member

hardyoyo commented Jan 2, 2024

I'm going to test this PR later today, this is exciting, thanks, @vins01-4science !

@hardyoyo
Copy link
Member

hardyoyo commented Jan 3, 2024

I can confirm that this PR now builds correctly in Docker-Compose, and results in a running DSpace backend instance.

The build works flawlessly:

docker-compose -f docker-compose.yml -f docker-compose-cli.yml build

and then it starts up without any errors:

docker-compose -p d7 up -d
docker-compose -p d7 logs -f

Now I need to reconfirm that the embedded Tomcat version still works. I'll check that and report back, probably tomorrow. But this is looking very promising indeed. @tdonohue will be pleased, I'm sure.

@hardyoyo
Copy link
Member

hardyoyo commented Jan 3, 2024

I've made an attempt at testing the embedded Tomcat, and am stuck. I'm trying to do this from the CLI, working from the comments above, but I can't seem to get past this error

https://gist.github.com/hardyoyo/ba6085196aab0cf9907549ebfb4111bc

when running these commands:

cd dspace/modules/server-boot/target/
java -jar ./server-boot-8.0-SNAPSHOT.jar -Ddspace.dir=/Users/hpotting/d/install/dspace7

There may be another way to override the dspace.dir property, I'll see if I can figure it out.

@hardyoyo
Copy link
Member

hardyoyo commented Jan 3, 2024

I've tried a few options, can cannot see a way to provide an override for the dspace.dir property for the server-boot jar. The inheritance from the dspace parent pom causes dspace.dir to be hardcoded in the server-boot JAR at build time, preventing runtime overrides. If I attempt to globally override the dspace.dir property at build time, the additions module fails to build. OH, after typing all that, I realize I can just skip the additions module. This seems to work:

mvn clean package -pl '!dspace/modules/additions' -Ddspace.dir=/Users/hpotting/d/install/dspace7

well... kinda... it still doesn't build successfully. This is a bit of a tangle, isn't it?

@vins01-4science
Copy link
Contributor

I've tried a few options, can cannot see a way to provide an override for the dspace.dir property for the server-boot jar. The inheritance from the dspace parent pom causes dspace.dir to be hardcoded in the server-boot JAR at build time, preventing runtime overrides. If I attempt to globally override the dspace.dir property at build time, the additions module fails to build. OH, after typing all that, I realize I can just skip the additions module. This seems to work:

mvn clean package -pl '!dspace/modules/additions' -Ddspace.dir=/Users/hpotting/d/install/dspace7

well... kinda... it still doesn't build successfully. This is a bit of a tangle, isn't it?

I tried again and if you provide both logging.dir and dspace.dir it works fine, or otherwise you can provide the application.properties file by using the spring.config.location property.

java -jar server-boot-8.0-SNAPSHOT.jar --spring.config.location=file:///path/to/target/application.properties

Could you try with this one?

Moreover, if we want to just run it without any parameter we need to change the building phase of the jar to just include it, take in count that with that configuration the application.properties will be shipped with the jar itself, and will point outside that jar so that could be a problem for someone that is not familiar with the project, java, spring-boot or maven.

@hardyoyo
Copy link
Member

hardyoyo commented Jan 3, 2024

I've tried this:

java -jar ./server-boot-8.0-SNAPSHOT.jar --spring.config.location=file:///Users/hpotting/d/install/dspace7/application.properties

with dspace.dir set correctly in that application.properties file (copied out of the additions module's target)

I get the same error, the embedded tomcat can't find the log config.

Can you provide an example of what you found that works? You mentioned:

if you provide both logging.dir and dspace.dir it works fine

Can you show me what you mean by that? Thanks!

@vins01-4science
Copy link
Contributor

I've tried this:

java -jar ./server-boot-8.0-SNAPSHOT.jar --spring.config.location=file:///Users/hpotting/d/install/dspace7/application.properties

with dspace.dir set correctly in that application.properties file (copied out of the additions module's target)

I get the same error, the embedded tomcat can't find the log config.

Can you provide an example of what you found that works? You mentioned:

if you provide both logging.dir and dspace.dir it works fine

Can you show me what you mean by that? Thanks!

Sure, here you got the command:

java -jar ./server-boot-8.0-SNAPSHOT.jar --dspace.dir=/path/to/install/folder/ --logging.config=file:///path/to/install/folder/config/log4j2.xml

In this way you are overriding the default configuration of the standard dspace.cfg file.

You will see the log inside the dspace.log file of the installation folder.

@hardyoyo
Copy link
Member

hardyoyo commented Jan 3, 2024

I think what we really need are instructions for testers of this PR. I've tried to get it running, and have gotten close, but still have not completely spun up the server-boot jar. I can't spend any more time on this today, I hope to be able to return to it later in the week. I really want this PR to be merged, because I feel very strongly that this is important for the project. Instructions would help not only me, but any other interested committers, or other community members.

@hardyoyo
Copy link
Member

hardyoyo commented Jan 3, 2024

OK, I managed to spin up the embedded tomcat. Here's what I needed to do:

  1. create a new docker-compose-just-deps.yml file (copy the existing docker-compose.yml file, and remove the config for the service config for the DSpace (backend) webapp container). Here's an example: https://gist.github.com/hardyoyo/f029712f4f68f2986f6628d9c0c4ae91

  2. run that with: docker-compose -f ./docker-compose-just-deps.xml -p d7 up -d

  3. ensure the config (local.cfg and dspace.cfg) have solr.server=http://localhost:8983/solr configured, as well as default database configurations (this is probably correct as-is, but worth double-checking).

  4. build this branch with maven: mvn clean package

  5. cd dspace/modules/server-boot/target

  6. java -jar ./server-boot-8.0-SNAPSHOT.jar --dspace.dir=/path/to/your/local/dspace7/home --logging.config=/path/to/your/local/dspace7/home/config/log4j2.xml --solr.server=http://localhost:8983/solr

step 3 I'm not entirely sure how important it is... but it's what I did.

Alright, I'm confident this all works. We need good docs. I'm going to give this PR a +1

* @author Luca Giamminonni (luca.giamminonni at 4science.it)
*
*/
@SuppressWarnings({ "checkstyle:hideutilityclassconstructor" })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I generally am leery of suppressing checkstyle warnings, in this instance I think it's fine. Calling it out because I noticed it, but I think it's fine to leave this as-is. (A quick search of the entire codebase finds a number of other checkstyle SuppressWarnings invocations, none for this particular warning).

Copy link
Member

@hardyoyo hardyoyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This all looks fine, the Docker build/testing instructions still work for the war build, and the embedded tomcat works as well. I think we'll need lots of docs on how to best make use of the server-boot/embedded tomcat (with instructions for various IDEs). This is a nice improvement for DSpace 8, and will surely lead to improved deployment methods in the future. 👍

@vins01-4science
Copy link
Contributor

vins01-4science commented Jan 4, 2024

This all looks fine, the Docker build/testing instructions still work for the war build, and the embedded tomcat works as well. I think we'll need lots of docs on how to best make use of the server-boot/embedded tomcat (with instructions for various IDEs). This is a nice improvement for DSpace 8, and will surely lead to improved deployment methods in the future. 👍

Thank you, I really appreciate that someone else is getting involved in this and that is giving its help and time to improve this new feature.

Moreover, I think that the better way to execute DSpace from the IDE will be by running it as a standard Java application, it will be compatible with all IDEs. I am going to provide a little recap down here just to allow everyone to run it on their own and provide some feedback.

How to try it out?

With this PR we can execute DSpace with different configurations:

  • War Configuration - Deploy the server.war target related to the /server/pom.xml
  • Jar Configuration - Run the server-boot.jar target related to the server-boot/pom.xml
  • Docker Configuration - Run it by using the docker-compose command
  • Development Configurations - Run it by using the IDE

For each of these configuration you need to be aware of the configuration that you have made during the build of the project.
The application.properties file will be embedded in each of these configuration and it will use the configuration you specified inside the dspace.cfg / local.cfg, thus you can run it without any extra parameters.
If you want to override the configuration you can specify one or more of the following properties (it depends on your needs):

  • spring.config.location - reference to the application.properties file to use
--spring.config.location=file:///path/to/target/application.properties
  • dspace.dir - reference to the installation directory of the application, default in application.properties
--dspace.dir=/path/to/install/folder
  • logging.config - log configuration file of the project, default in application.properties
--logging.config=file:///path/to/target/file/log2.xml
  • Every other configuration property that is placed one of the configuration file, the most important are placed inside dspace.cfg, local.cfg and application.properties

War Configuration

To Generate a proper server.war file, you need to do the following:

  1. Create a local.cfg file with the proper configuration of the system inside the dspace/config folder
    IMPORTANT: This will be used as the default configuration of the generated war file.
  2. Now just locate to the dspace/modules/server folder and run the following command:
mvn package
  1. Once completed you will have:
  • An exploded folder of the war (server-{dspace-version})
  • The war itself (server-{dspace-version}.war)
  1. Each of them can be deployed on the application server (i.e. tomcat or similar), and it will use the dspace.dir you specified in the local.cfg during the build phase so be careful that it contains everything needed (i.e. you have installed correctly your dspace project at least one time using the same local.cfg configuration).

Jar Configuration

To Generate a proper server.-boot.jar file, you need to do the following:

  1. Create a local.cfg file with the proper configuration of the system inside the dspace/config folder
    IMPORTANT: This will be used as the default configuration of the generated war file.
  2. Now just locate to the dspace/modules/server-boot folder and run the following command:
mvn package
  1. Once completed you will have the server-boot-{dspace-version}.jar file in the target folder.
  2. It can be executed with the standard java -jar server-boot-{dspace-version}.jar command, and it will use the dspace.dir you specified in the local.cfg during the build phase so be careful that it contains everything needed (i.e. you have installed correctly your dspace project at least one time using the same local.cfg configuration).
  3. You can override the default configuration by adding the properties as parameter of the execution command.

Docker Configuration

To run the project using docker you need to delete the local.cfg file, and just execute the following

  1. Locate to the main dspace project folder
  2. Build the docker image:
docker-compose -f docker-compose.yml -f docker-compose-cli.yml build
  1. Execute it accordingly:
  docker-compose -p d7 up -d
  docker-compose -p d7 logs -f

Development Configuration

Depending on your preferred IDE you can just run this project with one or more of the previous configuration.

Java Application

For sure, you will be able to run DSpace by configuring it as a standard Java application:

  1. Locate the Java class ServerBootApplication.java inside the server-boot module, and then click on the play icon visible next to the class name
  2. You should change this configuration, this depends on your IDE, so locate this configuration, or if it is possible, just select the modify configuration option
  3. Add the environment variables to determine either dspace.dir and logging.config, this example is for Intellij
    immagine
  4. Now you can run DSpace by using this configuration, as always be sure that you have already created the installation folder.

Maven Configuration

Similarly to the previous configuration:

  1. Locate the pom.xml file of the server-boot project
  2. Right click, and check for Run As Maven Build or just the Maven entry
  3. Find or type the maven goal: spring-boot:run (inside the plugin-goal list)
    immagine
  4. You can override the parameters by using the command-line parameter -Dspring-boot.run.arguments
mvn spring-boot:run -Dspring-boot.run.arguments="--dspace.dir=/path/to/install/folder/ --logging.config=file:///path/to/install/folder/config/log4j2-console.xml"

Deploy on IDE application server

This configuration remains the same as the one in the dspace documentation, the project that will be deployed is the server.

@atarix83 atarix83 requested a review from tdonohue January 8, 2024 10:37
@vins01-4science vins01-4science self-assigned this Jan 8, 2024
Copy link
Member

@tdonohue tdonohue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vins01-4science and @LucaGiamminonni : Thank you for this! I finally got back to reviewing/testing this today. Overall, it looks great, but there are some suggested updates.

The largest is requesting the removal of the changes to GeneralAuthorizationFeatureIT as they seem unrelated to embedded Tomcat and make up the majority of this PR (over 300 lines of changes). If they are related, then they need to be described. If they are not related, then I'd recommend submitting them as a different PR and explaining the purpose better....a 300 line change shouldn't be embedded within an unrelated PR. It needs separate attention.

Beyond that, this PR works very well. I've tested that the basic install process is unchanged (mvn clean package; ant fresh_install; deploy via Tomcat). I've also tested that you can alternatively run java -jar .\server-boot-8.0-SNAPSHOT.jar instead of the deploy via Tomcat (but obviously, first you still must install everything via Ant...but that's expected).

In both scenarios, I've verified that the User Interface and Hal Browser appear to still work with no issues. I've also verified I can use java -jar .\server-boot-8.0-SNAPSHOT.jar --dspace.dir=[directory-path] to run the JAR against a DIFFERENT dspace installation.

A few sidenotes for the future (not required in this PR):

  • After this PR is merged, I think we would need to make some additional updates to the following: Ant scripts (to remove filtering of application.properties from Ant) and Install Documentation (to add this new option).
  • As a future task (likely post-8.0), it'd be wonderful to find a way to remove Ant altogether, so that the runnable JAR can create the dspace.dir directory structure (i.e. run it's own "fresh_install"). That'd allow us to potentially distribute the entire backend as a JAR (no need to build it unless you need to customize it).

dspace-server-webapp/pom.xml Outdated Show resolved Hide resolved
dspace/modules/server/pom.xml Outdated Show resolved Hide resolved
dspace/modules/server-boot/pom.xml Outdated Show resolved Hide resolved
@paulo-graca
Copy link
Contributor

It just came to my mind the Handle Server... would this PR has any affect on how the Handle server integration is currently launched? In the same way, what about the CLI?

@tdonohue
Copy link
Member

tdonohue commented Jan 24, 2024

@paulo-graca : No, this PR has no impact on anything other than Tomcat.

With this PR in place you have two webapp install options:

  1. Install Apache Tomcat with the DSpace "server" WAR as the webapp
  2. Or, alternatively, just run the DSpace "server-boot.jar" (which includes that "server" webapp with an embedded Tomcat).

However, this PR has no impact on the DSpace installation directory (dspace.dir), CLI, Handle Server or other configs stored in that location. With "server-boot.jar" you still need to tell it where dspace.dir is. The only thing this PR changes is how the "server" webapp runs.

Copy link
Member

@tdonohue tdonohue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Thank you @vins01-4science and @LucaGiamminonni ! This all looks good to me now. I cannot find any bugs with the approach taken when testing using the UI.

Obviously, this will require updates to our Installation Documentation: https://wiki.lyrasis.org/display/DSDOC8x/Installing+DSpace

If you have time, I'd appreciate help there. In the meantime, I'll flag with with a needs documentation label to remind us it requires docs.

@tdonohue tdonohue added the needs documentation PR is missing documentation. All new features and config changes require documentation. label Jan 26, 2024
@tdonohue tdonohue merged commit 7ce1893 into DSpace:main Jan 26, 2024
22 checks passed
@paulo-graca
Copy link
Contributor

Great work!

@vins01-4science
Copy link
Contributor

👍 Thank you @vins01-4science and @LucaGiamminonni ! This all looks good to me now. I cannot find any bugs with the approach taken when testing using the UI.

Obviously, this will require updates to our Installation Documentation: https://wiki.lyrasis.org/display/DSDOC8x/Installing+DSpace

If you have time, I'd appreciate help there. In the meantime, I'll flag with with a needs documentation label to remind us it requires docs.

Hello @tdonohue,

the installation procedure has been updated with a new deploy step involving the executable jar configuration.

However, the other changes made with this PR are involving mainly the development procedure (Development Experience), but I cannot find any page that contains this kind of information.
Could you show me where to put that execution information / details?

Thank you.

@tdonohue
Copy link
Member

tdonohue commented Feb 1, 2024

@vins01-4science : Thanks for the updated installation docs!

Regarding developer documentation, you are correct that we don't tend to add that into the official documentation space (DSDOC8x). However, we do have some general IDE docs like these:

If you could find time to document just one IDE (whichever one you tend to use), that might be helpful to others in how to use this feature for development. So, if you tend to use IntelliJ, maybe just update that first page?

Or, honestly, if you feel those pages are way to outdated, just create a brand new page under this one https://wiki.lyrasis.org/display/DSPACE/Developer+Guidelines+and+Tools

My main goal is to just find a way to better document this for feature for development. So, where you create the page doesn't matter much... I can always move it later.

@vins01-4science
Copy link
Contributor

@vins01-4science : Thanks for the updated installation docs!

Regarding developer documentation, you are correct that we don't tend to add that into the official documentation space (DSDOC8x). However, we do have some general IDE docs like these:

* https://wiki.lyrasis.org/display/DSPACE/IDE+Integration+-+DSpace+and+IDEA

* https://wiki.lyrasis.org/display/DSPACE/IDE+Integration+-+DSpace+and+NetBeans

* https://wiki.lyrasis.org/display/DSPACE/IDE+Integration+-+DSpace%2C+Eclipse+and+Tomcat

If you could find time to document just one IDE (whichever one you tend to use), that might be helpful to others in how to use this feature for development. So, if you tend to use IntelliJ, maybe just update that first page?

Or, honestly, if you feel those pages are way to outdated, just create a brand new page under this one https://wiki.lyrasis.org/display/DSPACE/Developer+Guidelines+and+Tools

My main goal is to just find a way to better document this for feature for development. So, where you create the page doesn't matter much... I can always move it later.

Documentation created here: https://wiki.lyrasis.org/display/DSPACE/DSpace+8+development+with+IntelliJ+IDE
Maybe someone could extend it to include instructions for the docker plugin / execution.

Note that the configuration / steps can be reused for pretty much every IDE, since basically we need just to start a standard Java Application and its main method 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code task Code cleanup task needs documentation PR is missing documentation. All new features and config changes require documentation.
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

None yet

6 participants