oc4j thread问题

本文探讨了在使用OC4J的DataSource时可能遇到的线程问题,并提供了解决方案,包括通过命令行参数及代码配置允许使用用户线程的方法。

在使用oc4j的datasource时可能引发线程问题.

 

解决:

 

使用 java -jar oc4j.jar -userThreads  从而在使用oc4j时允许使用 用户线程 但线程可能是不安全的.

 

如果还有问题, 请在代码中设置: System.setProperty("oc4j.userThreads", "true");

 

 

package com.example.assignment.login; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.security.KeyStore; import java.security.SecureRandom; import java.security.cert.CertificateFactory; import java.util.concurrent.TimeUnit; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; import okhttp3.OkHttpClient; public class HttpHolder { private static final String TAG = "HttpHolder"; private static final String CLOUD_CERT = "-----BEGIN CERTIFICATE-----\n" + "MIIDBzCCAe+gAwIBAgIQT5x0ma7QnINHCQvhnmzR9zANBgkqhkiG9w0BAQsFADAV\n" + "MRMwEQYDVQQDEwp0cC1saW5rLUNBMCAXDTE4MDExOTA4Mjc1MloYDzIwNjgwMTE5\n" + "MDgzNzUyWjAVMRMwEQYDVQQDEwp0cC1saW5rLUNBMIIBIjANBgkqhkiG9w0BAQEF\n" + "AAOCAQ8AMIIBCgKCAQEAuGG8n5zEUN1j5wuvUz4pAIMurhKHbpfUUu+b2acFHKS6\n" + "iU9hNJWvDyhXcihY5Wz6aq9m4D5SZcgW3k31YoNNtrztDjdg2qw7AaX85S99/G0B\n" + "VbIXktrhs34OW19WA/haDwut3dFhLem+gCRRKUXcmuqchZc84dY7JFVfhPcJci4m\n" + "sRjLCFNO0ho9OX+MZwfO4BLaeAqKVoAor6rf4BXVtO0xjYHDKO0fb3AWLLJ4EjGe\n" + "q6YieqPiYlPFEqRm5PrvBXTm0IuQogygyVpK4LHr/K207ZLyV33DxLLbsUgSEJVn\n" + "pZUv/WUujXjlIDgxIvyZZCYiXO3dle2/MEvpmZk6JQIDAQABo1EwTzALBgNVHQ8E\n" + "BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUxu2iBRTsef5iNnsADVhM\n" + "JDQWi6kwEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQELBQADggEBAB52Majd\n" + "+wo3cb5BsTo63z2Psbbyl4ACMUaw68NxUMy61Oihx3mcLzLJqiIZcKePiHskLqLJ\n" + "F7QfT9TqjvizMjFJVgsLuVubUBXKBzqyN+3KKlQci0PO3mH+ObhyaE7BzV+qrS3P\n" + "dVTgsCWFv8DkgLTRudSWxL7VwVoedc7lRz5EroGgJ33nRGCR0ngcW919tLTARDQO\n" + "pULmzulcdWeZgG+0PLX0xjJQIjFEvbOxR1Z+gxMupBz0rWFokmWYrcga8eWiWzjQ\n" + "Ia3/ASBVJ69srV77trWlfLumkChbXk9i64NXBKnce0Jmll0Y9OC1nMPqrbQKnzcn\n" + "dSAA4fejD/qMQn0=\n" + "-----END c-----"; /** * 通用OkHttpClient单例 */ private static volatile OkHttpClient sInstance; /** * 连接超时时间 */ private static final int DEFAULT_CONN_TIMEOUT = 10; /** * 读写超时时间 */ private static final int DEFAULT_SOCKET_TIMEOUT = 30; /** * 返回通用的OkHttpClient * * @return */ public static OkHttpClient getOkHttpClient() { if (sInstance == null) { synchronized (HttpHolder.class) { if (sInstance == null) { generateOkHttpClient(); } } } return sInstance; } /** * 创建OKHttpClient,允许外部调用,因为该方法涉及到设置证书,所以在Application创建时调用一次,设置证书 */ private static void generateOkHttpClient() { if (sInstance != null) return; // TPLog.i(TAG, "start"); OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(DEFAULT_CONN_TIMEOUT, TimeUnit.SECONDS) .readTimeout(DEFAULT_SOCKET_TIMEOUT, TimeUnit.SECONDS) .writeTimeout(DEFAULT_SOCKET_TIMEOUT, TimeUnit.SECONDS); // //设置Log // if (TPLog.DEBUG) { // builder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)); // } //设置自签证书 SSLSocketFactory sslSocketFactory = getSocketFactory(new ByteArrayInputStream(CLOUD_CERT.getBytes())); if (sslSocketFactory != null) { builder.sslSocketFactory(sslSocketFactory) .hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return hostname.contains("https://n-wap-beta.tplinkcloud.com"); } }); } sInstance = builder.build(); // TPLog.i(TAG, "end"); } private static SSLSocketFactory getSocketFactory(InputStream... certificates) { try { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); try { int index = 0; for (InputStream certificate : certificates) { String certificateAlias = Integer.toString(index++); keyStore.setCertificateEntry(certificateAlias, certificateFactory .generateCertificate(certificate)); if (certificate != null) certificate.close(); } } catch (IOException e) { e.printStackTrace(); } SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom()); return sslContext.getSocketFactory(); } catch (Exception e) { e.printStackTrace(); } return null; } } 和package com.example.assignment.login; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.provider.Settings; import android.widget.Toast; import androidx.annotation.Nullable; import com.example.assignment.MainActivity; import com.example.assignment.databinding.ActivityWelcomeBinding; import com.example.assignment.login.repo.LoginRequestBean; import com.tplink.apps.architecture.BaseMvvmActivity; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.security.KeyStore; import java.security.SecureRandom; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.zip.GZIPInputStream; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; public class WelcomeActivity extends BaseMvvmActivity<ActivityWelcomeBinding> { @Nullable @Override protected ActivityWelcomeBinding bindContentView(@Nullable Bundle bundle) { return ActivityWelcomeBinding.inflate(getLayoutInflater()); } @Override protected void subscribeViewModel(@Nullable Bundle bundle) { //返回登录选择界面 viewBinding.close.setOnClickListener(v -> { Intent intent = new Intent(WelcomeActivity.this, LoginChooseActivity.class); startActivity(intent); finish(); }); //TODO 账号验证逻辑 //TODO 登录 viewBinding.btnContained.setOnClickListener(v -> { String username = viewBinding.id.getText(); String password = viewBinding.pass.getText(); LoginRequestBean requestBean = new LoginRequestBean(); requestBean.setAppType("TP-Link_aria_Android"); requestBean.setAppVersion("3.8.33"); requestBean.setCloudPassword(password); // 用户输入 requestBean.setCloudUserName(username); // 用户输入 requestBean.setPlatform("Android " + Build.VERSION.RELEASE); requestBean.setRefreshTokenNeeded(false); requestBean.setTerminalMeta("1"); requestBean.setTerminalName(Build.MANUFACTURER + " " + Build.MODEL); requestBean.setTerminalUUID(Settings.Secure.getString( getContentResolver(), Settings.Secure.ANDROID_ID )); // 转换为JSON并发送(使用try-catch) try { JSONObject json = requestBean.toJson(); sendLoginRequest(json); } catch (JSONException e) { // 处理异常 e.printStackTrace(); } }); //忘记密码 viewBinding.forgot.setOnClickListener(v -> { Intent intent = new Intent(WelcomeActivity.this, ResetActivity.class); startActivity(intent); finish(); }); //无账户 跳转注册界面 viewBinding.text2.setOnClickListener(v -> { Intent intent = new Intent(WelcomeActivity.this, CreateIDActivity.class); startActivity(intent); finish(); }); } private void sendLoginRequest (JSONObject json){ new Thread(() -> { HttpURLConnection connection = null; try { // 1. 将PEM字符串转换为X509证书对象 CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate certificate = (X509Certificate) cf.generateCertificate( new ByteArrayInputStream(CLOUD_CERT.getBytes(StandardCharsets.UTF_8)) ); // 2. 创建信任库并添加证书 KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); trustStore.setCertificateEntry("tp-cloud-cert", certificate); // 3. 初始化SSL上下文 TrustManagerFactory tmf = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() ); tmf.init(trustStore); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init( null, // 无客户端证书 tmf.getTrustManagers(), new SecureRandom() ); // 1. 创建URL对象(使用完整URL) URL url = new URL("https://n-wap-beta.tplinkcloud.com/api/v2/account/captchaLogin" + "?appName=TP-Link_aria_Android" + "&appVer=3.8.33" + "&netType=wifi" + "&termID=104AF94B6BAF9F6FDC901A2DFFDAD535" + "&ospf=Android%2012" + "&brand=TPLINK" + "&locale=en_US" + "&model=Redmi%20Note%209%20Pro" + "&termName=Redmi%20Note%209%20Pro" + "&termMeta=1"); // 2. 打开HTTP连接 connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setConnectTimeout(15000); connection.setReadTimeout(15000); // 3. 设置请求头(包含所有指定头) connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); connection.setRequestProperty("Accept-Encoding", "gzip"); connection.setRequestProperty("Connection", "Keep-Alive"); connection.setRequestProperty("User-Agent", "Dalvik/2.1.0 (Linux; U; Android 12; Redmi Note 9 Pro Build/SKQ1.210908.001)"); // 4. 启用输出流并写入JSON数据 connection.setDoOutput(true); try (OutputStream os = connection.getOutputStream()) { byte[] input = json.toString().getBytes(StandardCharsets.UTF_8); os.write(input, 0, input.length); } // 5. 获取响应码 int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // 6. 处理Gzip压缩响应 InputStream is = "gzip".equalsIgnoreCase(connection.getContentEncoding()) ? new GZIPInputStream(connection.getInputStream()) : connection.getInputStream(); // 7. 读取响应内容 try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) { StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } // 8. 解析JSON响应 JSONObject jsonResponse = new JSONObject(response.toString()); handleLoginResponse(jsonResponse); } } else { runOnUiThread(() -> Toast.makeText(WelcomeActivity.this, "HTTP错误: " + responseCode, Toast.LENGTH_SHORT).show()); } } catch (Exception e) { runOnUiThread(() -> Toast.makeText(WelcomeActivity.this, "请求失败: " + e.getMessage(), Toast.LENGTH_LONG).show()); } finally { if (connection != null) connection.disconnect(); } }).start(); } // 处理登录响应 private void handleLoginResponse (JSONObject jsonResponse){ runOnUiThread(() -> { try { int errorCode = jsonResponse.optInt("error_code", -1); JSONObject result = jsonResponse.optJSONObject("result"); if (errorCode == 0 && result != null) { String token = result.optString("token", ""); if (!token.isEmpty()) { // 登录成功处理 // saveToken(token); startActivity(new Intent(this, MainActivity.class)); } else { // showError("token获取失败"); Toast.makeText(WelcomeActivity.this, "token获取失败", Toast.LENGTH_LONG).show(); } } else { String errorMsg = result != null ? result.optString("msg", "未知错误") : "响应格式错误"; // showError("登录失败: " + errorCode + " - " + errorMsg); Toast.makeText(WelcomeActivity.this, "登录失败: " + errorCode + " - " + errorMsg, Toast.LENGTH_LONG).show(); } } catch (Exception e) { // showError("响应解析异常: " + e.getMessage()); Toast.makeText(WelcomeActivity.this, "响应解析异常: " + e.getMessage(), Toast.LENGTH_LONG).show(); } }); } private static final String CLOUD_CERT = "-----BEGIN CERTIFICATE-----\n" + "MIIDBzCCAe+gAwIBAgIQT5x0ma7QnINHCQvhnmzR9zANBgkqhkiG9w0BAQsFADAV\n" + "MRMwEQYDVQQDEwp0cC1saW5rLUNBMCAXDTE4MDExOTA4Mjc1MloYDzIwNjgwMTE5\n" + "MDgzNzUyWjAVMRMwEQYDVQQDEwp0cC1saW5rLUNBMIIBIjANBgkqhkiG9w0BAQEF\n" + "AAOCAQ8AMIIBCgKCAQEAuGG8n5zEUN1j5wuvUz4pAIMurhKHbpfUUu+b2acFHKS6\n" + "iU9hNJWvDyhXcihY5Wz6aq9m4D5SZcgW3k31YoNNtrztDjdg2qw7AaX85S99/G0B\n" + "VbIXktrhs34OW19WA/haDwut3dFhLem+gCRRKUXcmuqchZc84dY7JFVfhPcJci4m\n" + "sRjLCFNO0ho9OX+MZwfO4BLaeAqKVoAor6rf4BXVtO0xjYHDKO0fb3AWLLJ4EjGe\n" + "q6YieqPiYlPFEqRm5PrvBXTm0IuQogygyVpK4LHr/K207ZLyV33DxLLbsUgSEJVn\n" + "pZUv/WUujXjlIDgxIvyZZCYiXO3dle2/MEvpmZk6JQIDAQABo1EwTzALBgNVHQ8E\n" + "BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUxu2iBRTsef5iNnsADVhM\n" + "JDQWi6kwEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQELBQADggEBAB52Majd\n" + "+wo3cb5BsTo63z2Psbbyl4ACMUaw68NxUMy61Oihx3mcLzLJqiIZcKePiHskLqLJ\n" + "F7QfT9TqjvizMjFJVgsLuVubUBXKBzqyN+3KKlQci0PO3mH+ObhyaE7BzV+qrS3P\n" + "dVTgsCWFv8DkgLTRudSWxL7VwVoedc7lRz5EroGgJ33nRGCR0ngcW919tLTARDQO\n" + "pULmzulcdWeZgG+0PLX0xjJQIjFEvbOxR1Z+gxMupBz0rWFokmWYrcga8eWiWzjQ\n" + "Ia3/ASBVJ69srV77trWlfLumkChbXk9i64NXBKnce0Jmll0Y9OC1nMPqrbQKnzcn\n" + "dSAA4fejD/qMQn0=\n" + "-----END c-----"; // UI线程执行辅助方法 // private void runOnUiThread (Runnable action){ // new Handler(Looper.getMainLooper()).post(action); // } } 这两段代码怎么融合一下
09-06
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值