Ninja is a full stack web framework for Java. Rock solid, fast and super productive.

Overview
 _______  .___ _______        ____.  _____   
 \      \ |   |\      \      |    | /  _  \  
 /   |   \|   |/   |   \     |    |/  /_\  \ 
/    |    \   /    |    \/\__|    /    |    \
\____|__  /___\____|__  /\________\____|__  /
     web\/framework   \/                  \/ 

Ninja - web framework

Ninja is a full stack web framework for Java. Rock solid, fast and super productive.

Getting started

Comments
  • Add integrated Metrics support

    Add integrated Metrics support

    This is a basic integration of Metrics support. It currently collects and exposes Route and JVM metrics over JMX (install MBean plugin in VisualVM). Individual controller methods may be annotated with @Timed for the integration to collect and report metrics.

    This PR will create a merge conflict with #195 since they both implement a getRoutes() method for the Router. Assuming one or the other is merged, I will rebase.

    opened by gitblit 57
  • Allow remember me functionality via session cookie

    Allow remember me functionality via session cookie

    https://github.com/ninjaframework/ninja/issues/415

    Added Session.setExpiryTime() for setting the expiry time of sessions.

    Added 'remember me' toggle to the JPA blog to demonstrate Session.setExpiryTime().

    opened by watsonmw 42
  • Handling multipart requests

    Handling multipart requests

    First of all let me note that this PR is not complete yet and needs community's feedback.

    What this PR targets

    Parameter injection into controller methods does not work yet with multipart/form-data requests. This issue was addressed in mail group here where @raphaelbauer proposed to make @Param("...") String param work with multipart requests and additionally introduce something like @File("...") File file that directly injects uploaded file into controller's method. Besides, i found an old issue #88 that roughly says to hide commons-upload behind some Ninja API. Well, this PR is all about those issues.

    What's already done

    Almost everything to handle multipart requests. There are new annotations @FileParam and @FileParams that can be applied to controller method's parameters. For instance, by adding @FileParam("myfile") File file into your controller method you have a ready java.io.File instance to read uploaded file contents from. Additionally, every form parameter of a multipart request (i.e. those that are not attached files) can be injected by @Param annotation.

    What's not done, issues

    ~~Cleanup of uploaded files~~

    When multipart request are parsed, uploaded files are locally saved in temp directory. I need your feedback on how to clean up those files.

    • First thing that comes to my mind is to use finalize method of Context implementation(references to files are stored in Context).
    • Or there may be some aggregator of temporary files which deletes them after some time (thinking of a scheduler).

    What are your suggestions? Can we leave cleanup responsibility to application developers or app administrators? I guess not :)

    ~~Commons-upload~~

    Well there are no issues with the library ;) This is more related to issue #88. Currently to handle file uploads we use Context.getFileItemIterator() which returns us an iterator of multipart items aka parts. This is the recommended way of handling parts, it is described in Streaming API. As its name implies parts are streamed and you have to handle them once. In this PR, multipart requests are parsed automatically (i.e. iterator is used) and all related parameters and files are available for injection. So Context.getFileItemIterator() becomes useless -- it won't anymore return an iterator that you can iterate through parts. I thought to put @Deprecated on that method but deprecated methods shall have their old behavior for migration period but in our case that won't be the case. How hard would migration be if that method is removed?

    opened by bazi 39
  • Ninja app drastically slow / stop responding after some time.

    Ninja app drastically slow / stop responding after some time.

    Hi there

    I have a probleme that occure after 1 / 2 days of exploitation in my production server. The symptoms are :

    • all the server 8 core CPU at 100% usage.
    • the ninja app stop responding to request
    • ninja app memory usage rise up to 5/6 Go of Ram
    • my server dump is full of (arround 150) :
    "qtp55909012-2270" 
       java.lang.Thread.State: TIMED_WAITING
            at sun.misc.Unsafe.park(Native Method)
            at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
            at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:389)
            at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:531)
            at org.eclipse.jetty.util.thread.QueuedThreadPool.access$700(QueuedThreadPool.java:47)
            at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:590)
            at java.lang.Thread.run(Thread.java:745)
    

    After searching on the google I think that the problem is that the Ninja JVM reach the XMX (which I have not set at the startup command on my 32Go of ram server). And then the JVM use all the CPU to try to free some memory without success. So the CPU is fully used and the Ninja app stop responding.

    And after looking at all dump I have like 6 threads running some clients code and all the rest is that sun.misc.Unsafe.park(Native Method) : about 150 occurrences of this. I don’t know if this is another symptom or the root cause of the problem. I am still waiting that the problem occure one more time in order to check my memory usage and log files.

    It is the first time I am facing this sort of problem. And the website has not so many user yet : around 8/12 at the same time at maximum. I found on Google that it can be a lock problem. I am a little bit lost. Any help would be appreciated.

    Thanks.

    opened by danielsawan 32
  • Fix issue exposed when saving the cookie on every request.

    Fix issue exposed when saving the cookie on every request.

    Redirect routes were returning the same Result object every time and this object could be modified by the session or by filters. The fix is to make a copy of this Result on each request before it can be modified.

    Since setting the cookie on every request is prone to race conditions, dont do it in the default example and update the session docs to explain the issue.

    This pull request originates from this discussion:

    https://github.com/ninjaframework/ninja/pull/416

    opened by watsonmw 32
  • added proposal for authenticity handling #23

    added proposal for authenticity handling #23

    This is a proposal for authenticity handling from #23

    You call in the template either ${authenticity("form")} or ${authenticity("token")} and it is checked via the filter, when you add the filter to one of your controller methods.

    This proposal is open for discussion. I will add tests and update the documentation once we agree on a final way to go.

    opened by svenkubiak 32
  • Session cookie encryption

    Session cookie encryption

    We use Ninja framework and in our deployment we needed session cookies to be encrypted. This was achieved by injecting a modified implementation of Session interface. This PR introduces session cookie encryption into Ninja so that others can make use of it. Here are some important points:

    • session encryption is optional, it is disabled by default
    • enabling it is pretty simple -- ~~a secret key should be included in application.conf with application.cookie.secret property~~ add application.cookie.encryption=true
    • ~~DES~~ AES algorithm is used ~~by default~~ -- mainly because it is strong and is one of the widely supported algorithms of every implementation of the Java platform
    • ~~encryption algorithm can be customized by implementing CookieEncryptionKeyGenerator interface and binding the interface type to that implementation~~
    • encrypted session cookie value without sign is encoded in base64 - it is more efficient in terms of space (which is important as cookie size is limited)

    Testing:

    • SessionCookieTest is updated and run two times by JUnit's Parameterized runner
      1. existing unencrypted session cookie tests
      2. encrypted session cookies tests

    Documentation is also updated with brief description. Further updates are appreciated.

    opened by bazi 31
  • Open freemarker template engine configuration.

    Open freemarker template engine configuration.

    Just two little modifications that will allow :

    • to act on the freemarker configuration, by injecting the TemplateEngineFreemarker and calling getConfguration() (Useful to add, for example, user-defined shared variables or methods)
    • to override the default suffix for freemarker templates Please note it's my very first pull request using github, I hope I did it right.
    opened by jlannoy 31
  • Refactored servlet and standalone to prepare for eventual non-servlet-based Ninjas

    Refactored servlet and standalone to prepare for eventual non-servlet-based Ninjas

    Fairly large commit to prepare for non-servlet-based contexts, bootstraps, and standalones. Should finally remove the overall reliance on servlets to Bootstrap a Ninja application. Here are the main changes...

    ninja-servlet/src/main/java/ninja/servlet/NinjaBootstrap.java

    • Non-servlet functionality extracted to ninja-core/src/main/java/ninja/Bootstrap.java and is now part of ninja-core.
    • Servlet functionality extracted to ninja-servlet/src/main/java/ninja/servlet/NinjaServletBootstrap.java

    ninja-servlet/src/main/java/ninja/servlet/ContextImpl.java

    • Non-servlet functionality extracted to ninja-core/src/main/java/ninja/utils/AbstractContext.java and is now part of ninja-core.
    • Servlet functionality extracted to ninja-servlet/src/main/java/ninja/servlet/NinjaServletContext.java

    ninja-standalone/src/main/java/ninja/standalone/NinjaJetty.java

    • Non-jetty functionality extracted to ninja-core/src/main/java/ninja/standalone/AbstractStandalone.java and is now part of ninja-core.
    • Jetty functionality retained in ninja-standalone/src/main/java/ninja/standalone/NinjaJetty.java
    • New ninja-core/src/main/java/ninja/standalone/Standalone.java interface that any standalone is required to implement.

    Other notable enhancements

    • Any Ninja standalone configuration (e.g. ninja.port) now available in conf/application.conf. The priority of settings is systemProperty then configurationProperty then defaultValue.
    • New 'ninja.standalone' system property available to change the standalone implementation to be used for NinjaTestServer or maven plugin. I have been working on an Undertow implementation for Ninja standalone and this let's me pick what Ninja uses in key spots. It defaults to NinjaJetty.

    Where are the docs & changelog?

    Let me know what you think of the PR first and I can add the final doc and changelog info.

    opened by jjlauer 30
  • Weird behavior of UnitOfWork: breaks Transactional

    Weird behavior of UnitOfWork: breaks Transactional

    UnitOfWork caches the retrieved values from EntityManager somewhere (seems like thread local of threads in Jetty's pool) even if the database's cache is disabled completely.

    Here is the repo of the project to reproduce: https://github.com/nobullet/unitofwork-transactional

    The heart of the app is UserService: a) it loads an User object from database (or creates new if not found), increments its field #visited and saves it back to database each second (#doStuffEachSeconds) in @Transactional method.

    b) it has 2 methods that do the same thing: query the User object by name. getUserOneUOW - is @UnitOfWork annotated getUserOneT - is @Transactional annotated

    c) ApplicationController has two methods to render the retrieved objects to JSON (with no-cache headers): one calls UserService#getUserOneUOW, the other calls UserService#getUserOneT

    Steps to reproduce:

    1. clone the aforementioned repo
    2. cd to the folder of the repo
    3. chmod +x ./standalone_dev.sh
    4. ./standalone_dev.sh (this will start simple Ninja app in standalone mode with H2 database with completely disabled database cache - see persistence.xml, reproducible in MySQL too).
    5. When app starts you should see the warn messages like about saved User entity with name one and the current value of visited field: 01:38:55.350 WARN Ninja.useCase [48] - User one visited: 51 times, 1 users in database. [pool-1-thread-1] 01:38:55.350 WARN Ninja.useCase [48] - User one visited: 52 times, 1 users in database. [pool-1-thread-1] etc
    6. Open this url http://localhost:8081/test/userT.json - @Transactional method, in browser, run several times. Switch back to the console and make sure the url returns same results for #visited field as in logs (console) and database. At this point we are using @Transactional method and everything is fine.
    7. Now open http://localhost:8081/test/userUOW.json - @UnitOfWork method and run it several times (> than number of cores that your processor has). It will start to return cached values (depends on thread from Jetty's thread pool) and while UserService#doStuffEachSeconds continues to increment the returned entities are cached and have obsolete #visited values. The returned User instances are cached somewhere (like thread locals in Jetty's threads).
    8. If you switch back and try to run @Transactional method (6) it will start to return same cached values as (7): UnitOfWork has broken the Transactional behavior.

    mvn -version Apache Maven 3.1.1 (hashcode; 2013-09-17 08:22:22-0700) Maven home: /Users/nb1967/bin/maven Java version: 1.8.0, vendor: Oracle Corporation Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre Default locale: en_US, platform encoding: UTF-8 OS name: "mac os x", version: "10.9.2", arch: "x86_64", family: "mac"

    sysctl hw.ncpu | awk '{print $2}' # number of cores 8

    bug 
    opened by nobullet 26
  • Fix directory listing

    Fix directory listing

    Steps to reproduce

    $ mvn archetype:generate -DarchetypeGroupId=org.ninjaframework -DarchetypeArtifactId=ninja-servlet-archetype-simple
    $ cd MY_INSTALLED_PROJECT
    $ mvn clean package
    $ mvn ninja:run -Dninja.mode=prod -Dninja.ssl.port=-1 &
    $ curl http://localhost:8080/assets/css/
    custom.css
    

    I think that curlshould get "404 not found". But Ninja returns file list in the directory. This PR will fix this problem.

    opened by mallowlabs 22
  • [SECURITY] Fix Temporary File Information Disclosure Vulnerability

    [SECURITY] Fix Temporary File Information Disclosure Vulnerability

    Security Vulnerability Fix

    This pull request fixes a Temporary File Information Disclosure Vulnerability, which existed in this project.

    Preamble

    The system temporary directory is shared between all users on most unix-like systems (not MacOS, or Windows). Thus, code interacting with the system temporary directory must be careful about file interactions in this directory, and must ensure that the correct file posix permissions are set.

    This PR was generated because a call to File.createTempFile(..) was detected in this repository in a way that makes this project vulnerable to local information disclosure. With the default uname configuration, File.createTempFile(..) creates a file with the permissions -rw-r--r--. This means that any other user on the system can read the contents of this file.

    Impact

    Information in this file is visible to other local users, allowing a malicious actor co-resident on the same machine to view potentially sensitive files.

    Other Examples

    The Fix

    The fix has been to convert the logic above to use the following API that was introduced in Java 1.7.

    File tmpDir = Files.createTempFile("temp dir").toFile();
    

    The API both creates the file securely, ie. with a random, non-conflicting name, with file permissions that only allow the currently executing user to read or write the contents of this file. By default, Files.createTempFile("temp dir") will create a file with the permissions -rw-------, which only allows the user that created the file to view/write the file contents.

    :arrow_right: Vulnerability Disclosure :arrow_left:

    :wave: Vulnerability disclosure is a super important part of the vulnerability handling process and should not be skipped! This may be completely new to you, and that's okay, I'm here to assist!

    First question, do we need to perform vulnerability disclosure? It depends!

    1. Is the vulnerable code only in tests or example code? No disclosure required!
    2. Is the vulnerable code in code shipped to your end users? Vulnerability disclosure is probably required!

    Vulnerability Disclosure How-To

    You have a few options options to perform vulnerability disclosure. However, I'd like to suggest the following 2 options:

    1. Request a CVE number from GitHub by creating a repository-level GitHub Security Advisory. This has the advantage that, if you provide sufficient information, GitHub will automatically generate Dependabot alerts for your downstream consumers, resolving this vulnerability more quickly.
    2. Reach out to the team at Snyk to assist with CVE issuance. They can be reached at the Snyk's Disclosure Email.

    Detecting this and Future Vulnerabilities

    This vulnerability was automatically detected by GitHub's CodeQL using this CodeQL Query.

    You can automatically detect future vulnerabilities like this by enabling the free (for open-source) GitHub Action.

    I'm not an employee of GitHub, I'm simply an open-source security researcher.

    Source

    This contribution was automatically generated with an OpenRewrite refactoring recipe, which was lovingly hand crafted to bring this security fix to your repository.

    The source code that generated this PR can be found here: SecureTempFileCreation

    Opting-Out

    If you'd like to opt-out of future automated security vulnerability fixes like this, please consider adding a file called .github/GH-ROBOTS.txt to your repository with the line:

    User-agent: JLLeitschuh/security-research
    Disallow: *
    

    This bot will respect the ROBOTS.txt format for future contributions.

    Alternatively, if this project is no longer actively maintained, consider archiving the repository.

    CLA Requirements

    This section is only relevant if your project requires contributors to sign a Contributor License Agreement (CLA) for external contributions.

    It is unlikely that I'll be able to directly sign CLAs. However, all contributed commits are already automatically signed-off.

    The meaning of a signoff depends on the project, but it typically certifies that committer has the rights to submit this work under the same license and agrees to a Developer Certificate of Origin (see https://developercertificate.org/ for more information).

    - Git Commit Signoff documentation

    If signing your organization's CLA is a strict-requirement for merging this contribution, please feel free to close this PR.

    Sponsorship & Support

    This contribution is sponsored by HUMAN Security Inc. and the new Dan Kaminsky Fellowship, a fellowship created to celebrate Dan's memory and legacy by funding open-source work that makes the world a better (and more secure) place.

    This PR was generated by Moderne, a free-for-open source SaaS offering that uses format-preserving AST transformations to fix bugs, standardize code style, apply best practices, migrate library versions, and fix common security vulnerabilities at scale.

    Tracking

    All PR's generated as part of this fix are tracked here: https://github.com/JLLeitschuh/security-research/issues/18

    opened by JLLeitschuh 0
  • X-Forwarded-For does an insecure internal DNS lookups for user-provided hosts

    X-Forwarded-For does an insecure internal DNS lookups for user-provided hosts

    An attacker can put a DNS name into the X-Forwarded-For header and Ninja would do a DNS lookup of it.

    The code responsible is in AbstractContext.getRemoteAddr:

                        // If ip4/6 address string handed over, simply does pattern validation.
                        InetAddress.getByName(forwardHeader);
    

    So, contrary to the comment, getByName doesn't do a simple validation, but also does a DNS lookup if the provided value is not an IP address. This code is irrelevant and should be removed.

    opened by tenor-dev 0
  • Test Smell: it is not a good practice to write return statement in test case

    Test Smell: it is not a good practice to write return statement in test case

    Hi!

    I notice that you write a test case with a return statement. image

    It is not a good idea to write the return statement in your test case. So I would like to know if is it really a useful test case? It also has no assertions. Maybe I think you should remove the @test annotation from this method ? Thanks.

    opened by TestSmell 0
  • Code optimization suggestions

    Code optimization suggestions

    Hi,

    I find that the private field metricsService at Line 36 in the file 'ninja/ninja-metrics/src/main/java/ninja/metrics/InstrumentedCache.java' on the develop branch is only assigned and used in the method InstrumentedCache. Therefore, this field can be removed from the class, and become a local variable in the method InstrumentedCache. Besides, for method init, the field metricsService can be converted to an input parameter.This transformation will normally reduce memory usage and improve readability of your code.I will be happy if this transformation is helpful.

    private MetricsService metricsService; // line 36 this field can be replaced by local variable
    
    InstrumentedCache(Cache cache, MetricsService metricsService) {
    		this.underlyingCache = cache;
      	// MetricsService metricsService = metricsService;
        this.metricsService = metricsService;
      	// init(metricsService);
        init();
    }
    // private void init(MetricsService metricsService)
    private void init() {
         MetricRegistry registry = metricsService.getMetricRegistry();
    
         hitCounter = registry.counter("ninja.cache.hits");
         missCounter = registry.counter("ninja.cache.miss");
    }
    
    opened by noobyu6 0
  • Retrieve url path from template

    Retrieve url path from template

    Hello,

    I am looking for a way to get the actual URL from the freemarker template without using the Results.render(). I want it to be global. I thought the Implicit functions ${contextPath} would do the trick but i got an empty result. I also tried to use the TemplateEngineFreemarker and the setSharedVariable on each route request in Ninja.java but it gets overwritten if multiple requests run in parallels (not threadsafe or not for this type of usage).

    And now I have no idea to do it. Any help is appreciated.

    Thanks !

    opened by danielsawan 0
Owner
Ninja Web Framework
Ninja Web Framework
An Intuitive, Lightweight, High Performance Full Stack Java Web Framework.

mangoo I/O mangoo I/O is a Modern, Intuitive, Lightweight, High Performance Full Stack Java Web Framework. It is a classic MVC-Framework. The foundati

Sven Kubiak 52 Oct 31, 2022
A web MVC action-based framework, on top of CDI, for fast and maintainable Java development.

A web MVC action-based framework, on top of CDI, for fast and maintainable Java development. Downloading For a quick start, you can use this snippet i

Caelum 347 Nov 15, 2022
Firefly is an asynchronous web framework for rapid development of high-performance web application.

What is Firefly? Firefly framework is an asynchronous Java web framework. It helps you create a web application Easy and Quickly. It provides asynchro

Alvin Qiu 289 Dec 18, 2022
An evolving set of open source web components for building mobile and desktop web applications in modern browsers.

Vaadin components Vaadin components is an evolving set of high-quality user interface web components commonly needed in modern mobile and desktop busi

Vaadin 519 Dec 31, 2022
:rocket: Lightning fast and elegant mvc framework for Java8

Based on Java8 + Netty4 to create a lightweight, high-performance, simple and elegant Web framework ?? Spend 1 hour to learn it to do something intere

Blade Framework 5.7k Dec 28, 2022
:rocket: Lightning fast and elegant mvc framework for Java8

Based on Java8 + Netty4 to create a lightweight, high-performance, simple and elegant Web framework ?? Spend 1 hour to learn it to do something intere

Blade Framework 5.7k Jan 5, 2023
The modular web framework for Java and Kotlin

∞ do more, more easily Jooby is a modern, performant and easy to use web framework for Java and Kotlin built on top of your favorite web server. Java:

jooby 1.5k Dec 16, 2022
A server-state reactive Java web framework for building real-time user interfaces and UI components.

RSP About Maven Code examples HTTP requests routing HTML markup Java DSL Page state model Single-page application Navigation bar URL path UI Component

Vadim Vashkevich 33 Jul 13, 2022
Javalin - A simple web framework for Java and Kotlin

Javalin is a very lightweight web framework for Kotlin and Java which supports WebSockets, HTTP2 and async requests. Javalin’s main goals are simplicity, a great developer experience, and first class interoperability between Kotlin and Java.

David (javalin.io) 6.2k Jan 6, 2023
Vaadin 6, 7, 8 is a Java framework for modern Java web applications.

Vaadin Framework Vaadin allows you to build modern web apps efficiently in plain Java, without touching low level web technologies. This repository co

Vaadin 1.7k Jan 5, 2023
Apache Wicket - Component-based Java web framework

What is Apache Wicket? Apache Wicket is an open source, java, component based, web application framework. With proper mark-up/logic separation, a POJO

The Apache Software Foundation 657 Dec 31, 2022
Micro Java Web Framework

Micro Java Web Framework It's an open source (Apache License) micro web framework in Java, with minimal dependencies and a quick learning curve. The g

Pippo 769 Dec 19, 2022
True Object-Oriented Java Web Framework

Project architect: @paulodamaso Takes is a true object-oriented and immutable Java8 web development framework. Its key benefits, comparing to all othe

Yegor Bugayenko 748 Dec 23, 2022
A simple expressive web framework for java. Spark has a kotlin DSL https://github.com/perwendel/spark-kotlin

Spark - a tiny web framework for Java 8 Spark 2.9.3 is out!! Changeset <dependency> <groupId>com.sparkjava</groupId> <artifactId>spark-core</a

Per Wendel 9.4k Dec 29, 2022
The Grails Web Application Framework

Build Status Slack Signup Slack Signup Grails Grails is a framework used to build web applications with the Groovy programming language. The core fram

grails 2.7k Jan 5, 2023
jetbrick web mvc framework

jetbrick-webmvc Web MVC framework for jetbrick. Documentation http://subchen.github.io/jetbrick-webmvc/ Dependency <dependency> <groupId>com.githu

Guoqiang Chen 25 Nov 15, 2022
🚀 The best rbac web framework. base on Spring Boot 2.4、 Spring Cloud 2020、 OAuth2 . Thx Give a star

?? The best rbac web framework. base on Spring Boot 2.4、 Spring Cloud 2020、 OAuth2 . Thx Give a star

pig-mesh 4.3k Jan 8, 2023
RESTEasy is a JBoss project that provides various frameworks to help you build RESTful Web Services and RESTful Java applications

RESTEasy RESTEasy is a JBoss.org project aimed at providing productivity frameworks for developing client and server RESTful applications and services

RESTEasy 1k Dec 23, 2022
Java Web Toolkit

What is JWt ? JWt is a Java library for developing web applications. It provides a pure Java component-driven approach to building web applications, a

null 48 Jul 16, 2022