In the configuration of my template engine I would like to add SpringSecurityDialect() like:
#Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.addDialect(new SpringSecurityDialect());
engine.setEnableSpringELCompiler(true);
engine.setTemplateResolver(templateResolver());
return engine;
}
However eclipse is telling me:
The type org.thymeleaf.dialect.IExpressionEnhancingDialect cannot be resolved. It is indirectly referenced from required .class files
What does this mean and how can I fix it?
In pom.xml I have:
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
As #Lachezar already answered, you have to add those missing dependencies. But the specified version with ext['thymeleaf.version'] = '3.0.0.RELEASE should be the same as in the compile dependencies so you better use ext['thymeleaf.version'] = '3.0.1.RELEASE'.
Furthermore, please note that it is enough to just specify a bean for the security dialect without providing a bean for the template engine. With Thymeleaf on the classpath, it will automatically recognize that the bean is an instance of IDialect and adds it directly to the dialects:
#Bean
public SpringSecurityDialect springSecurityDialect() {
return new SpringSecurityDialect();
}
It means that org.thymeleaf.extras:thymeleaf-extras-springsecurity4 has a dependency to org.thymeleaf:thymeleaf as you can see in the link to the repo above. Apparently you haven't provided this dependency. The class IExpressionEnhancingDialect is there. You can resolve that by adding the dependency to your project.
Since this may get a bit complicated... I'm also playing around with Spring Boot, spring security and the security dialect for thymeleaf (plus spring data with h2). Here are my gradle dependencies for reference, they may help you somehow:
ext['thymeleaf.version'] = '3.0.1.RELEASE'
ext['thymeleaf-layout-dialect.version'] = '2.0.0'
dependencies {
compile("org.springframework.boot:spring-boot-devtools")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity4:3.0.1.RELEASE")
compile("com.h2database:h2")
}
Note that I want to use thymeleaf 3 instead of 2, that is why there are some extra unpleasant tweaks in my configuration.
EDIT: The version of thymeleaf-extras-springsecurity4 should be the same as thymeleaf.version as suggested in the other answer.
Related
So I am working on a spring-mvc project, which suddenly started giving this issue when installed on Windows machines only. It's a thick client app.
When trying to access the swagger docs, following error comes :
The logs show following error in the stacktrace :
2022-04-20 04:15:44.821utc WARN Configuration,main:117 - couldn't read inflector config from resource stream
2022-04-20 04:15:44.821utc WARN Configuration,main:131 - couldn't read inflector config from system property
2022-04-20 04:15:44.853utc WARN OpenAPIV3Parser,main:91 - Exception while reading:
io.swagger.v3.parser.exception.ReadContentException: Unable to read location `openapi.yaml`
at io.swagger.v3.parser.OpenAPIV3Parser.readContentFromLocation(OpenAPIV3Parser.java:238) ~[swagger-parser-v3-2.0.27.jar:2.0.27]
at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:87) ~[swagger-parser-v3-2.0.27.jar:2.0.27]
..
..
2022-04-19 17:19:16.980utc ERROR [swagger-inflector],http-nio-8080-exec-8:175 - Allocate exception for servlet [swagger-inflector]
*java.lang.NullPointerException: Cannot invoke "io.swagger.v3.oas.models.OpenAPI.getComponents()" because "openAPI" is null
at io.swagger.oas.inflector.utils.ExtensionsUtil.removeExtensions(ExtensionsUtil.java:26) ~[swagger-inflector-2.0.6.jar:2.0.6]
at io.swagger.oas.inflector.OpenAPIInflector.getExposedAPI(OpenAPIInflector.java:543) ~[swagger-inflector-2.0.6.jar:2.0.6]*
at io.swagger.oas.inflector.OpenAPIInflector.init(OpenAPIInflector.java:139) ~[swagger-inflector-2.0.6.jar:2.0.6]
at io.swagger.oas.inflector.OpenAPIInflector.<init>(OpenAPIInflector.java:117) ~[swagger-inflector-2.0.6.jar:2.0.6]
at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
at
OpenAPIInflector.getExposedAPI reads swaggerURL location from inflector.yaml file. For some reason on windows, configuration is not picking up openapi.yaml file or corresponding openapi.json file as shown in the screenshot. xxx-openapi.yaml is something defined inside inflector.yaml which in my understanding is being used to generate an openapi.yaml file. In MacOs/local setup I can see this file getting generated and the docs coming up fine.
Please help debug, what the potential cause could be. Permissions are fine on the system this tool is running for inflector.yaml inside classes folder?
here is how the inflector.yaml is defined.
swaggerUrl: xxx-openapi.yaml
xxx-openapi.yaml & inflector.yaml are present in
src/main/resources/
I am also wondering if windows OS is not able to read the files from this path properly. Bases on other posts I have already tried different URLs such as following but they did not work for me.
http://windows-machine-ip:8080/swagger-ui/
http://windows-machine-ip:8080/swagger-ui/index.html
http://windows-machine-ip:8080/v3/api-docs/swagger-ui.html
Note**
openapi: 3.0.0
Dependencies :
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>0.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-inflector</artifactId>
<version>2.0.6</version>
</dependency>
Please guide. I am new to this project as well as swagger on spring-mvc. I will be happy to read about stuff which can lead me to fix this. Not looking for a readymade solution but I have tried almost all relevant solutions across multiple forums and hence the post as I am still not able to find the root cause to this. Also I cannot change the existing implementations (like writing it all from scratch) hence I am here more to understand the root cause.
I'm just installing OpenAPI 3 on Spring Core 5.3.18 (Not Boot) projetc :
1/`<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.7</version>
</dependency>`
2/ Configurer :
#Configuration
#EnableOpenApi
public class SwaggerConfig {
private static final Logger log = LoggerFactory.getLogger(SwaggerConfig.class);
private static String line = "=".repeat(100);
#Bean
public Docket api(ServletContext servletContext) {
log.info(line);
log.info("Docket swagger called : {} , name :{} ", servletContext.getContextPath(), servletContext.getContext("/rs"));
log.info(line);
return new Docket(DocumentationType.OAS_30)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
;
}
3/ WebConfigurer :
`
#Configuration
#EnableWebMvc
public class WebConfigurer implements WebMvcConfigurer {
private static final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
.resourceChain(false);
}`
4/ URL of Swagger UI is :
[root path]/v3/api-docs for documentation
[root path]/swagger-ui/index.html
Hope that help ;-)
For the configuration in PaxExam (version 4) we're using wrappedBundle() as you can see here:
wrappedBundle(mavenBundle().groupId("com.github.tomakehurst").artifactId("wiremock-jre8").versionAsInProject()),
Because we want to create an OSGi bundle out of an ordinary jar.
Then in order the wrap mechanism can be used we have to install the wrap feature:
features(karafStandardRepo, "wrap"),
The problem is when it comes to install wrappedBundle() the wrap feature is not yet there. How can I assure in the PaxExam configuration wrappedBundle() is executed only after the wrap feature is there and ready for use? The Karaf distribution we are using in this test is version 4.0.7.
Thanks for help,
Kladderradatsch
Yes, indeed we had to wrap the WireMock bundle generation by the PaxUrl Wrap mechanism into a separate feature file:
<features name="wiremock-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<feature name="wiremock" version="${project.version}">
<feature prerequisite="true">wrap</feature>
<bundle>
wrap:mvn:com.github.tomakehurst/wiremock-jre8-standalone/2.21.0$Bundle-ClassPath=.
</bundle>
</feature>
</features>
Very important is here to configure the XML namespace properly, namely to address version v1.4.0 otherwise prerequisite is of no use. A further pitfall I stepped in before was not taking the standalone version of WireMock.
Then in the PaxExam configuration I have just installed the feature:
features(maven().groupId("com.company.wiremock").artifactId("wiremock-feature").type("xml").classifier("features").version("1.0.0-SNAPSHOT"), "wiremock"),
When it comes to initialize the WireMockServer in your tests, in order the resources in the new generated WireMock-Bundle can be loaded via ClassLoader.getResource() (internal stuff of that library), you have to do this here in your test otherwise the Bundle-Classloader of that WireMock-Bundle is not used:
#BeforeClass
public static void setup() {
ClassLoader savedClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(WireMockClassRule.class.getClassLoader());
wireMockServer = new WireMockServer(options().dynamicPort());
wireMockServer.start();
} finally {
Thread.currentThread().setContextClassLoader(savedClassLoader);
}
}
#AfterClass
public static void end() {
wireMockServer.stop();
}
You could put this in a JUnit #ClassRule for encapsulation.
I'm aware of this answer: Pax Exam: provisioning bundle with all dependencies
But it feels like I'm doing something wrong when I have to include bundles that are part of bundles that are external to my project.
Here is the error I'm getting:
java.lang.Exception: Could not start bundle wrap:mvn:org.apache.cxf/cxf-bundle-jaxrs/2.7.14 in feature(s) test-dependencies-0.0.0: Unresolved constraint in bundle org.apache.cxf.bundle-jaxrs [80]: Unable to resolve 80.0: missing requirement [80.0] osgi.wiring.package; (&(osgi.wiring.package=com.ctc.wstx.stax)(version>=4.4.0)(!(version>=5.0.0)))
Here is my configuration code for my pax exam test:
#Configuration
public Option[] config() {
MavenArtifactUrlReference karafUrl = maven()
.groupId("org.apache.karaf")
.artifactId("apache-karaf")
.version(karafVersion())
.type("tar.gz");
MavenUrlReference karafStandardRepo = maven()
.groupId("org.apache.karaf.features")
.artifactId("standard")
.classifier("features")
.version(karafVersion())
.type("xml");
return new Option[] {
// KarafDistributionOption.debugConfiguration("5005", true),
karafDistributionConfiguration()
.frameworkUrl(karafUrl)
.unpackDirectory(new File("target/exam"))
.useDeployFolder(false),
keepRuntimeFolder(),
KarafDistributionOption.features(karafStandardRepo , "scr"),
//**Do I seriously need to do this?**
wrappedBundle(mavenBundle("org.codehaus.woodstox", "wstx-lgpl")).noStart(),
//**Why am I doing this?**
wrappedBundle(mavenBundle("org.apache.cxf", "cxf-bundle-jaxrs").version("2.7.14")).noStart(),
//**Some of my bundles use this so I guess this makes sense**
wrappedBundle(mavenBundle("org.apache.commons", "commons-lang3")),
mavenBundle("com.company.project", "common-core").versionAsInProject().start(),
mavenBundle("com.company.project", "common-properties", "1.3.1").start(),
mavenBundle("com.company.project", "rev-common-core", "1.3.1").start(),
mavenBundle("com.company.project", "rev-common-properties", "1.3.1").start(),
mavenBundle("com.company.project", "maintenance-core", "1.3.1").start(),
};
}
So my questions are: why am I getting the error about unresolved constraints, do I have to include even external bundles, and what do I need to do to get my tests to run?
Yes, you have to include all required bundles, Karaf container is running empty, you have to provide all bundles required in your test.
You can create a feature for the module you want to test as a way to supply all required bundles. Then you can use it in your test, e.g:
KarafDistributionOption.features("mvn:group/artifact-id/version/xml", "feature-name")
I have a Maven project, in which I want to try integration-testing an EAR sub-module.
In the integration-test submodule, I do the following:
Properties env;
Context ctx;
env = new Properties();
env.setProperty( "java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
env.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
env.setProperty( "java.naming.provider.url", "remote://localhost:4447");
env.put(Context.SECURITY_PRINCIPAL, "jboss-user");
env.put(Context.SECURITY_CREDENTIALS, "*******");
ctx = new InitialContext( env );
IBMPFacadeRemote bmpFacade = ( IBMPFacadeRemote ) ctx.lookup( "ejb:DeDomain-ejb-1.0-SNAPSHOT/BMPFacade!de.domain.service.IBMPFacadeRemote");
bmpFacade.executeBMPProcess( model1, model2);//model1 & model2 are some entities
The problem: when calling mvn integration-test it ends up with the following Exception
java.lang.ClassCastException: org.jboss.ejb.client.naming.ejb.EjbNamingContext cannot be cast to de.domain.service.IBMPFacadeRemote
Could someone help me to solve this problem? Are there any possibilities to integration-test this using a Local Bean (the maven project uses the failsafe-plugin)?
It is now hard to say what exactly solved the problem, but I will try to mention all made changes that solved the problem.
Added to the pom.xml the dependencies
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-ejb-client-bom</artifactId>
<version>7.1.1.Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-jms-client-bom</artifactId>
<version>7.1.1.Final</version>
<type>pom</type>
</dependency>
Changed the JNDI lookup as follows (after changing the deployed name of the EAR&EJB projects)
IBMPFacadeRemote bmpFacade = ( IBMPFacadeRemote ) ctx.lookup( "ejb:DeDomain-ear/DeDomain-ejb//BMPFacadeBean!de.domain.service.IBMPFacadeRemote");
Got rid of the EJB maven plugin from the EJB Project & of some other resources, like jndi.properties
Probably it is worth mentioning, that the Properties instance remained the same as in the stated in the question.
The JNDI Properties are looking strange for me. I was always successfull with the following Properties for JBoss:
java.naming.provider.url=jnp://localhost:1099
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
jnp.socket.Factory=org.jnp.interfaces.TimedSocketFactory
May be you should double check them.
I want to use logger in my java web application.
I'm using JBossAS 6.0.0.final, cdi (weld), jsf ... etc. Seam solder proposes to use an abstract logger is not tying to a concrete implementation (slf4j, log4j, etc) using jboss-logging api.
In order to get this logger in your code will need to write
# Inject
org.jboss.logging.Logger log
seam-solder.jar has the producer for this logger.
package org.jboss.seam.solder.log;
...
class LoggerProducers
{
# Produces
org.jboss.logging.Logger produceLog (InjectionPoint injectionPoint) {}
}
When I deploying my application, I get an error
15:51:18,300 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] Error installing to Start: name=vfs:///C:/Java/jboss-6.0.0.Final/server/default/deploy/kamis-web-client.5.0.0-SNAPSHOT.ear_WeldBootstrapBean state=Create: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Logger] with qualifiers [#Default] at injection point [[field] #Inject private ru.kamis.suite.webclient.web.breadcrumbs.BreadcrumbsManager.log]
This is due to the seam-solder.jar has not META-INF/beans.xml file, and it is necessary for cdi container.
If to add beans.xml file in seam-solder.jar manually, then the application works WELL.
How to do without hacks?
To build my application I use maven, so my solution is not comfortable and NOT fine.
PS: Former weld-extensions project contained META-INF/beans.xml file in jar.
with seam-solder-3.0.0.Beta1 there should be no need to modify the jar