I'm having trouble while trying to run JUnit 5 test suite using jmeter-maven-plugin version 3. The setup and tear down phases of the test suite are not invoked at all. However, the methods annotated with #Test are called.
My setup is this:
First project (contains the JUnit test case)
Dummy test suite (BasiTest.java):
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
#TestInstance(Lifecycle.PER_CLASS)
public class BasicTest {
public BasicTest() {
}
#Test
public void passingTest() {
System.out.println("I'm a simple test that passes!");
}
#BeforeAll
public void setUp() {
System.out.println("setUp");
}
#AfterAll
public void tearDown() {
System.out.println("tearDown");
}
}
And the pom.xml file contains:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Second project (should run the jar generated by the first project via jmeter-maven-plugin)
The pom.xml file:
<build>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>configuration</id>
<goals>
<goal>configure</goal>
</goals>
</execution>
<execution>
<id>jmeter-tests</id>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
</executions>
<configuration>
<overrideRootLogLevel>debug</overrideRootLogLevel>
<jmeterExtensions>
<artifact>org.junit.jupiter:junit-jupiter:5.6.2</artifact>
</jmeterExtensions>
<junitLibraries>
<artifact>com.dummy.group.id:junit4sample:0.0.1-SNAPSHOT-tests</artifact>
</junitLibraries>
</configuration>
</plugin>
</plugins>
</build>
And the JMeter test scenario (JMX file) is:
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.2.1">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">1</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">10</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
</ThreadGroup>
<hashTree>
<JUnitSampler guiclass="JUnitTestSamplerGui" testclass="JUnitSampler" testname="JUnit Request" enabled="true">
<stringProp name="junitSampler.classname">com.dummy.group.id.BasicTest</stringProp>
<stringProp name="junitsampler.constructorstring"></stringProp>
<stringProp name="junitsampler.method">passingTest</stringProp>
<stringProp name="junitsampler.pkg.filter"></stringProp>
<stringProp name="junitsampler.success">Test successful</stringProp>
<stringProp name="junitsampler.success.code">1000</stringProp>
<stringProp name="junitsampler.failure">Test failed</stringProp>
<stringProp name="junitsampler.failure.code">0001</stringProp>
<stringProp name="junitsampler.error">An unexpected error occurred</stringProp>
<stringProp name="junitsampler.error.code">9999</stringProp>
<stringProp name="junitsampler.exec.setup">false</stringProp>
<stringProp name="junitsampler.append.error">false</stringProp>
<stringProp name="junitsampler.append.exception">false</stringProp>
<boolProp name="junitsampler.junit4">true</boolProp>
</JUnitSampler>
<hashTree>
<ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<url>true</url>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>
I have to mention that the jar file containing the JUnit test cases (first project) is loaded by the junit plugin, the method annotated with #Test is running (I'm able to see the output in the console) but the setup and tear down phases are completely ignored.
Do you have any idea why?
Thanks a lot!
JMeter calls setUp and tearDown functions automatically
You need to call functions annotated with #BeforeClass and #AfterClass explicitly from separate JUnit Request samplers, the same applies to #BeforeAll and #AfterAll
I don't think JUnit 5 is officially supported, consider downgrading to JUnit 4, otherwise you will be left alone with your problems
More information: How to Use JUnit With JMeter
Related
I am trying to complete the web tutorial 'Creating a simple web application using a MySQL database'. The NetBeans project name is 'IFPWAFCAD' and I am using GlassFish 5 and Java EE 5.
The database and its tables are listed correctly under Project Services, and the database shows as connected.
I am unable to deploy the application after attempting to create a connection pool. The xml files are as follows:
web.xml:
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<resource-ref>
<description>Database for IFPWAFCAD application
</description>
<res-ref-name>jdbc/IFPWAFCAD</res-ref-name>
<res-type>javax.sql.ConnectionPoolDataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>
glassfish-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
<class-loader delegate="true"/>
<jsp-config>
<property name="keepgenerated" value="true">
<description>Keep a copy of the generated servlet class' java code.</description>
</property>
</jsp-config>
</glassfish-web-app>
glassfish-resources.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-resource enabled="true" jndi-name="jdbc/IFPWAFCAD" object-type="user" pool-name="IfpwafcadPool">
<description>Accesses IFPWAFCAD database</description>
</jdbc-resource>
<jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="table" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="IfpwafcadPool" non-transactional-connections="false" ping="false" pool-resize-quantity="2" pooling="true" res-type="javax.sql.ConnectionPoolDataSource" statement-cache-size="0" statement-leak-reclaim="false" statement-leak-timeout-in-seconds="0" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="true">
<property name="URL" value="jdbc:mysql://localhost:3306/mynewdatabase?zeroDateTimeBehavior=convertToNull"/>
<property name="User" value="root"/>
<property name="Password" value="23447HP"/>
</jdbc-connection-pool>
</resources>
I'm trying to replicate the JMeter script described here: https://www.blazemeter.com/blog/selenium-vs-jmeter-which-one-should-you-choose-and-when -- specifically under the "Front End: Testing Custom Communication Channels".
The author talks about setting up JSON assertions to verify response data, which is where I'm stuck. I'll post my code at the end, but what I've done is setup a HTTP request to POST to https:\reqres.in\api\users, sending the JSON payload shown in the article:
{
"name": "new_user",
"job": "user_role"
}
I then have the HTTP Header Manager setup with the header "Content-Type" set to "application/JSON". Finally, there's a JSON response assertion I tried to setup to replicate the author's description. I checked the box for "Match as regular expression" and set the expected value as [0-9]+. (I'm guessing this is where I went horribly wrong.)
The script's view results tree listener shows that the script did get a response:
{"name":"new_user","job":"user_role","id":"86","createdAt":"2020-11-16T23:41:04.645Z"}
But the script failed because the assertion failed with this message:
Assertion error: false
Assertion failure: true Assertion failure
message: Path must not end with a '.' or '..'
Here's my full script:
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.1 r1853635">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="host" elementType="Argument">
<stringProp name="Argument.name">host</stringProp>
<stringProp name="Argument.value">wsf.cdyne.com</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
<stringProp name="Argument.desc">Host of Webservice</stringProp>
</elementProp>
</collectionProp>
</Arguments>
<hashTree/>
<ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">${host}</stringProp>
<stringProp name="HTTPSampler.port"></stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path"></stringProp>
<stringProp name="HTTPSampler.concurrentPool">4</stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</ConfigTestElement>
<hashTree/>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Number of Users" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">2</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">5</stringProp>
<stringProp name="ThreadGroup.ramp_time">5</stringProp>
<longProp name="ThreadGroup.start_time">1375525852000</longProp>
<longProp name="ThreadGroup.end_time">1375525852000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
</ThreadGroup>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Rest Request" enabled="true">
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
<collectionProp name="Arguments.arguments">
<elementProp name="" elementType="HTTPArgument">
<boolProp name="HTTPArgument.always_encode">false</boolProp>
<stringProp name="Argument.value">{
"name": "new_user",
"job": "user_role"
}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</elementProp>
<stringProp name="HTTPSampler.domain">reqres.in</stringProp>
<stringProp name="HTTPSampler.port"></stringProp>
<stringProp name="HTTPSampler.protocol">https</stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path">\api\users</stringProp>
<stringProp name="HTTPSampler.method">POST</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree>
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
<collectionProp name="HeaderManager.headers">
<elementProp name="" elementType="Header">
<stringProp name="Header.name">Content-Type</stringProp>
<stringProp name="Header.value">application/JSON</stringProp>
</elementProp>
</collectionProp>
</HeaderManager>
<hashTree/>
<JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion on id" enabled="true">
<stringProp name="JSON_PATH">$.</stringProp>
<stringProp name="EXPECTED_VALUE">[0-9]+</stringProp>
<boolProp name="JSONVALIDATION">true</boolProp>
<boolProp name="EXPECT_NULL">false</boolProp>
<boolProp name="INVERT">false</boolProp>
<boolProp name="ISREGEX">true</boolProp>
</JSONPathAssertion>
<hashTree/>
<JSONPathAssertion guiclass="JSONPathAssertionGui" testclass="JSONPathAssertion" testname="JSON Assertion on createdAt" enabled="false">
<stringProp name="JSON_PATH">$.</stringProp>
<stringProp name="EXPECTED_VALUE">[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z</stringProp>
<boolProp name="JSONVALIDATION">true</boolProp>
<boolProp name="EXPECT_NULL">false</boolProp>
<boolProp name="INVERT">false</boolProp>
<boolProp name="ISREGEX">true</boolProp>
</JSONPathAssertion>
<hashTree/>
</hashTree>
</hashTree>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>false</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>false</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>true</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<hostname>true</hostname>
<threadCounts>true</threadCounts>
<sampleCount>true</sampleCount>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
<ResultCollector guiclass="StatGraphVisualizer" testclass="ResultCollector" testname="Aggregate Graph" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>false</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>false</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>true</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<hostname>true</hostname>
<threadCounts>true</threadCounts>
<sampleCount>true</sampleCount>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</jmeterTestPlan>
There are several problems with your script:
You need to use forward slashes in your request path like /api/users
More information: HTML Uniform Resource Locators
Correct mime type for JSON is application/json, for HTTP Headers the names are case-insensitive but the values MAY be case sensitive
More information: HTTP Headers Specification
You need to provide a Json Path expression which will match the value you're trying to assert, to wit $.id instead of $.
More information: API Testing With JMeter and the JSON Extractor
You forgot the key name as createdAt in JSON path expressions
$.createdAt
and id
$.id
You can't have JSON expression as $.
I have a weblogic server that I run into Inlellij Idea for audit work of an application.
I made web-app based on SpringBoot 2.x. I am using Intellij Idea 2019 and there I configure a deploy my webapplication on weblogic 12.x.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.weblogic</groupId>
<artifactId>weblogic</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>weblogic</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<version.apache.maven.plugins>3.8.1</version.apache.maven.plugins>
<version.mapstruct>1.3.0.Final</version.mapstruct>
<version.apache.common.lang3>3.9</version.apache.common.lang3>
<version.apache.commons.text>1.8</version.apache.commons.text>
<version.apache.commons.beanutils>1.9.4</version.apache.commons.beanutils>
<version.datasource.proxy>1.6</version.datasource.proxy>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<!--исключаем из компиляции встроенный Tomcat-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
<manifest>
<addDefaultImplementationEntries>false</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
</web-app>
src/main/webapp/WEB-INF/weblogic.xml
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
http://xmlns.oracle.com/weblogic/weblogic-web-app/1.9/weblogic-web-app.xsd">
<wls:weblogic-version>12.2.1.4.0</wls:weblogic-version>
<wls:context-root>/api</wls:context-root>
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>org.slf4j.*</wls:package-name>
<wls:package-name>org.springframework.*</wls:package-name>
<wls:package-name>javax.persistence.*</wls:package-name>
</wls:prefer-application-packages>
</wls:container-descriptor>
</wls:weblogic-web-app>
src/main/webapp/index.html
When I run weblogic by Intellij Idea I get index.html by url - http://localhost:7001/api
So, It works.
But I need more complex static content and I want to place it into an application classpath.
I made so…
src/main/resources/templates/pages/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello Weblogic!!!</title>
<link type="text/css" href="/static/css/style.css" rel="stylesheet"/>
</head>
<body>
<div class="st">
Hello Weblogic!!!
</div>
</body>
</html>
src/main/resources/static/css/style.css
.st{
color: red;
font-size: 35px;
}
And then…
src/main/java/com/weblogic/weblogic/mvc/config/MyMvcConfig.java
package com.weblogic.weblogic.mvc.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class MyMvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(
"/static/css/**",
"/templates/pages/**")
.addResourceLocations(
"classpath:/",
"classpath:/static/css/",
"classpath:/templates/pages/");
}
}
But I get … Error 500--Internal Server Error
java.lang.NullPointerException at
weblogic.servlet.internal.ServletResponseImpl.sendContentError(ServletResponseImpl.java:738)
at
weblogic.servlet.internal.ServletResponseImpl.sendError(ServletResponseImpl.java:796)
at
weblogic.servlet.internal.ServletResponseImpl.sendError(ServletResponseImpl.java:713)
at
org.springframework.boot.web.servlet.support.ErrorPageFilter$ErrorWrapperResponse.sendErrorIfNecessary(ErrorPageFilter.java:349)
at
org.springframework.boot.web.servlet.support.ErrorPageFilter$ErrorWrapperResponse.getWriter(ErrorPageFilter.java:363)
at
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$StaticView.render(ErrorMvcAutoConfiguration.java:227)
at
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1373)
at
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1118)
at
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1057)
at
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
who has any ideas how to fix this ?
You must use "template engine" – Thymeleaf. It doesn't work any other way (I would like to use pure (html + bootstrap), but it's not clear how to configure it).
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>web.spring.boot.jar</groupId>
<artifactId>web-spring-boot-jar</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>web-spring-boot-jar</name>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The structure of the static resources
src/main/resources/static/css/style.css
src/main/resources/templates/index.html
src/main/resources/templates/pages/login/login.html
*.properties
src/main/resources/application.properties
These settings don't work.
spring.mvc.servlet.path=/api
server.servlet.context-path=/api
server.servlet.contextPath=/api
These settings could not be applied.
Configuration files - *.xml
src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
</web-app>
If this file is missing, then the deployment occurs with errors ( in the development environment, you can see this in the console).
src/main/webapp/WEB-INF/weblogic.xml
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app
xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
https://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
http://xmlns.oracle.com/weblogic/weblogic-web-app
https://xmlns.oracle.com/weblogic/weblogic-web-app/1.9/weblogic-web-app.xsd">
<wls:context-root>rst</wls:context-root>
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>org.slf4j</wls:package-name>
</wls:prefer-application-packages>
</wls:container-descriptor>
</wls:weblogic-web-app>
<wls:context-root>rst</wls:context-root>
Here you need to be careful with choosing a name for the root context of the application (for example, if you chose a name for the context - /web, - > there will be an error, since this name is reserved somewhere).
Entry point
#SpringBootConfiguration
#EnableAutoConfiguration
#ComponentScan
public class WebSpringBootJarApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
public static void main(String[] args) {
SpringApplication.run(WebSpringBootJarApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(WebSpringBootJarApplication.class);
}
}
#SpringBootConfiguration
#EnableAutoConfiguration
#ComponentScan
You must have these 3 annotations, otherwise nothing will work.
The documentation says that #SpringBootConfiguration, replaces annotations:
#Configuration,
#EnableAutoConfiguration
#ComponentScan
#SpringBootConfiguration - indicates that this class provides an application
SpringBoot
It can also be used as an alternative to the #Configuration annotation, because the configuration can be found automatically.
#EnableAutoConfiguration - enables automatic configuration of Spring ApplicationContext by scanning class path components and registering beans that match different conditions.
That is, this annotation tries to guess and configure the beans that you may need.
Auto-configuration of classes, usually applied based on classpath
your application and on those beans that you have defined.
When using the #SpringBootConfiguration annotation, the context configuration is enabled automatically and the annotation is added, which will not have any additional effect…
But what I see here is quite different…
Without this annotation, nothing works... That is, we don't get the requested resources.
#ComponentScan - Directive configures component scanning for the classes marked with #Configuration.
Provides support in parallel using the configuration described in XML format in the element:
... But I didn't even specify the packages to scan....
And without specifying this annotation, I also can't access resources... ???
Why is that? I don't know…
What do I need to implement WebApplicationInitializer , - I don't know…
https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-weblogic
Contollers
src/main/java/web/spring/boot/jar/webspringbootjar/controller/index/IndexController.java
IndexController
#Controller
public class IndexController {
#RequestMapping(value="/", method= RequestMethod.GET)
public String index() {
return "index";
}
}
src/main/java/web/spring/boot/jar/webspringbootjar/controller/login/LoginController.java
LoginController
#Controller
public class LoginController {
#GetMapping(value = {"/log"})
public ModelAndView showUsersPage() {
return new ModelAndView("pages/login/login.html");
}
}
The creation of an artifact (Intellij Idea)
- Project Structure/Artifacts
- Alt + Insert
- Web Application: Exploded -> From module
There is the path to the directory with your project will be specified.
You can also configure
- Project Structure/Facets
And then…
Run\Edit Configuration
Here you configure - weblogic…
URL to the app(in my case)
http://localhost:7001/rst/
The same access will be available when you migrate .*war from the development environment and deploy it to an external weblogic server.
If you start an external server, you get an error
This means that you need to run maven and it must will make a *.war-file…
Also It doesn't work...
#Configuration
#EnableWebMvc
#ComponentScan(basePackageClasses = { ServletContextConfig.class })
public class ServletContextConfig implements WebMvcConfigurer {
#Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
webServerFactoryCustomizer() {
return factory -> factory.setContextPath("/rootweb");
}
}
I suppose we only can use xml-configuration for servlet-context here.
If someone can add something, please specify what is wrong....
Can who has what ideas, about my issues which arose during this messages ....
i just started with Java and i'm trying to configure the logging via logback.
The logging does not work, instead i get an an error in the console:
-ERROR in ch.qos.logback.core.joran.spi.Interpreter#9:29 - no applicable action for [root], current ElementPath is [[configuration][appender][root]]
so no appender is found:
-WARN in Logger[Test01] - No appenders present in context [default] for logger [Test01].
My code is very simple:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MainClass {
public static void main(String[] args) {
Logger log = LoggerFactory.getLogger(MainClass.class);
log.debug("test"); }
}
Complete console output when running looks like this:
08:41:43,047 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
08:41:43,047 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
08:41:43,047 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/C:/Users/klein/IdeaProjects/Maven01ArtifactId/target/classes/logback.xml]
08:41:43,196 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
08:41:43,199 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
08:41:43,209 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
08:41:43,235 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter#9:29 - no applicable action for [root], current ElementPath is [[configuration][appender][root]]
08:41:43,235 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter#10:41 - no applicable action for [appender-ref], current ElementPath is [[configuration][appender][root][appender-ref]]
08:41:43,235 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
08:41:43,235 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator#78e94dcf - Registering current configuration as safe fallback point
08:41:43,235 |-WARN in Logger[Test01] - No appenders present in context [default] for logger [Test01].
I'm using IntelliJ Community 2018.3 and started a project with Maven. logback.xml and pom.xml are below.
Any ideas what is wrong here?
logback.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</appender>
</configuration>
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<slf4jVersion>1.7.25</slf4jVersion>
<logbackVersion>1.2.3</logbackVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4jVersion}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logbackVersion}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logbackVersion}</version>
</dependency>
</dependencies>
</project>
In logback.xml, you put the <root> section inside the <appender> section.
Your logback.xml should be:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
I am using log4j2 with this 2 dependencies:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.6.2</version>
</dependency>
When I try to log for example an error with a throwable like:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.testng.annotations.Test;
public class Test {
private static final Logger logger = LogManager.getLogger(Test.class);
#Test
public void testSendMessage() throws Exception {
Exception exception = new Exception("some exception");
logger.error("error with exception", exception);
}
}
using patternlayout:
<Configuration>
<properties>
<property name="filters">org.testng,org.apache.maven,sun.reflect,java.lang.reflect</property>
</properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT" direct="true">
<PatternLayout pattern="%maxLen{%d{DEFAULT} [%p] %c{-3}:%L - %enc{%m} %xEx{filters(${filters})}%n}{200}"/>
</Console>
</Appenders>
<Loggers>
<logger name="my.test.class.path" level="trace" additivity="false">
<AppenderRef ref="ConsoleAppender" />
</logger>
</Loggers>
</Configuration>
Then the filtered packages won't disappear from the stacktrace, I can't even manipulate the stacktrace in any way like maximizing the lines:
%xEx{5}
Highlightning also don't work in eclipse nor in Kibana(ELK environment).
Can anybody help?
Could it be that the %xEx PatternLayout converter doesn't support property substitution in its options?
What if you put the packages you want to filter directly in the filters list?
It may be worth raising a Jira ticket on the Log4j 2 issue tracker for this.
try to remove the ending{200}. i think there is an issue using more sub parameters.
here is a snippet which works. please note if you add additional things like separator(|) it will stop working [tested in version 2.8.1 and 2.9.1]
<Properties>
<Property name="exfilters">org.jboss,java.lang.reflect,sun.reflect</Property>
<Property name="log-pattern">%d %-5p %m%n%xEx{filters(${exfilters})}/Property>
</Properties>
...
<PatternLayout pattern="${sys:log-pattern}"/>
Works for me on Log4j2 v 2.17 (and also for rThrowable):
<Properties>
<Property name="PACKAGE_FILTER">org.jboss,java.lang.reflect,sun.reflect</Property>
<Property name="LOG_PATTERN">%xThrowable{filters(${PACKAGE_FILTER})}</Property>
</Properties>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
</Appenders>