생각하는 족족 고.따.구 냐..

Posted
Filed under About Knowledge/Programs_Java
...
apply plugin: 'java'
apply plugin: 'maven-publish'
...

...
jar {
    into("META-INF/maven/$project.group/$project.name") {
        from { generatePomFileForMavenJavaPublication }
        rename ".*", "pom.xml"
    }
}
...



group 'com.my-group'
version '1.0'

publishing {
    publications {
        mavenJava(MavenPublication) {
            artifactId = rootProject.name
            from components.java
            versionMapping {
                usage('java-api') {
                    fromResolutionOf('runtimeClasspath')
                }
                usage('java-runtime') {
                    fromResolutionResult()
                }
            }
        }
    }

    repositories {
        maven {
            credentials {
                username 'username'
                password 'password'
            }
            url 'http://localhost:8081/repository/my/'
        }
    }
}

============================================================================
gradle clean build -x test publish

============================================================================

https://docs.gradle.org/current/userguide/viewing_debugging_dependencies.html
2021/03/23 10:57 2021/03/23 10:57
Posted
Filed under About Knowledge/Programs_Java
spring boot bootRun argument

$ ./gradlew bootRun --args='--spring.profiles.active=dev'
2021/03/08 11:14 2021/03/08 11:14
Posted
Filed under About Knowledge/Programs_Java

publish with pom-dependencies

to set plugins

...
apply plugin: 'java'
apply plugin: 'maven-publish'
...

to include pom.xml

...
jar {
    //from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
    into("META-INF/maven/$project.group/$project.name") {
        from { generatePomFileForMavenJavaPublication }
        rename ".*", "pom.xml"
    }
}
...

to set publication

group 'com.my-group'
version '1.0'

publishing {
    publications {
        mavenJava(MavenPublication) {
            artifactId = rootProject.name
            from components.java
            versionMapping {
                usage('java-api') {
                    fromResolutionOf('runtimeClasspath')
                }
                usage('java-runtime') {
                    fromResolutionResult()
                }
            }
        }
    }

    repositories {
        maven {
            credentials {
                username 'username'
                password 'password'
            }
            url 'http://localhost:8081/repository/my/'
        }
    }
}

to build

command> gradle clean build -x test publish  # native gradle
# or
command> ./gradlew clean build -x test publish # gradle wrapper 

 

2021/02/22 22:32 2021/02/22 22:32
Posted
Filed under About Knowledge/Programs_Java
URL url = ${TARGET_CLASS}.class.getProtectionDomain().getCodeSource().getLocation();
2020/11/12 13:42 2020/11/12 13:42
Posted
Filed under About Knowledge/Programs_Java
java에서 x509 인증서(certificate)를 읽어온다.

            CertificateFactory fact = CertificateFactory.getInstance("X.509");
            FileInputStream is = new FileInputStream("./lib/license/felice.pem");
            result = (X509Certificate) fact.generateCertificate(is);
          
            // 인증서를 검증한다.
            result.verify( ${OTHER_CERT}.getPublicKey()
2020/11/12 13:41 2020/11/12 13:41
Posted
Filed under About Knowledge/Programs_Java
signed jar파일에서 인증서(certificate)를 읽어온다.

X509Certificate result = null;
        try {
            //InputStream in = X509Certificate.class.getResourceAsStream("classpath:META-INF/xxxxx.RSA");
            InputStream in = new ClassPathResource("META-INF/xxxxxx.RSA").getInputStream();
            byte[] buffer = in.readAllBytes();
            in.close();
            //Corresponding class of signed_data is CMSSignedData
            CMSSignedData signature = new CMSSignedData(buffer);
            Store cs = signature.getCertificates();
            SignerInformationStore signers = signature.getSignerInfos();
            Collection c = signers.getSigners();
            Iterator it = c.iterator();
            //the following array will contain the content of xml document
            //byte[] data = null;
            while (it.hasNext()) {
                SignerInformation signer = (SignerInformation) it.next();
                Collection certCollection = cs.getMatches(signer.getSID());
                Iterator certIt = certCollection.iterator();
                X509CertificateHolder cert = (X509CertificateHolder) certIt.next();

                CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
                InputStream in2 = new ByteArrayInputStream(cert.getEncoded());
                result = (X509Certificate) certFactory.generateCertificate(in2);

                if( null != result)
                    break;
                //CMSProcessable sc = signature.getSignedContent();
                //data = (byte[]) sc.getContent();
            }
        } catch (CertificateException | CMSException | IOException e) {
            log.error("",e);
        }
        return result;
2020/11/12 13:38 2020/11/12 13:38
Posted
Filed under About Knowledge/Programs_Java
원격에서 JMX 정보를 제공하려 할 때 JMX정보를 제공할 포트를 개방해야 합니다. 
점검해야 할 부분은 아래와 같습니다. 

1. SELinux

[조회]
semanger port -l | grep ${port-numer}
 
[예외추가]
semanger port -a -t http_port_t -p tcp ${port-number}

2. FirewallD

[조회]

firewall-cmd --list-all | grep ${port-numer}
 
[예외추가]
firewall-cmd --zone=public --add-port=${port-numer}/tcp --permanent && firewall-cmd --reload

3. Java Application 설정

호스트 외부에서 JMX서비스에 접속해야 할 경우 붉은색 내용을 java 명령줄에 꼭 명시해야 한다.

-Djava.rmi.server.hostname=${hostip}
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.rmi.port=${port}
-Dcom.sun.management.jmxremote.port=${port} 
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
2020/03/30 16:30 2020/03/30 16:30
Posted
Filed under About Knowledge/Programs_Java
QueryDSL을 적용할 때 보통은 Lombok을 함께 사용하는데 둘다 Annotation Processor 이라서 그런저 항상 시간을 들여서 설정을 해야만 했습니다. Gradle 5.0에서 QueryDSL을 적용하는 방법이 또 달라졌습니다. 


lombok, queryDSL 둘 다 모두 변경 적용 완료







Buildscript { ext { springBootVersion = "$SPRING_BOOT_VERSION" } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } plugins { id "org.springframework.boot" version "2.1.0.RELEASE" id 'io.spring.dependency-management' version '1.0.6.RELEASE' } ... ...

dependencies {
def querydslVersion = "4.2.1"
compile ("com.querydsl:querydsl-core:$querydslVersion")
compile ("com.querydsl:querydsl-jpa:$querydslVersion")
compileOnly 'org.projectlombok:lombok:1.18.4'
annotationProcessor(
"com.querydsl:querydsl-apt:${querydslVersion}:jpa",
"org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final",
"javax.annotation:javax.annotation-api:1.3.2",
"org.projectlombok:lombok"
)
...
}

sourceSets {
main.java.srcDirs += [ "src-gen/main/java" ]
}



tasks.withType(JavaCompile) {
options.annotationProcessorGeneratedSourcesDirectory = file( "src-gen/main/java" )
}

clean.doLast {
file( "src-gen" ).deleteDir()
}
2018/12/24 16:28 2018/12/24 16:28
Posted
Filed under About Knowledge/Programs_Java
403 Forbidden에 대한 사용자 정의 메시지 정의가 가능합니다.

1. 로그인에 실패하는 경우의 메시지 정의

HttpSecurity에 AccessDeniedHandler를 구현 한다.

스프링부트의 경우 .exceptionHandling().accessDeniedHandler() 에 새롭게 정의한 내용을 활용한다.


2. 로그인 후 접근해야 하는 리소스에 접근할 때 메지시 정의

HttpSecurity에 AuthenticationEntryPoint 구현 한다.

스프링부트의 경우

.exceptionHandling().authenticationEntryPoint()에 새롭게 정의한 내용을 활용한다.

2018/12/06 15:13 2018/12/06 15:13
Posted
Filed under About Knowledge/Programs_Java
Proxy 서버에 뒤에 스프링부트를 운영할 때 난감한 상황이 발생합니다. 최초 사용자가 접속하는 환경이 HTTPS 일 경우 헤더에 해당 정보를 담고 있어야 하는데 스프링부트에 설정하지 않으면 X-Forward-* 를 사용하지 않게 됩니다. 스프링 시큐리티의 login / logout 의 redirect ( http 30x )  또는 controller에서 30x 명령을 내리면 프로토콜정보와 포트정보를 사용하지 않고 http://xxxxx:80/xxxx 와 같이 일반적인 URL으로 redirect 요청을 합니다.

[상태설명]
HTTPS[브라우져]  ==> HTTPS[AWS :LB]  ==> HTTP[NginX] ==> Spring Boot
                                                                   |     X-Forward-*    |        ??

이런경우 스프링부트의 [Running Behind a Front-end Proxy Server] 를 참고하여 설정하면 헤더정보를 사용하게 됩니다.




78.12 Running Behind a Front-end Proxy Server

Your application might need to send 302 redirects or render content with absolute links back to itself. When running behind a proxy, the caller wants a link to the proxy and not to the physical address of the machine hosting your app. Typically, such situations are handled through a contract with the proxy, which adds headers to tell the back end how to construct links to itself.

If the proxy adds conventional X-Forwarded-For and X-Forwarded-Proto headers (most proxy servers do so), the absolute links should be rendered correctly, provided server.use-forward-headers is set to true in your application.properties.

[Note]

If your application runs in Cloud Foundry or Heroku, the server.use-forward-headers property defaults to true. In all other instances, it defaults to false.



[Nginx 참고자료]
 proxy_set_header        Host               $host;
        proxy_set_header        X-Real-IP          $remote_addr;
        proxy_set_header        X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Host   $host:443;
        proxy_set_header        X-Forwarded-Server $host;
        proxy_set_header        X-Forwarded-Port   443;
        proxy_set_header        X-Forwarded-Proto  https;
        proxy_set_header        X-HTTPS-Protocol $ssl_protocol;


        proxy_redirect     off;
        proxy_pass http://localhost:8080;
2018/12/04 16:21 2018/12/04 16:21