Spring Boot project structure with Authentication - java

I am learning Spring boot and its modules, but I want avoid to learning bad practices. So can you tell me what project structure is usually using for that?
I am using this structure:
com
+- example
+- myproject
+- Application.java
|
+- config
| +- CustomSecurityConfig.java (extends WebSecurityConfigurerAdapter)
|
+- domain
| +- Customer.java
|
+- repository
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
+- CustomerController.java
Now I need implement JWT Authentication, so I have theese new classes:
CustomAuthFilter.java for Security Filter Chain
CustomUserDetailsService.java for AuthenticationManager
CustomEntryPoint.java for handle exceptions
CustomJwtService.java for managing jwt tokens
CustomAuthController.java for rest endpoints like /login, /logout, /create-user, /reset-password
Can you tell me where store this classes? I have 2 ideas:
Create security folder and put it here together
Split files into existing folders like that: CustomAuthFilter.java -> config, CustomUserDetailsService.java -> service, CustomEntryPoint.java -> config, CustomJwtService.java -> service, CustomAuthController.java -> web
Can yo give me some advice pls? Thank.

This is code organization problem and independent of spring boot.
Go by business sense/ functionality of the module than the technical sense of the module. Functionality sense helps to understand the code easily if you are looking after a while.
+Application.java
+security/
+-CustomAuth
+-CustomJwtSevice
if functionality is scatters in multiple files then keep them in subfolder like 'security' in above.
+Application.java
+security/
+-auth/
+--token/
+---JWTtokenGenerator.java
+---JWTutil.java
+--configuration/
+---SecurityConfig
+---...
+--customer/
+---customerservice.java
+---customerrepo.java
The above pattern works by dividing a module, into sub-module and sub-module to their sub-modules.. so on

Related

Adapter Pattern and packaging

I am working on a project that needs to be refactored in order to achieve decoupled modules.
I need to us an Adapter to decide which module to route to depending on some config.
+===========+
| Front-end |
+===========+
| |
+==================+ +==================+
| RESTful Service1 | | RESTful Service2 |
+==================+ +==================+
| |
+=========================+ +=========+
| Adapter | --- | Config |
+=========================+ +=========+
| | |
+=========+ +=========+ +=========+
| Module1 | | Module2 | | Module3 |
+=========+ +=========+ +=========+
I have a Java application, and want to package the modules in JARS using Maven.
RESTful Service1 will either talk to Module1 or Module2 while RESTful Service2 will always talk to Module3. I need to establish which is the nest way to package these modules.
RESTful Service1 will be in it's own Jar while Module1 and Module2 will have their own Jars too.
Question
Seeing that RESTful Service2 will always talk toModule3 only, should they be in the same Jar? Or should I separate them into two seperate Jars too?
Thanks
Because RS2 when deployed always needs to work with M3, putting them in the same jar offers one benefit: we won’t forget M3 when deploying RS2. But the downside is that it is difficult to reuse and deploy M3 to another system which does not require RS2.
I think the benefit above is little. Often, when deploying a system you should have a document or checklist. Even if some component was forgotten, chance is that you could detect and fix it quickly.
So the better option is to seperate RS2 and M3 into two jars.

spring boot test does not scan subpackages

I'm coding with spring(boot, data, test...) and I'm using TDD, my tests are under src/test/java inside specifics packages just like my normal classes. When I run tests, Spring does not execute my JUnit tests inside the subpackages. For exemple: ApplicationTests runs without any problem but JUnitTest does not. What should I do? I'm getting started with Spring and I don't know what to do. The package organization is bellow:
com
+- example
+- myproject
+- ApplicationTests.java
|
+- domain
| +- JUnitTest.java
ApplicationTests are annoted with #RunWith(SpringRunner.class) and #SpringBootTest
Any help?

NoClassDefFoundError for a class in the same package as another class that runs fine

I'm developing for AEM 6 and I am seeing a NoClassDefFoundError for one of my classes. Here is the setup of my maven project:
+- pom.xml
|
+- parent
| |
| '- pom.xml
|
+- content
| |
| '- pom.xml
|
'- bundles
|
+- pom.xml
|
+- taglib
| |
| '- pom.xml
|
'- components
|
'- pom.xml
Here's a few more details on what is happening:
The bundles pom specifies all child bundles as modules
The content pom
specifies the packaging as content-package and contains the jcr_root
specifies both the taglib bundle and the components bundle as dependencies and embeddeds
The taglib pom.xml has specified the components bundle as a dependency
The components bundle has two classes generated: Component.class and ComponentFactory.class
All of my installed bundles are active in /system/console/bundles
The taglib bundle lists that it imports the package containing the classes
The components bundle lists that it exports the package containing the classes
If I put add the line Component component = new Component() to the tag that I'm using in my jsp, the code runs fine. Loading with my page with the tag containing the code loads fine.
However, if I try to instantiate a ComponentFactory like ComponentFactory factory = new ComponentFactory(), the code will build completely fine and then fail at runtime. Loading my page with the tag results in a white page and the error logs have a NoClassDefFoundError.
I looked into the error and it seems to be an issue of a class being available at compile time but not in the classpath at runtime which makes sense. My confusion is that both classes are in target/classes and the .classpath file doesn't seem to indicate why one would be excluded.
Any insights would be greatly appreciated.

Clojure: LOG4J 1.2.16 & SLF4J 1.5.6 clashing with clj-tika and ring-middleware-logger

I am trying to use clj-tika and ring-middleware-logger in the same project. If I use either of them, everything compiles and works as expected.
However, as soon as I start using both at the same time, I am getting this error at compile time:
CompilerException java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
Normally this means that SLF4J is not in the classpath. However, if I do a lein classpath in my project folder, I can clearly see:
C:\Users\Proprietaire\.m2\repository\org\slf4j\slf4j-api\1.5.6\slf4j-api-1.5.6.jar
So, it should be something else.
Then I ran: mvn dependency:tree to see if there could be SLF4J compatibility issues, and here is what I got for ring-middleware-logger:
[INFO] +- ring.middleware.logger:ring.middleware.logger:jar:0.4.3:compile
[INFO] | +- onelog:onelog:jar:0.4.3:compile
[INFO] | | +- org.clojure:tools.logging:jar:0.2.3:compile
[INFO] | | \- clj-logging-config:clj-logging-config:jar:1.9.6:compile
[INFO] | | +- log4j:log4j:jar:1.2.16:compile
[INFO] | | \- swank-clojure:swank-clojure:jar:1.3.2:compile
[INFO] | \- org.clojars.pjlegato:clansi:jar:1.3.0:compile
And for Tika:
[INFO] +- clj-tika:clj-tika:jar:1.2.0:compile
[INFO] | \- org.apache.tika:tika-parsers:jar:1.2:compile
[INFO] | +- org.apache.tika:tika-core:jar:1.2:compile
[INFO] | +- org.gagravarr:vorbis-java-tika:jar:0.1:compile
[INFO] | | \- org.gagravarr:vorbis-java-core:jar:tests:0.1:test,provided
[INFO] | +- edu.ucar:netcdf:jar:4.2-min:compile
[INFO] | | \- org.slf4j:slf4j-api:jar:1.5.6:compile
[INFO] | +- org.apache.james:apache-mime4j-core:jar:0.7.2:compile
[INFO] | +- org.apache.james:apache-mime4j-dom:jar:0.7.2:compile
[INFO] | +- org.apache.commons:commons-compress:jar:1.4.1:compile
[INFO] | | \- org.tukaani:xz:jar:1.0:compile
[INFO] | +- org.apache.pdfbox:pdfbox:jar:1.7.0:compile
[INFO] | | +- org.apache.pdfbox:fontbox:jar:1.7.0:compile
[INFO] | | \- org.apache.pdfbox:jempbox:jar:1.7.0:compile
[INFO] | +- org.bouncycastle:bcmail-jdk15:jar:1.45:compile
[INFO] | +- org.bouncycastle:bcprov-jdk15:jar:1.45:compile
[INFO] | +- org.apache.poi:poi:jar:3.8:compile
[INFO] | +- org.apache.poi:poi-scratchpad:jar:3.8:compile
[INFO] | +- org.apache.poi:poi-ooxml:jar:3.8:compile
[INFO] | | +- org.apache.poi:poi-ooxml-schemas:jar:3.8:compile
[INFO] | | | \- org.apache.xmlbeans:xmlbeans:jar:2.3.0:compile
[INFO] | | \- dom4j:dom4j:jar:1.6.1:compile
[INFO] | +- org.apache.geronimo.specs:geronimo-stax-api_1.0_spec:jar:1.0.1:c
ompile
[INFO] | +- org.ccil.cowan.tagsoup:tagsoup:jar:1.2.1:compile
[INFO] | +- asm:asm:jar:3.1:compile
[INFO] | +- com.googlecode.mp4parser:isoparser:jar:1.0-RC-1:compile
[INFO] | | \- org.aspectj:aspectjrt:jar:1.6.11:compile
[INFO] | +- com.drewnoakes:metadata-extractor:jar:2.4.0-beta-1:compile
[INFO] | +- de.l3s.boilerpipe:boilerpipe:jar:1.1.0:compile
[INFO] | +- rome:rome:jar:0.9:compile
[INFO] | | \- jdom:jdom:jar:1.0:compile
[INFO] | +- org.gagravarr:vorbis-java-core:jar:0.1:compile
[INFO] | \- com.googlecode.juniversalchardet:juniversalchardet:jar:1.0.3:com
So, one use LOG4J and the other one SLF4J. If I stop using one of these packages, I do not get that error, as soon as I start using both I start getting the one above...
I am not a Java developer, so I am kind of stuck to fix this error. I have the intuition that I can probably make something available in my classpath or something such that the compiler finds it.
In any case, I am not sure why adding ring-middleware-logger conflict with Tika when none use the same packages (even if they are probably related in ways I don't know).
Thanks to #nathan-hughes for the pointers. Here is the final resolution of this issue.
The problem I had is that I didn't initially saw with the maven dependencies report that the org.clojure:tools.logging:jar library was including the slf4j jar version 1.6.2, which I found on the project's GitHub pom.xml file.
Then the next question was: how can we fix this slf4j incompatibilities issues? As #nathan-hughes suggested, just to make the version 1.6.2 a dependency.
So, what I did is simple to add the following two dependencies into my project.clj file:
[org.slf4j/slf4j-api "1.6.2"]
[org.slf4j/slf4j-log4j12 "1.6.2"]
(both are required otherwise logging won't work with the ring middleware)
Now that my Clojure project has these two libraries as direct dependencies, then this force the other packages to use it as well.
Now the compilation errors are gone, and the ring.middleware.logger package is working as expected, and Tika is not complaining neither which suggest that it works with this version of SLF4J without any issues.
There are two slf4j jars, an api jar that the library depends on, and the implementation jar that the application uses. This is from the Libraries section of the slf4j manual:
Authors of widely-distributed components and libraries may code against the SLF4J interface in order to avoid imposing an logging framework on their end-user. Thus, the end-user may choose the desired logging framework at deployment time by inserting the corresponding slf4j binding on the classpath, which may be changed later by replacing an existing binding with another on the class path and restarting the application. This approach has proven to be simple and very robust.
As of SLF4J version 1.6.0, if no binding is found on the class path, then slf4j-api will default to a no-operation implementation discarding all log requests. Thus, instead of throwing a NoClassDefFoundError because the org.slf4j.impl.StaticLoggerBinder class is missing, SLF4J version 1.6.0 and later will emit a single warning message about the absence of a binding and proceed to discard all log requests without further protest. For example, let Wombat be some biology-related framework depending on SLF4J for logging. In order to avoid imposing a logging framework on the end-user, Wombat's distribution includes slf4j-api.jar but no binding. Even in the absence of any SLF4J binding on the class path, Wombat's distribution will still work out-of-the-box, and without requiring the end-user to download a binding from SLF4J's web-site. Only when the end-user decides to enable logging will she need to install the SLF4J binding corresponding to the logging framework chosen by her.
Basic rule Embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a transitive dependency on a specific binding, that binding is imposed on the end-user negating the purpose of SLF4J. Note that declaring a non-transitive dependency on a binding, for example for testing, does not affect the end-user.
SLF4J usage in embedded components is also discussed in the FAQ in relation with logging configuration, dependency reduction and testing.
Since you're using 1.5 version of the api jar, you're seeing it throw the NoClassDefFoundError. It sounds like you have a library using the 1.5.6 version of the api jar that you're trying to use with the 1.6.2 version of the implementation jar.
There is a compatibility report on the slf4j website but it appears to not be updated yet for 1.6 or later. I would expect you'd have better chances getting 1.6.2 to work with the 1.5.6 version than the opposite (if the logger tool is using 1.6-specific features then downgrading the version won't work). I'd try naming the 1.6.2 version as an explicit dependency and see if that works.

How to aggregate JPA entities in seperate jars into a single persistence unit?

In my application right now I have one project which contains all the JPA entities. I would like to modularize my application along feature lines:
Feature1.jar - has all JPA entities for feature 1, business logic, ui logic ... etc
Feature2.jar - has all JPA entities for feature 2, business logic, ... etc
How can JPA 2.0 be configured to place the JPA entities in Feature1.jar and Feature2.jar into the same persistence unit?
Use tag <jar-file> in persistence unit
<jar-file>Feature1.jar</jar>
<jar-file>Feature2.jar</jar>
ear should look like
.ear
+- /lib
| +- persistence.jar
| +- /META-INF
| +- persistence.xml
+- .war file
+- Feature1.jar
+- Feature2.jar

Categories

Resources