I recently started out with Spring-Security and in this context found a project on GitHub matching my interests.
While reading some code i discovered that a class (facade\impl\UserFacadeImpl.java) was linked to the target package. This means, when i run
mvn package: the target-file is created and the import-link is valid
mvn clean: the target-file is destroyed and my IDE marks the import-link as invalid
Imports from the target-directory and the class being used normally:
import com.boza.swaggergen.model.Credential;
import com.boza.swaggergen.model.User;
public class UserFacadeImpl implements UserFacade {
#Override
public User createUser(final User user) {
UserModel userModel = modelMapper.map(user, UserModel.class);
userModel = userService.createUser(userModel);
return modelMapper.map(userModel, User.class);
}
The UserModel class shares the same fields with use User class, but the methods are different.
I have never seen anything like this and am completly baffled. I looked in the configuration files, but couldn`t find a hint where those classes are generated.
Those class are generated by Swagger Codegen. The general workflow is:
Describe API using OpenAPI spec.
Configure Maven 's POM to use swagger-codegen-maven-plugin to generate the codes.
Generate codes by mvn generate-sources (mvn package will call it behind scene)
It only generates an abstract #RestController that is configured with #RequestMapping and the request/response POJO for each API endpoint. You still have to implement the actual logic by extending the generated #RestController.
Related
I need to add an annotation to a class which is in a sperate dependency (in a separate jar) of the project that I am working on. I am wondering that can I do this in Java?
As an example, I need to add an annotation HisClass without touching the source code of HisClass.
public class HisClass{
// ...
}
So, that the above class should be look like below at the build time,
#MyAnnot ( me = MyClass.class )
public class HisClass{
// ...
}
There are many ways:
Write a compiler plugin for javac, and make it add the annotations. This will be quite difficult, as the plugin API has nearly no documentation.
2.(Maybe not possible) Inject the annotation after compiling. Add an extra buildstep after compiling and use a library like ASM to add this annotation to the classfile.
I have a java project containing a spring boot application called processor. This project depends on a project called rules and a project called service. Every project has the same package pattern - my.com.package.
The processor and rules projects both contain classes annotated with a custom annotation #Condition. The annotation interface is annotated with #Retention(RetentionPolicy.RUNTIME). When I scan for classes annotated with #Condition from service or processor like this
private ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(
false);
scanner.addIncludeFilter(new AnnotationTypeFilter(Condition.class));
for (BeanDefinition bd : scanner.findCandidateComponents("my.com")) {
try {
Class<?> c = Class.forName(bd.getBeanClassName());
Condition condition = c.getAnnotation(Condition.class);
register(condition);
} catch (ClassNotFoundException | IOException e) {
logger.error(e.getLocalizedMessage());
}
}
The classes annotated with #Condition in the processor project have the correct class name(my.com.package.x.Class), but the classes annotated with #Condition in the rules project have an incorrect fully qualified class name(my.com.Class) and it only finds 2 out of 5 class names in the project that have the annotation.
If I change the argument to scanner.findCandidateComponents to the full package path in the rules project (my.com.package.rules) while scanning in either processor or service the scanner finds no candidates. If I use my.com.* as the argument it only finds the candidates in the processor project.
I saw a similar question here Using ClassPathScanningCandidateComponentProvider with multiple jar files? and the solution was to pass the class loader to the component provider. I tried getting the class loader of the class doing the scanning and passing it to the provider like this
scanner.setResourceLoader(new PathMatchingResourcePatternResolver(classLoader));
and it didn't change any results for me.
Silly mistake, the problem was I had the wrong version of the rules project defined in the pom for my processor project so it was using an older version of the code.
However this
Condition condition = c.getAnnotation(Condition.class);
returned null for the classes taken from the jar, so this concerns me a little if this code isn't being run from source in my workspace.
I am working with grails application. I want to perform methods like get(),save(),delete(),findBy() etc and associated with domains of grails application. When I execute Domain.get() method inside Utils or src/groovy package I get following error.
Caught: java.lang.IllegalStateException: Method on class [Domain Class] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
java.lang.IllegalStateException: Method on class [Domain Class] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
Any one help me how can I use domain class method inside Utils or src/groovy classes?
This error is caused by interacting with GORM entities that have not been properly registered with GORM. The error doesn't have anything to do with where the interaction is initiated from (src/groovy, grails-app/services/, etc...).
Not always, but most often this error occurs in a testing environment where the entity type has not been registered with GORM.
See the project at https://github.com/jeffbrown/illegalaccessgorm. That project contains the following.
A domain class:
// grails-app/domain/demo/Person.groovy
package demo
class Person {
String name
}
A service:
// grails-app/services/demo/HelperService.groovy
package demo
class HelperService {
int getNumberOfPeople() {
Person.count()
}
}
A utility class:
// src/groovy/demo/SomeHelper.groovy
package demo
class SomeHelper {
int getNumberOfPeople() {
Person.count()
}
}
A unit test for the service:
// test/unit/demo/HelperServiceSpec.grovy
package demo
import grails.test.mixin.TestFor
import spock.lang.Specification
#TestFor(HelperService)
#Mock(Person)
class HelperServiceSpec extends Specification {
void "test gorm method"() {
expect:
service.numberOfPeople == 0
}
}
A unit test for the utility class:
// test/unit/demo/SomeHelperSpec.groovy
package demo
import spock.lang.Specification
#Mock(Person)
class SomeHelperSpec extends Specification {
void "test gorm method"() {
given:
def helper = new SomeHelper()
expect:
helper.numberOfPeople == 0
}
}
Both of those tests pass. If you remove the #Mock(Person) from either of them, the test will fail with the following:
java.lang.IllegalStateException: Method on class [demo.Person] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
If the problem is happening in some context other than a test, knowing more about the context would be helpful. Other likely suspects are Java entities that are not being initialized properly for some reason and in some cases domain classes brought in from plugins can be problematic.
Also, knowing what version of Grails you are using may be relevant.
I hope that all makes sense.
You shouldn't use domain classes inside src/groovy or inside utils. You should use services for it. Check out best practises for Grails architecture:
Domain
Favor placing model domain specific logic in its own domain. Anything that applies to a single domain with few dependencies should go in its domain class. But keep it restricted to the logic specific to that domain only - more complex business logic that deals with a group of domains belongs to a service.
To reuse common partial queries or decompose the complex logic, use named queries and chain them together as required, just like one commonly chains jQuery function calls.
Don't mix any other common utility classes or value objects in the domain folder, rather they can go in src/groovy. If these classes need to support validation, one can annotate them with #Validateable.
If you still want to do it, check this FAQ:
import org.codehaus.groovy.grails.commons.ApplicationHolder
//…
def book = ApplicationHolder.application.getClassForName("library.Book").findByTitle("Groovy in Action")
I made class implementation that packaging the needed classes and send it to execute on server.
I did a method using org.reflections that allows me to load all needed classes to this job. I generate a jar file with this classes and it will be executed on server by a web service. This is already done.
But, I have a situation where occurs a problem that I cannot solve until now.
Ex:
package com.marciob.applications.report.generator;
import com.marciob.applications.onleague.model.Team;
class MyJob implements Job {
public void execute(Team team) {
...
}
}
package com.marciob.applications.onleague.model;
class Team {
private List<Player> players;
// getters and setters
}
When I generate the jar file, there is a MyJob and Team class, but the class Player that is needed by Team class is not found as a dependency because is not found in import statement of Team class.
Anyone knows a way to do this? Find all needed classes, including that was is not indicated in import statement because is in the same package?
Just as sdoca said, it is a mystery how you package your classes.
Since the Player class is in the same package as the Team class, the only way for them not to be packaged together could be if they are in different source folders, i.e. like ${project}/src/main/java and ${project}/src/test/java.
The only way that I can think of (at this moment) to discover the classes which the target class depends on is by analyzing the bytecode, just like the Class Dependency Analyzer tool does it.
In my grails application I have Java classes (src/java). And I want to have access to my domain classes and use GORM features(like get(), findBy..., save(), delete() and etc.) directly from my Java classes. I know, I can do this by Spring IoC: for example, I can add grails service to my Java class:
public class SimpleJavaClass{
//...
#Autowired
private ExampleService exampleService;
//...
}
And wireup each instance of this class by Spring:
//...
GrailsApplication grailsApplication
//...
def simpleAction(){
def instance = new SimpleJavaClass()
grailsApplication.mainContext.autowireCapableBeanFactory.autowireBean(instance)
}
But may be there is more appropriate way to do same?
Using Grails 2.0, the only current way is to package your domain classes into a binary plugin (see http://grails.org/doc/2.0.x/guide/single.html#binaryPlugins)
You then can depend on this binary plugin and because it is precompiled the Java code will see many of the GORM methods which are wired into the byte code