SpringBoot security on heroku-deployed project even without using its dependency - java

I am using java 1.8 for Gradle SpringBoot restAPI.
I haven't used spring-boot-starter-security and API works accordingly but after deploying the same code on heroku the API asks for the signup.
I tried disabling it via following way,
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
#SpringBootApplication (exclude = { SecurityAutoConfiguration.class })
public class LawCaseApplication {
public static void main(String[] args) {
SpringApplication.run(LawCaseApplication.class, args);
}
}
But still after re-deploying the screen appeared.
Then I tried giving it my own user name and password by writing the following in the application.properties as I wasn't getting any randomly generated password in the logs too,
spring.security.user.name="user"
spring.security.user.password="user"
And I am still getting this screen.
However, the dependencies I used are,
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.projectlombok:lombok:1.18.20'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation "org.jsoup:jsoup:1.13.1"
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
}
I repeat that there is no security when run on local host but on the heroku deployed version.

Actually, there is a most important step before you redeploy each time.
build the jar/war file so that it gets updated by the recent changes you made...
The steps you used are working on localhost proving them to be correct...
Try building the jar/war file then check if it works or not...

Related

Junit Runner cannot be resolved type

I am using Springboot 2.1.3.RELEASE version.
Recently I have written DAO, Service, Component and Integration layer test cases using Junit 5 and Mockito framework all these test cases are working fine.
If I want to run all these test cases then individually I have to run each test classes.
To overcome this problem I have implemented Spring Suite using Junit 5.
Recently I made changes in build.gradle file or added junit-platform-runner dependency.
After adding this dependency my Suite class throwing below exception.
The type org.junit.runner.Runner cannot be resolved. It is indirectly referenced from required .class files
Here is my Spring Suite class
SpringSuitTest.java
import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.runner.RunWith;
#RunWith(JUnitPlatform.class)
#SelectClasses({someclasseshere.class})
public class SpringSuitTest {
}
My dependencies
// Runtime dependencies
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.3.2")
testRuntime("org.junit.platform:junit-platform-runner:1.5.2")
testCompile("org.junit.jupiter:junit-jupiter-api:5.3.2")
testCompile("org.mockito:mockito-core:2.27.0")
testCompile("org.mockito:mockito-junit-jupiter:2.27.0")
I googled a lot but none of the solutions worked for me.
Recently I have added Junit runner dependency, I am considering may be invalid version I have added
testRuntime("org.junit.platform:junit-platform-runner:1.5.2")
Any idea why I am getting such exception.
Thank you
After adding below 2 dependencies resolved the issue.
testImplementation group: 'org.junit.vintage', name: 'junit-vintage-engine', version: '5.3.2'
testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: '1.2.0'

Running projects without Eclipse

In my company, plenty of teams (including mine) don't know how to run Spring projects without Eclipse to a point that this is becoming a problem. I've extensively searched around for stuff, but stumbling upon places just saying "press Run" for the project to be ran. Many times that doesn't help us understand the dependencies of legacy projects, and of course, legacy projects have no documentation laying around, or the folks who designed it (or the folks who designed it don't know how to run that without the IDE).
Here is the architecture of the latest one:
Spring, Gradle, Java.
I've tried running this project with ./gradlew run, but the task run doesn't seem supposed to run the application, the task doesn't even exist and the build.gradle file doesn't have it.
This is the build.gradle file:
plugins {
id 'org.springframework.boot' version '2.1.6.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.name'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-actuator'
compileOnly 'org.projectlombok:lombok:1.18.4'
}
This is the Java file that is suppose to be the runner:
package com.company.authApplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class AuthApplication {
public static void main(String[] args) {
SpringApplication.run(AuthApplication.class, args);
}
}
Even if the build.gradle file mentiones mavenCentral(), this is not build for Maven at all, that's just the default structure for it.
Any help is appreciated.

Create stand-alone jar for appium test scripts

I would like to create a stand-alone (thin jar) jar without dependencies for Appium test scripts.
I have a Runner class
import org.junit.runner.JUnitCore;
import java.net.MalformedURLException;
public class Runner {
public static void main(String[] args) throws MalformedURLException {
try{
JUnitCore.runClasses(Calculator.class);
}finally {
}
}
}
and
I have a Calculator test class
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
//import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class Calculator {
// WebDriver driver;
public AndroidDriver<MobileElement> driver;
#Before
public void setUp() throws MalformedURLException{
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("udid", "ZH33L2Z6KL"); //Give Device ID of your mobile phone
caps.setCapability("platformName", "Android");
caps.setCapability("platformVersion", "6.0.1");
caps.setCapability("automationName", "uiautomator2");
caps.setCapability("skipUnlock","true");
caps.setCapability("appPackage", "com.google.android.calculator");
caps.setCapability("appActivity", "com.android.calculator2.Calculator");
caps.setCapability("noReset","true");
driver = new AndroidDriver<MobileElement>(new URL("http://127.0.0.1:4723/wd/hub"), caps);
}
#Test
public void testCal() throws Exception {
//locate the Text on the calculator by using By.name()
WebElement two=driver.findElement(By.id("digit_2"));
two.click();
WebElement plus=driver.findElement(By.id("op_add"));
plus.click();
WebElement four=driver.findElement(By.id("digit_4"));
four.click();
WebElement equalTo=driver.findElement(By.id("eq"));
equalTo.click();
//locate the edit box of the calculator by using By.tagName()
WebElement results=driver.findElement(By.id("result_final"));
//Check the calculated value on the edit box
assert results.getText().equals("6"):"Actual value is : "+results.getText()+" did not match with expected value: 6";
}
#After
public void teardown(){
//close the app
driver.quit();
}
}
I have gone through one article about ThinJar and hollowJar.
https://dzone.com/articles/the-skinny-on-fat-thin-hollow-and-uber
Questions
How to add Gradle task (in intellij)to build thin jar as per the article?
How to add Gradle task to build 'Hollow' jar as per the article?
If I build a 'fat' jar my jar size is 18mb. How to build skinny or thin jar with less size, and keep dependencies separately?
How to run the created 'skinny' or 'thin' jar in different PC?
The terminology used in your link is a bit strange. With gradle, the "skinny" jar is always built. It is the default artifact, check the build/libs folder. If you apply the application plugin, there is a distribution zip built as well under build/distribution which is pretty much the fat jar (it is a zip of all relevant jars). But by definition you cannot build a fat jar into a smaller size, and you cannot simply run the "skinny" or "thin" jar on the target host.
Running your application always requires just three things:
The compiled artifact of your code - a bunch of .class files corresponding to, and only to, the code you write, usually packaged in a jar format. This is the skinny jar in that terminology. This is also the commonest artifact produced out of a build (any build system, maven, gradle etc) if you don't do anything special.
The library dependencies - all 3rd party jars
The runtime - this usually refers to Java itself.
All of the above need to present on the host where you are about to run your application. Now, what gets a bit complicated is the stuff you actually need to ship to that host (this is called deployment):
Obviously you will need No. 1 shipped to the host
Usually you would expect/assume No. 3 is pre-installed on the host
What about No.2 the 3rd party dependencies? The answer is it depends.
If (some of) these dependencies can be pre-installed on the target
host, you don't need to ship them. In this case usually people would
just call these dependencies as also the "runtime". For example,
Maven is a runtime, so is Gradle. These are, in themselves, Java
libraries to you when you are writing a Maven/Gradle plugin. You
would normally expect people using your code to have maven/gradle
installed already. They run your code through maven/gradle, and
maven/gradle will provide the dependencies your code requires
when running it. This is why in maven this kind of dependencies is
called "Provided". Maven has a dedicated dependency scope for it.
If any of your dependencies is not provided on the target host, you
need to ship it, period.
In Gradle, if you apply the application plugin (which will automatically apply the distribution plugin), you can have both your artifact and your dependencies (exclude java runtime) in a single zip - this is called a distribution.
plugins {
id 'java'
id 'application'
}
Once you build, you will find a zip file under build/distributions. There are two folders if you unzip the file: bin and lib. Within the lib folder sits your jar, and all your dependencies jars. This technically is not a fat jar, because it is not a single jar. But jar-or-not is just a format. Eventually what you are after is just to get your code and dependencies across to the target host. The distribution zip does not mess around with jar because jar-merging is not as simple as folder merges. Instead distribution zip expects you to unzip on the target host and invoke the script under bin folder to start the application.
The following article answers these questions:
Java Build Automation Part 2: Create executable jar using Gradle
https://vocon-it.com/2016/11/15/how-to-build-a-lean-jar-file-with-gradle/
The corresponding sample code is available under:
https://github.com/oveits/gradle-tutorial-build-executable-jar/releases/tag/v1.0
The final build.gradle file is given below:
group 'io.cloudgrey.appiumpro'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
maven { url "https://jitpack.io" }
mavenCentral()
maven { url "https://repo.maven.apache.org/maven2" }
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'log4j', name: 'log4j', version:'1.2.17'
testCompile group: 'io.appium', name: 'java-client', version: '7.3.0'
testCompile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.13.0'
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3'
testCompile group: 'com.eclipsesource.minimal-json', name: 'minimal-json', version: '0.9.5'
testCompile group: 'org.java-websocket', name: 'Java-WebSocket', version: '1.3.9'
testCompile group: 'org.zeroturnaround', name: 'zt-exec', version: '1.10'
testCompile group: 'me.xdrop', name: 'fuzzywuzzy', version: '1.2.0'
testCompile group: 'io.appium', name: 'mitmproxy-java', version: '1.6.1'
testCompile group: 'com.applitools', name: 'eyes-appium-java4', version: '4.2.1'
testCompile group: 'com.github.testdotai', name: 'classifier-client-java', version: '1.0.0'
testCompile group: 'com.google.guava', name: 'guava', version: '28.1-jre'
}
test {
outputs.upToDateWhen {false}
useJUnit()
testLogging {
exceptionFormat = 'full'
showStandardStreams = true
}
maxParallelForks = 3
forkEvery = 1
}
task copyJarsToLib (type: Copy) {
def toDir = "build/libs/dependency-jars"
// create directories, if not already done:
file(toDir).mkdirs()
// copy jars to lib folder:
from configurations.compile
into toDir
}
task marshallClasspathDeps(type: Copy) {
from sourceSets.test.runtimeClasspath
// if you need this from the dependencies in the build.gradle then it should be :
// from sourceSets.main.runtimeClasspath
include '**/*.class'
include '**/*.jar'
exclude { FileTreeElement details ->
details.file.name.contains('Edition') || details.file.name.contains('kotlin')
}
into 'build/libs/dependency-jars'
}
build.dependsOn(marshallClasspathDeps)
task buildJar(dependsOn:classes,type: Jar) {
// exclude log properties (recommended)
exclude ("log4j.properties")
// make jar executable: see http://stackoverflow.com/questions/21721119/creating-runnable-jar-with-gradle
manifest {
attributes (
'Main-Class': 'com.example.appium.Runner',
// add classpath to Manifest; see http://stackoverflow.com/questions/30087427/add-classpath-in-manifest-file-of-jar-in-gradle
"Class-Path": '. dependency-jars/' + sourceSets.test.runtimeClasspath.collect { it.getName() }.join(' dependency-jars/')
)
}
baseName = "AppiumTests"
from sourceSets.test.output
include 'com/example/appium/*.class'
}
// always call copyJarsToLib when building jars:
jar.dependsOn copyJarsToLib
build.dependsOn(buildJar)
// END AUTOMATICALLY INSERTED
The test cases can be executed using:
java -jar -Dlog4j.configuration=file:%cd%\log4j.properties build\libs\AppiumTests.jar

Cannot resolve symbol hbase

I am new to HBase, I copied a sample java code from the internet, but I meet an error "Cannot resolve symbol hbase" when building this sample. I use Gradle to build this sample project and Intellij as IDE. The HBase server is a remoter server and I try to write a put sample at my windows laptop to test the HBase, but I am not familiar with HBase and Gradle, could someone suggest what I have missed? Here is my code
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
public class PutHbaseClient {
public static void main(String[] args) throws IOException {
Configuration conf = HBaseConfiguration.create();
Connection connection = ConnectionFactory.createConnection(conf);
Table table = connection.getTable(TableName.valueOf("test"));
try {
/*
* Put operations for a single row. To perform a
* Put, instantiate a Put object with the row to insert to and for
* each column to be inserted, execute addcolumn.
*/
Put put1 = new Put(Bytes.toBytes("row1"));
Put put2 = new Put(Bytes.toBytes("row2"));
Put put3 = new Put(Bytes.toBytes("row3"));
put1.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("qual1"),
Bytes.toBytes("ValueOneForPut1Qual1"));
put2.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("qual1"),
Bytes.toBytes("ValueOneForPut2Qual1"));
put3.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("qual1"),
Bytes.toBytes("ValueOneForPut2Qual1"));
put1.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("qual2"),
Bytes.toBytes("ValueOneForPut1Qual2"));
put2.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("qual2"),
Bytes.toBytes("ValueOneForPut2Qual2"));
put3.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("qual2"),
Bytes.toBytes("ValueOneForPut3Qual3"));
table.put(put1);
table.put(put2);
table.put(put3);
} finally {
table.close();
connection.close();
}
}
}
Here is my build.gradle
plugins {
id 'java'
}
group 'gid'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.apache.hadoop', name: 'hadoop-common', version:'2.7.3'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
According to a JAR finder site, the org.apache.hadoop.hbase.TableName class is in the hbase-common JAR file.
That means that the dependency that you have in your build.gradle file should work. However, I don't think that the version number is correct. The most recent 2.x version in Maven Central is 2.2.2. (And 3.0.0-SNAPSHOT is not there ... naturally ... because Maven Central doesn't host SNAPSHOT artifacts!)
However, I recommend that you do what the HBase Documentation says (here):
"For Java applications using Maven, including the hbase-shaded-client module is the recommended dependency when connecting to a cluster."
The corresponding Gradle dependency is:
// https://mvnrepository.com/artifact/org.apache.hbase/hbase-shaded-client
compile group: 'org.apache.hbase', name: 'hbase-shaded-client', version: '2.2.2'
I am not familiar with Gradle, but I expect that there was another error message saying that it couldn't resolve the dependency for hbase-common version 2.7.3.
I think you need something like this in your gradle dependency:
compile 'org.apache.hbase:hbase:3.0.0-SNAPSHOT'

Spring development on Docker

I'm quite new to Java and Spring. I'm looking for a containerized solution that watches the src folder, rebuilds the project and takes advantage of Spring devtools hotswap to reload the changed classes.
I searched, but I just keep finding about production-ready containers, with separated steps for build and run. I tried to use 2 different containers, one with Gradle that keeps building (gradle build --continuous) and one that executes the built result:
version: '3.7'
services:
builder:
image: gradle:jdk11
working_dir: /home/gradle/project
volumes:
- ./:/home/gradle/project
command: gradle build --continuous
api:
image: openjdk:11-slim
volumes:
- ./build/classes:/app
command: java -classpath /app/java/main com.example.Application
It fails because Java doesn't find the dependencies (Spring, devtools, h2, etc.) inside the api container, and I don't know how to ask Gradle to include the external jars in the build folder. I want to do something like this, except that the example is outdated.
Still, I keep thinking that there might be a more elegant, simpler solution. It doesn't have to be with Gradle, it can be Maven if it works! :)
I know that many IDE have support for automatic builds and devtools, I just want to achieve it on Docker. This way, I would have a development workflow that is on repository, instead of on IDE's configuration, and virtually compatible with any dev environment. Is it a bad idea?
At last, I've found a solution that works quite well, with just one caveat.
This is of course a development environment, meant to quickly change files, automatically build and refresh the Spring application. It is not for production.
The build process is delegated to a Gradle container that watches for changes. Since Gradle has Incremental Compilation, it should scale well even for big projects.
The application itself is executed on a openjdk:11-slim. Since it runs the .class files, SpringBoot gets that it's dev-env and activates its devtools.
Here's my docker-compose.yml:
version: '3.7'
services:
builder:
image: gradle:jdk11
working_dir: /home/gradle/project
volumes:
- ./build:/home/gradle/project/build
- ./src:/home/gradle/project/src
- ./build.gradle:/home/gradle/project/build.gradle
command: gradle build --continuous -x test -x testClasses
api:
image: openjdk:13-alpine
volumes:
- ./build:/app
depends_on:
- builder
command: java -cp "/app/classes/java/main:/app/dependencies/*:/app/resources/main" com.example.Application
And here's my build.gradle:
plugins {
id 'org.springframework.boot' version '2.2.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.1.0-SNAPSHOT'
sourceCompatibility = '11'
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
task copyLibs(type: Copy) {
from configurations.runtimeClasspath
into "${buildDir}/dependencies"
}
build.dependsOn(copyLibs)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'com.h2database:h2'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
All in all, it takes 5s for the whole thing to rebuild and hot-swap a change in the source code. Not webpack-like quick, but still acceptable. And the biggest advantage of having it this way is that it resides on code, and everyone can get it working, regardless of their workstation.
The caveat? On the first run, the build folder is empty and the api container fails to start. You have to wait for builder to complete its work, and then restart api.
I'm still hoping for a better solution, and I encourage you to post everything that works smoother than this.

Categories

Resources